Publish

Animated story

Free

Show why a plan changed, one step at a time. A story plays timed edits and captions on a roadmap: move an activity, let its dependencies follow, then give the reader time to see the result. Readers can stop the story and try the plan themselves.

Watch a launch change across three views

The Board, Timeline and Flow below show one plan. First, Marketing takes over Launch page. Next, that activity stops waiting for Build and waits for Wireframes instead. Compacting the plan removes the gap, so the launch page can start earlier. Finally, Campaign waits for Build, and the views show the new schedule.

Watch the cards, bars and arrows change together. Touch a frame, scroll inside it or use its keyboard controls to stop playback and explore. Use the replay button in the first frame to return to the opening plan and play again. The code below the frames is the story they play; replace its shortened example URLs with your own complete embed URLs before using it.

<iframe id="hero-board" src="https://embed.tidigar.com/#s=1.…" name="tidigar-theme-dark" title="Board" width="100%" height="210" style="border:0"></iframe>
<iframe id="hero-plan" src="https://embed.tidigar.com/#s=1.…" name="tidigar-theme-dark" title="Timeline" width="100%" height="390" style="border:0"></iframe>
<iframe id="hero-flow" src="https://embed.tidigar.com/#s=1.…" name="tidigar-theme-dark" title="Flow" width="100%" height="150" style="border:0"></iframe>
<script type="text/tidigar-story" data-for="hero-board hero-plan hero-flow">
  0:00   shiftToToday("Wireframes", 2)
  0:00.7 update("Launch page", {"Team": "Marketing"})
  0:03.2 removeDependency("Launch page", "Build")
         connectActivities("Launch page", "Wireframes")
         compactRoadmap()
  0:06.4 connectActivities("Campaign", "Build")
         compactRoadmap()
  0:10.2 restore()
  0:12   loop()
</script>
<script async src="https://embed.tidigar.com/assets/publisher.js?v=4779b404bdc0"></script>

Add a story to your page

  1. Prepare the starting plan, dependencies, work calendar and saved views in Tidigar. Follow Embed a roadmap to copy its embed code to a page that accepts HTML and scripts.
  2. Give the iframe a unique id, such as launch-plan. Add a <script type="text/tidigar-story" data-for="launch-plan"> block beside it. Keep the embed.js script from the copied code.
  3. Write a few timed calls inside the story block. Use the exact record titles from your plan, double quotes for text and JSON for fields. Start with one visible change and a caption that explains its consequence.
  4. Leave a few seconds between changes. Use restore() before loop() when a demonstration should return to its opening state on every cycle. Omit loop() to leave the final result on screen.
  5. Reload the page and watch a full cycle. Stop it, edit an activity and replay it. Check the frames on a phone and with reduced motion enabled before publishing.

For a plan containing Build prototype, this small story moves the activity three days later and explains what to watch. Put it beside a frame whose id is launch-plan:

<script type="text/tidigar-story" data-for="launch-plan">
  0:01 caption("Watch the prototype and the activities waiting for it")
  0:04 changeDates("Build prototype", {"start": "+3d", "end": "+3d"})
       caption("The prototype moves later; work that waits for it follows")
  0:09 restore()
       caption()
  0:12 loop()
</script>

A time such as 0:04 is four seconds from the start. A line without a time uses the preceding line's time; those calls are drawn together. Timecodes must move forwards or stay equal. Dates can be explicit, such as "2026-07-12"; relative dates such as "+3d" refer to that activity's current dates. See the story specification for all calls, fields and limits.

Explain several views with one story

Embed the same plan in each desired view and give every frame its own id. List those ids, separated by spaces, in one story's data-for. The first frame plays the timed calls and shows captions; the others follow its plan changes and selected activity while keeping their own views. Put the frame you want readers to follow first in that list.

Use focus("Build prototype") to select an activity across the views and highlight its dependency chain. Use focus() to clear the selection. applyView("Timeline by team") switches only the playing frame to that saved view. Start with the same project in every frame: listing ids does not turn different plans into one.

Replay a plan's status meetings

Keep the latest plan as the one people work in, and use a story to show how it got there. A plan's history shows an assistant turning status slides into one plan with a story. Give each meeting a moment with its changes, a caption and today("2026-03-02") to place the date line on that meeting's date.

Calls at 0:00 that change the plan set up its opening state without animation. Hide records that arrived later with hide("Pilot"), then bring them back with show("Pilot") at the right meeting. End with the current plan. Every named frame runs the opening setup, including shiftToToday when used to move the whole example relative to today's date.

A screen link can carry a story written by the plan's editors. It plays in a full window or an embedded frame. A story block on the page takes precedence over that screen's own story. If the shared plan changes during playback, the screen takes the new version when the story starts again.

How stories work in detail

Edits follow the plan's scheduling rules

A story changes records, rather than clicking menus. Moving an activity carries dependent work; vacation changes use the plan's work calendar. A dependency can retain an intentional gap until compactRoadmap() removes it. Filters can hide work that still changes, so choose views that reveal the consequence you are explaining. See dependency scheduling and vacation and working days for those rules.

Titles must identify one record exactly. After renaming a record, later calls use its new title. A hidden record is temporarily absent: nothing waits for it and calls naming it are skipped. Showing it again restores its relationships wherever both records are shown. Use a caption to explain these changes so readers can follow them without reading the code.

A loop repeats calls; replay restores the opening

restore() returns the plan, view, hidden records and today line to the opening state after setup, and clears the selection. Clear a caption separately with caption(). loop() restarts the timed sequence; it does not itself undo edits. Without a restore or explicit opening-state edits, relative moves can accumulate and repeated additions can fail on later cycles. Test more than the first pass.

The reader's replay button restores the opening state before playing again, discarding their exploratory edits in the frame. Setup calls at 0:00 run before playback and define that opening; a loop does not run those setup calls again. Use restore() before looping a history story too. Returning to that opening means returning to the first meeting, which may differ from the latest plan stored in Tidigar.

Readers can stop, pause and start again

The first touch, key or wheel inside a frame stops the page's stories and clears the playing caption. Playback stays stopped until the reader chooses replay. With reduced motion enabled, the story waits for the play button; changes appear without motion.

Switching away from the page pauses playback. In browsers with visibility observation, scrolling all the story's named frames out of view also pauses it. Any named frame still visible keeps the whole group playing, even if the first frame is offscreen. Returning resumes from the paused time, without restarting or racing through missed steps. While playing, a frame can grow for its content but does not shrink with every step.

The frame holds the result in memory

Story edits and readers' experiments stay in the frame. They do not save to the original plan. Open in Tidigar opens a copy as it currently appears, including story changes. Reloading an ordinary embed loads its published starting plan again. Follow Sharing a plan for copy contents and limits; use a screen link when the published plan should follow later shared changes.

Check missing steps before publishing

If your site strips scripts, an ordinary embed shows its plan without the page's story. Check that the iframe ids match data-for, the full embed URLs load and embed.js is present. A loaded frame alone does not prove the story is running.

A malformed line, missing or ambiguous title, unknown field or forbidden change is skipped with a line-number warning in the browser console. The story continues, so inspect those warnings even when later captions appear. Correct the record names, field values or dependency direction and reload the page. Story text accepts only the documented calls and JSON arguments; it cannot run JavaScript, fetch resources or insert HTML.

Browse publishing options or all guides.