HTML exports come with two important files – Player.js and Driver.js.
The Driver is a class that registers with the UI on the main index page, allowing a user to play / pause and drag a slider to drive the animation.
The Driver is a simple extension of Player.js, the main class that actually handles the playback control and setup of your animations.
The Player class is responsible for setting up animations, and has all the playback functionality you’ll need to work with your animations.
You can find the file in the js
folder of any HTML export.
Have a look at the code for Player.js
The interface for the player is pretty straightforward – it has the same functions as the driver class.
This is the constructor for creating a player:
You need to pass:
Timeline
class (e.g. SquareTimeline
)timerID
associated with the animation you’re creating the player forbool
whether to loop the animationdelay
time (in milliseconds) at the END of an animationAn example of creating a non-looping animation that starts right away is:
You can set and get the current time of a player:
Players track time in milliseconds
To start an animation from it’s current time:
You can check if a player is currently playing:
You can pause a player:
Pausing simply stops all animations at the current time.
You can stop a player:
Stopping will also set the player’s
currentTime
to0
The driver is responsible for interfacing with UI elements on an html page. It is an extension of a player and therefore shares the same playback functionality as you saw above.
play/pause
buttonloop
buttonslider
time
labelYou can find the file in the js
folder of any HTML export.
Have a look at the code for Driver.js
The driver has all the same playback commands as the player.
The major difference between the driver and player is the constructor, where the driver requires you pass it the ids for the interface elements associated with it.
Driver(timeline, loopButtonID, playButtonID, sliderID, timeLabelID, timerID)
You need to pass:
Timeline
class (e.g. SquareTimeline
)id
for the loopButton
tagid
for the playButton
tagid
for the slider
tagid
for the timeLabel
tagid
for the timer
tagYou should pass unique ids to the for interface elements to the driver.
Here’s an example from the move
timeline in the intro.flow
file:
new Driver(Move, 'loopButton-move', 'playPauseButton-move', 'slider-move', 'timeLabel-move', 'timer-move')
The driver requires a DOM in order to be initialized. As you may have guessed from the constructor, there are 5
main elements that the standard driver requires during initialization.
Here’s what the driver looks like:
<div class="playback">
<div class="slider">
<input type="range" min="0" max="1" step="0.001" value="0.0" id="slider-wordmark" />
</div>
<div class="controls">
<div class="playPauseLoop">
<div class="playPauseContainer loop">
<input type='checkbox' id="loopButton-wordmark">
<label for="loopButton-wordmark" class="loopLabel" id="loopLabel" />
</div>
<div class="playPauseContainer">
<input type='checkbox' id="playPauseButton-wordmark">
<label for="playPauseButton-wordmark" class="playPauseLabel" id="playPauseLabel" />
</div>
<div class="playPauseContainer">
<div class="time" id="timeLabel-wordmark">0 s</div>
</div>
</div>
</div>
</div>
During the initialization of a driver, the following function gets called:
createControlFunctions() { ... }
This function is reponsible for linking the driver directly to the UI in your dom.
The driver also requires its own CSS. The standard export looks like this:
Have a look at the code for Driver.css
You can trigger events to occur when animations finish by overriding or re-writing the createOnFinishCallback()
function. This works for both the driver and player classes.
This method currently looks like the following:
createOnFinishCallback() {
if (this.timingAnimation == null) {
return
}
this.timingAnimation.onfinish = () => {
if (this.loop == true) {
this.currentTime = 0
} else {
this.stop()
}
}
}
To add your own function call to be triggered when an animation ends.
This callback creation function gets executed at the end of the player’s constructor.
The callback actually tracks the animation attached to the timer because its duration represents the entire duration of the set of animantions laced throughout svgs and other elements in your timeline
By default, the page you export from Flow uses a driver. Here are a few simple steps to remove and replace it with a player.
This is the code for the Move
timeline:
Replace the above with…
Remove the driver UI by deleting the playback
div:
You can also delete:
js > driver.js
css > driver.css
To hook up your animations to user input, sliders, or events, simply bind whatever it is you’re tracking to the currentTime
of the animation.
For example, the standard driver binds the animation to the slider like so:
this.slider.oninput = () => {
this.pause()
var newTime = this.slider.value * this.duration
this.setAnimationTimeLabels(newTime)
var newTime = Math.min(newTime, this.duration - 1)
this.currentTime = newTime
}
Wham!
To have multiple animations on a page requires every player – or driver – to have a unique timer.
The current HTML template exports each timer with its own unique id, which is defined by the name of the timeline you’re exporting.
For example, in the Move
timeline from the intro.flow
file, the timer id looks like this:
<div id="timer-move"></div>
…you want multiple animations all driven by the same timer, or driver UI.
Here is an example that we cooked up for you.
The following download contains a Sketch and a Flow file as well as a modified export from Flow, which has 4 animations running independently using players instead of drivers.
Remember to hit up our Slack Channel if you have any questions.
result(s) found for “”.