Wee JavaScript program for running animated SVG Keyshape diagrams with step/run/stop buttons and HTML captions.
ksd.js
If you have…
…then this wee bit of JavaScript (KeyshapeDiagram) will add buttons so you can step/run/reset it, whilst displaying the corresponding captions.
Great for diagrams that let people figure out what’s going on in their own time!
See an example
Code: see the HTML below (or look at the source in these examples).
Process:
<svg>
or <object>
element with class="ksd"
<div>
or <ol>
) whose children
are captions, one per timeline markerksd.js
or its contents)ksd.css
or its contents)When you’ve exported the SVG, embed it with an <object>
tag with class ksd
.
Add (optional) captions under the same parent. Captions must be in a single
container (any tag name) with class ksd-captions
. They’ll be matched against
the timeline markers in the order they appear, unless you explicitly add the
name of the marker it applies to with data-ksd-id
(or id
… but be careful
because that might not be unique in the DOM you’re inserting it into).
The KeyshapeDiagram code automatically triggers a call to
window.KsDiagram.init()
when it loads: this detects and initialises any
suitable diagrams it finds in the DOM. If you add more diagrams after this
has happened, you can initialise them by calling window.KsDiagram.init()
again. You can pass a scope (e.g., a fragment of the DOM) in as an argument to
init()
— by default, it is the whole document
.
For example, with a Keyshape animation in my-diagram.svg
whose primary
timeline has markers you’ve called start
, middle
, and end
, you can
embed it like this (by hauling in the .svg
, .js
, and .css
files):
<link href="ksd.css" rel="stylesheet" type="text/css" />
<div>
<object class="ksd" data="my-diagram.svg" type="image/svg+xml"></object>
<ol class="ksd-captions">
<li>
This is caption shown before you press
<em>step</em> or <em>run</em>.
</li>
<li>
This is displayed while the animation runs,
starting from the first timeline marker to
the next one (say, "middle").
</li>
<li>
This caption is shown as the animation
runs from "middle" to "end".
</li>
</ol>
<div class="ksd-no-js">
This content is displayed if JavaScript (and hence
animation) is not supported on this page load.
</div>
</div>
<script src="ksd.js"></script>
If the final (terminating) timeline marker is not called end
, you must
explicitly tell KeyshapeDiagram what it is: put a data-ksd-end-marker
attribute on the <object>
.
If you don’t want to use external files, you can do the same thing but have
everything in-line. In some cases this might be more convenient — for example,
embedding a diagram into a single page without worrying about any other setup.
This means your SVG really is just an <svg>
tag (not an <object>
), and
the external JavaScript can be the <script>
tag’s inline contents, instead
of loaded externally by src
.
You can see some examples of this in these examples.
This was intended for use on the Moodle… but it’s turning out to be, uh, problematic.
Keyshape is a neat little app for making SVG animations on the Mac. A key capability that this KeyshapeDiagram code is exploiting is that it lets you name the markers on the timeline: those are used as the breakpoints in the animation.
end
you must tell KeyshapeDiagram what it is called with data-ksd-end-marker
.Things work fine if you export from Keyshape with JavaScript animation embedded. However, if you’re fully in control of the environment you’re deploying to, it’s probably more efficient to handle the Keyshape animation library separately. Your call.
CSS animations should work the same, provided they still respond to Keyshape’s named-markers API.
If the target browser does not support SVG — frankly very rare, these days —
you can put a fall-back <img>
in there.
If JavaScript isn’t enabled, the captions will be displayed in full. This is probably what you want, but if it isn’t, you can style them with regular CSS (including, if required, hiding them).
Any elements with the class ksd-no-js
are hidden if JavaScript is enabled.
Use these for fall-back content.
Currently the SVG diagram is displayed if JavaScript is not available; maybe
that will change (depending on more data-ksd-
settings?): that’s for
future development.
Add data-
attributes to the <object>
element for more control:
attribute | purpose |
---|---|
data-ksd-button-labels |
Customising the labels displayed on the buttons |
data-ksd-layout |
Controlling the order of layout (buttons, diagram, captions) |
data-ksd-end-marker |
Nominating the end-of-animation marker name (if it isn’t end ) |
See below for details for each of these settings.
Because you’re putting them on the <object>
element containing one diagram
within it, so can be different for other diagrams on the same page.
The default labels on the buttons are step, run and stop (and reset and stopping). You can override any of these with:
data-ksd-button-labels="stop:halt, stopping: halting"
If you are generating these programmatically (e.g., an i18n build process) a JSON object in there also works, so this is equivalent:
data-ksd-button-labels='{"stop":"halt", "stopping":"halting"}'
Any labels you don’t specify remain the (English) defaults.
The KeyshapeDiagram code assumes the end-of-animation marker is called end
.
If it isn’t, add it explicitly:
data-ksd-end-marker="finished"
The default layout is b-d-c
:
b
buttons above…d
diagram above…c
captions…but you can change it by setting the layout with any order:
data-ksd-layout="d-b-c"
The hyphens are optional (characters other than b
, c
, and d
are ignored).
You can change the layout further with CSS.
The components have extra classes to allow you to select them for further styling (the layout control only affects their relative order in the DOM). They also have IDs so you can manipulate them further if you want to.
Item | class | id |
---|---|---|
<div> containing buttons |
ksd-btn-block |
ksd-btn-block-$$$ |
step <button> |
ksd-step |
ksd-step-$$$ |
run <button> |
ksd-run |
ksd-run-$$$ |
stop/reset <button> |
ksd-stop |
ksd-stop-$$$ |
element containing captions | ksd-captions |
ksd-captions-$$$ |
caption | ksd-caption |
ksd-caption-$$$-@@@ |
$$$
is the ID of the diagram. This will be whatever id
you gave the
<object>
tag, or an ID allocated by KeyshapeDiagram if you didn’t.
(Furthermore if you did allocate one but it was the same as another
diagram’s, KeyshapeDiagram will have amended it). The ID allocated is
returned by the KsDiagram.add_diagram(container)
function, but if you
didn’t call that yourself you can find all the diagram id
s in the
window.KsDiagram.diagram_ids
array (or inspect the data-ksd-id
attribute that has magically appeared on the <object>
).@@@
is the ID of the corresponding timeline marker.Everything KeyshapeDiagram adds to the DOM is prefixed with ksd-
to avoid
namespace clashes (e.g., CSS and DOM IDs). So avoid using those unless you
deliberately mean to override stuff.
If you use in-line SVGs (not <object>
), be careful about duplicate KeyshapeJS code: ideally, don’t embed it in your exported SVG and load it
as a separate library instead. This helper script isn’t helping much with
that yet and is currently aggressively removing diagrams from the DOM if it
thinks they might be bad — this is probably wrong: TODO.
Should be fine with multiple diagrams on the same page.
Should be resilient to the ksd JS being loaded more than once (occupational hazard for material being embedded in things like Moodle).
Maintaining aspect ratio of animations is still not straightforward in CSS
but that’s not quite the remit of this project. However, full-page examples
like this example seem to be pretty
well-behaved with CSS like, e.g., object.ksd{max-height:60vmin;}