Repository navigation
Variables and conditions, multiple-answer and timed questions, cues and player plugins, jumping to any scene, and recovery from videos that fail. Both packages are now licensed under Apache 2.0.
Added
@ivkit/core:answerRange(question, offered), the fewest and most options an answer takes. The engine,validateStoryand the player now share it.@ivkit/core:StoryEngine.goTo(sceneId, time?), which enters any scene from any state, dismissing the question on screen, and plays it fromtime, asking its questions from there on. It works beforestart(), e.g. to resume a saved story. Thesceneevent now carries thattime, andMediaControllerstarts the video there.@ivkit/core:StoryEngine.seek(time), which resumes the current scene fromtimelike aseekin the story.@ivkit/core:StoryEngine.destroy(), which cancels a question's timeout and removes every listener, andpauseTimeout()andresumeTimeout(), which stop and go on with a question's countdown.@ivkit/player:goTo(sceneId, time?)on<ivkit-player>, which jumps to a scene and plays it. Use it to branch on a score, resume where the viewer left off or build chapter menus.@ivkit/core: anerrorevent onMediaControllerwhen a scene's video can't be loaded or played, andretry(), which loads it again from where it failed. A failed preload is no longer stuck: it's loaded again when its scene comes.@ivkit/player: an error screen with anerrorslot, aniv-errorevent andretry(), so a missing or unplayable video no longer leaves the player frozen without notice.@ivkit/player: removing the player from the page pauses a question's timeout until it's back, and keeps a scene that finishes loading meanwhile from playing. Setting another story destroys the previous engine.@ivkit/core:pauseon hotspots, which pauses the video when the hotspot appears until it's activated. The engine emits a newpauseevent, andMediaControllerpauses on the hotspot's first frame and resumes when it's activated without agoto.@ivkit/core: variables and conditions in the story format.Story.varsdeclares variables,setchanges them on choices, hotspots and scenes,branchespick a scene by condition before falling back togotoornext, andifoffers a choice or shows a hotspot only while it holds.validateStoryreports undeclared variables with the newmissing_variablecode.@ivkit/core:StoryEngine.vars,StoryEngine.setVar()and avarsevent. Theinteractionevent now includes theoptionsoffered, andanswerandhotspotinclude the scene they branch to asgoto.@ivkit/player: questions show only the options whoseifholds, andiv-interaction,iv-answerandiv-hotspotcarry the same new fields as the engine's events.@ivkit/core:correcton choices, reported in theanswerevent to score quizzes.@ivkit/core:seekon choices and hotspots, which resumes the current scene from another second when they don't branch, asking the questions from there on again.MediaControllernow seeks onresumewhen itstimeisn't the current one.@ivkit/player:hrefon hotspots, which openshttp:andhttps:links in a new tab when activated.@ivkit/core: multiple-answer questions.multiple: truetakes several options, bounded byminandmax, and applies each one'sset. Questions also takegoto,branchesandseek, which decide formultiplequestions and act as a fallback for single ones.StoryEngine.answer()takes a list of ids, and theanswerevent addschoicesandcorrect, true when exactly the options markedcorrectwere picked.@ivkit/player:multiplequestions show toggle options and a Confirm button, exposed as::part(submit).@ivkit/core:timeoutanddefaulton questions. When nobody answers in time, the engine emits a newtimeoutevent and answers withdefault, or else lets the question'sbranches,gotoandseekdecide.@ivkit/player: a countdown bar for questions withtimeout, exposed as::part(timer), and aniv-timeoutevent. The player now ignores events from an engine it has replaced.@ivkit/core:cueevents in the story format, which mark a span of a scene for plugins and apps, picked bykind. The engine emits a newcuesevent with the active ones and exposes them asStoryEngine.activeCues.@ivkit/core:dataon the story, scenes, events and options, free-form JSON that IVKit carries but never reads.validateStorychecks that it's a JSON object.@ivkit/core:validateStory(story, { cues })runs a plugin's checks on cues of its kind, reporting with the newinvalid_cuecode.@ivkit/player: plugins throughplayer.use(plugin). A plugin runs for each story with the engine, the media controller, its own layer over the video and anon()that unsubscribes by itself, and may return a cleanup. The player also dispatchesiv-cues.@ivkit/core: atimeevent onMediaController, with each playback time it reports to the engine.<ivkit-player>now moves animated hotspots on it instead of keeping its own frame callbacks.
Changed
- The license is now the Apache License 2.0 instead of MIT, for both packages.
- Size budgets: the standalone player now stays under 9.5 KiB gzip (was 8 KiB), and all of
@ivkit/coreunder 6 KiB (was 4 KiB), to fit variables, conditions, multiple-answer questions and timeouts. @ivkit/player: its CSS is now minified at build time, which takes about 500 B off the standalone player.@ivkit/core:MediaControlleremitsblockedonly when the autoplay policy rejectsplay()(aNotAllowedError). Aplay()interrupted by a pause or a new source no longer shows the player's Play button over a scene that's playing.@ivkit/core:MediaController.play()does nothing while the next scene loads, so the previous scene can't play, heard but hidden, behind it.@ivkit/player: settingstoryto one whosestartisn't a scene throws without resetting the player, instead of leaving it half reset.@ivkit/core: a listener that moves the story, withgoTo(),start()orseek(), wins over what the engine was doing. Before, agoTo()from ananswer,hotspotortimeoutlistener was overridden by the answer's own branch or followed by a staleresume.@ivkit/core: a listener that throws no longer stops the other listeners or leaves the engine halfway through a transition. Its error is still reported.@ivkit/player: a plugin that throws, when it runs or cleans up, no longer stops the player or the plugins after it.@ivkit/player:restart(), and so the Replay button, sets the variables back to their initial values. Before, a replay kept the previous run's scores and counters.@ivkit/player: hotspots that stay on screen keep their buttons when others appear or go, so keyboard focus,renderHotspotchanges and animations aren't lost.renderHotspotruns once per hotspot while it stays on screen.
npm: npm install @ivkit/player@0.2.0 or @ivkit/core@0.2.0