Overview
Kinetic (@wildflowerjs/kinetic) turns a WildflowerJS page into a video or interactive, previewed and checked in the browser, and a video rendered to MP4 there too.
Every value on the page is a function of time, so a scene has no timeline to register. The same scenes can also run in interactive mode, as a lesson on the page that plays one step at a time and waits for the viewer.
Why Kinetic
Kinetic turns a web page into a video or interactive. The page is plain HTML and JavaScript in your own repository, it runs on your own site, and the browser renders it.
The video is a page you can ship
The same scenes play as an MP4 and as a page in your site or app.
Lessons the viewer drives
In interactive mode the viewer steps through the scenes with your buttons and sliders, and the same file still renders as a video (Interactive mode).
Your real data, in every frame
A scene reads a query, a CSV file or a transcript, and frame 0 waits for it (Readiness). The batch script renders one video per row of a file.
Code you own
A composition is a file you can read, diff and keep in version control, written by hand or with any assistant that reads the llms.txt. The package is MIT, with no account and no install.
The frame you check is the frame you render
check() compares frames seeked in two orders before you render, and the development build names any line that would make them differ (Reliability).
A finished look
Motion blur, eases and springs, speed ramps, mattes, blend modes, grain, bloom and a grade. Most After Effects tools have a counterpart (Coming from After Effects).
An MP4 from the browser, with sound
The preview bar's Render button writes the file in Chrome, with no render server. It draws the page with HTML-in-Canvas, Chrome's way of drawing HTML into a canvas, on by default from Chrome 157 (earlier versions need a setting, in render()). HyperFrames' command line renders it too, with parallel workers.
The model
A video is a series of captured frames of the page, 30 a second by default.
You write what the page looks like at second t, and the renderer sets the time to t = 0, 1/30, 2/30 and so on, capturing the page each time.
The page loads three scripts (the framework, Kinetic and its own) and marks the composition's root with data-composition-id, data-start, data-duration, data-width and data-height (and data-fps, 30 by default); each clip inside it has its own data-start and data-duration.
A scene is a WildflowerJS component whose values are functions of time, so rows come from a data-list, shared values from a store, and remote data from a query.
Lists and static pools draw hundreds of rows a frame, and a three.js scene through Trillium is drawn once per seek.
Kinetic runs on every tier. A tier is one of the framework's builds, from the smallest (nano) to the fullest (full, which adds queries); Loading it lists the tier each feature needs, and the script tags.
The smallest page
Two files in one folder. index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script defer src="https://cdn.jsdelivr.net/npm/wildflowerjs@^1.5.5/dist/wildflower.lite.dev.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/@wildflowerjs/kinetic@0.1/dist/kinetic.wf.js" data-preview></script>
<script defer src="scenes.js"></script>
<style>
[data-composition-id] { position: relative; overflow: hidden; background: #efe8db; font-family: sans-serif; }
[data-composition-id]:not([data-kinetic-ready]) { visibility: hidden; }
</style>
</head>
<body>
<div data-composition-id="hello" data-start="0" data-duration="4" data-width="1280" data-height="720" data-fps="30">
<div data-component="title" data-start="0" data-duration="4" style="position: absolute; inset: 0; padding: 64px">
<h1 data-bind-style="heading" style="margin: 0; font-size: 120px">Hello</h1>
<p data-bind="line" style="font-size: 36px"></p>
</div>
</div>
</body>
</html>
And scenes.js:
const { scene, typewriter } = wildflower.kinetic;
scene('title', {
keyframes: {
heading: {
opacity: { at: [0, 0.5], to: [0, 1] },
translateY: { at: [0, 0.8], to: [40, 0], ease: 'spring' },
},
},
computed: {
line() { return typewriter(this.local - 0.6, 'A page that is also a video.', 20); },
},
});
Open index.html in Chrome: data-preview adds the bar that plays, checks and renders it.
As one file, put the scene code in <script type="module"> at the end of the body instead, since a plain inline script runs before the deferred ones.
First video builds a full piece step by step.
In interactive mode there is no renderer, and the page's own buttons and sliders drive the clock (Interactive mode).
Pick a track
With an AI assistant
You start from a brief, Claude Code writes the page from it, and you review, check and render what it wrote. A Claude Code skill gives the assistant the same rules the guides teach.
First video
You build a title card from a blank page, with letters that rise one by one, then preview, check and render it to an MP4 in the browser. It assumes no video experience.
Motion
Comps, layers and keyframes from motion design map onto elements of a page. The guide covers keyframe tracks, easing, springs, clips and timing, staggers, holds and ramps, and the camera.
Data
You draw a chart from a query, set captions from a transcript, pulse an element on the beat, and render one page as many videos from its variables.
One page, many videos
One page renders once for each row of a JSON or CSV file, with the row's values as the composition's variables, through the batch script.
Also
- The reference lists every function, option and default, starting from Loading it.
- The patterns have worked code for pieces that combine several features, grouped by subject.
- The playground runs Kinetic code in the browser.
- The demos include a title, a sales chart, captions on a beat, a showreel, and two lessons.
- The error codes page lists the KN codes, each with a sentence saying what to change.