Options

direction

The direction property defines whether an animation should be played forwards, backwards or in alternate cycles.

direction: normal (default)
new Scene({
"[data-direction='normal'] .rect": i => ({
"transform": {
scale: [0, 1],
},
"border-width": [`${30 + i * 5}px`, "0px"],
options: {
duration: 1,
delay: i * 0.1,
}
}),
}, {
easing: "ease-in-out",
selector: true,
direction: "normal",
iterationCount: 2,
}).play();
direction: reverse
new Scene({
"[data-direction='reverse'] .rect": i => ({
"transform": {
scale: [0, 1],
},
"border-width": [`${30 + i * 5}px`, "0px"],
options: {
duration: 1,
delay: i * 0.1,
}
}),
}, {
easing: "ease-in-out",
selector: true,
direction: "reverse",
iterationCount: 2,
}).play();
direction: alternate
new Scene({
"[data-direction='alternate'] .rect": i => ({
"transform": {
scale: [0, 1],
},
"border-width": [`${30 + i * 5}px`, "0px"],
options: {
duration: 1,
delay: i * 0.1,
}
}),
}, {
easing: "ease-in-out",
selector: true,
direction: "alternate",
iterationCount: 2,
}).play();
direction: alternate-reverse
new Scene({
"[data-direction='alternate-reverse'] .rect": i => ({
"transform": {
scale: [0, 1],
},
"border-width": [`${30 + i * 5}px`, "0px"],
options: {
duration: 1,
delay: i * 0.1,
}
}),
}, {
easing: "ease-in-out",
selector: true,
direction: "alternate-reverse",
iterationCount: 2,
}).play();

delay

The delay property specifies a delay for the start of an animation.

new Scene({
"[data-delay] .circle1": {
0: {
transform: "translate(-50%, -50%) scale(0)",
"border-width": "100px",
},
1: {
transform: "scale(1)",
"border-width": "0px",
},
},
"[data-delay] .circle2": {
0: {
transform: "translate(-50%, -50%) scale(0)",
"border-width": "100px",
},
1: {
transform: "scale(1)",
"border-width": "0px",
},
options: {
delay: 0.5,
}
},
}, {
iterationCount: "infinite",
selector: true,
}).play();

iterationCount

The iterationCount property specifies the number of times an animation should be played.

iterationCount: 1 (default)
new Scene({
"[data-iterationcount='1'] .circle": i => ({
0: {
transform: "translate(-50%, -50%) scale(0)",
"border-width": "100px",
opacity: 1,
},
1: {
transform: "scale(1)",
"border-width": "0px",
opacity: 0.3,
},
options: {
delay: i * 0.3,
}
}),
}, {
selector: true,
iterationCount: 1,
}).play();
iterationCount: 2
new Scene({
"[data-iterationcount='2'] .circle": i => ({
0: {
transform: "translate(-50%, -50%) scale(0)",
"border-width": "100px",
opacity: 1,
},
1: {
transform: "scale(1)",
"border-width": "0px",
opacity: 0.3,
},
options: {
delay: i * 0.3,
}
}),
}, {
selector: true,
iterationCount: 2,
}).play();
iterationCount: infinite
new Scene({
"[data-iterationcount='infinite'] .circle": i => ({
0: {
transform: "translate(-50%, -50%) scale(0)",
"border-width": "100px",
opacity: 1,
},
1: {
transform: "scale(1)",
"border-width": "0px",
opacity: 0.3,
},
options: {
delay: i * 0.3,
}
}),
}, {
selector: true,
iterationCount: "infinite",
}).play();

fillMode

The fillMode property specifies a style for the element when the animation is not playing (before it starts, after it ends, or both).

fillMode: forwards (default)
new Scene({
"[data-fillmode='forwards'] .pie, [data-fillmode='forwards'] .half.left .semicircle": {
transform: {
rotate: ["0deg", "180deg"],
}
},
"[data-fillmode='forwards'] .half.right .semicircle": {
transform: {
rotate: ["0deg", "-180deg"],
}
}
}, {
delay: 0.5,
duration: 1,
easing: "ease-in-out",
selector: true,
fillMode: "forwards",
}).play();
fillMode: backwards
new Scene({
"[data-fillmode='backwards'] .pie, [data-fillmode='backwards'] .half.left .semicircle": {
transform: {
rotate: ["0deg", "180deg"],
}
},
"[data-fillmode='backwards'] .half.right .semicircle": {
transform: {
rotate: ["0deg", "-180deg"],
}
}
}, {
delay: 0.5,
duration: 1,
easing: "ease-in-out",
selector: true,
fillMode: "backwards",
}).play();
fillMode: both
new Scene({
"[data-fillmode='both'] .pie, [data-fillmode='both'] .half.left .semicircle": {
transform: {
rotate: ["0deg", "180deg"],
}
},
"[data-fillmode='both'] .half.right .semicircle": {
transform: {
rotate: ["0deg", "-180deg"],
}
}
}, {
delay: 0.5,
duration: 1,
easing: "ease-in-out",
selector: true,
fillMode: "both",
}).play();

easing

The easing(timing-function) specifies the speed curve of an animation.

easing: linear (default)
new Scene({
"[data-easing='linear'] .rect": i => ({
"transform": {
scale: [0, 1],
},
"border-width": [`${30 + i * 5}px`, "0px"],
"options": {
duration: 1,
delay: i * 0.1,
}
}),
}, {
easing: "linear",
selector: true,
}).play();
easing: ease
new Scene({
"[data-easing='ease'] .rect": i => ({
"transform": {
scale: [0, 1],
},
"border-width": [`${30 + i * 5}px`, "0px"],
"options": {
duration: 1,
delay: i * 0.1,
}
}),
}, {
easing: "ease",
selector: true,
}).play();
easing: ease-in
new Scene({
"[data-easing='ease-in'] .rect": i => ({
"transform": {
scale: [0, 1],
},
"border-width": [`${30 + i * 5}px`, "0px"],
"options": {
duration: 1,
delay: i * 0.1,
}
}),
}, {
easing: "ease-in",
selector: true,
}).play();
easing: ease-out
new Scene({
"[data-easing='ease-out'] .rect": i => ({
"transform": {
scale: [0, 1],
},
"border-width": [`${30 + i * 5}px`, "0px"],
"options": {
duration: 1,
delay: i * 0.1,
}
}),
}, {
easing: "ease-out",
selector: true,
}).play();
easing: ease-in-out
new Scene({
"[data-easing='ease-in-out'] .rect": i => ({
"transform": {
scale: [0, 1],
},
"border-width": [`${30 + i * 5}px`, "0px"],
"options": {
duration: 1,
delay: i * 0.1,
}
}),
}, {
easing: "ease-in-out",
selector: true,
}).play();
easing: steps(6, end)
new Scene({
"[data-easing='steps(6, end)'] .rect": i => ({
"transform": {
scale: [0, 1],
},
"border-width": [`${30 + i * 5}px`, "0px"],
"options": {
duration: 1,
delay: i * 0.1,
}
}),
}, {
easing: "steps(6, end)",
selector: true,
}).play();
easing: cubic-bezier(0.74, 0, 0.42, 1.47)
new Scene({
"[data-easing='cubic-bezier(0.74, 0, 0.42, 1.47)'] .rect": i => ({
"transform": {
scale: [0, 1],
},
"border-width": [`${30 + i * 5}px`, "0px"],
"options": {
duration: 1,
delay: i * 0.1,
}
}),
}, {
easing: "cubic-bezier(0.74, 0, 0.42, 1.47)",
selector: true,
}).play();

playSpeed

The playspeed define the speed at which the play is performed.

playSpeed: 1 (default)
new Scene({
"[data-playspeed='1'] .chase .dot": {
0: {
transform: "rotate(0deg) translate(0px, -99px) scale(1)",
},
2: {
transform: "rotate(360deg) scale(0.1)",
},
},
"[data-playspeed='1'] .chase ellipse": {
0: {
"stroke-dasharray": "0 1000",
},
2: {
"stroke-dasharray": "311 1000",
},
},
}, {
selector: true,
playSpeed: 1,
easing: "ease",
}).play();
playSpeed: 2
new Scene({
"[data-playspeed='2'] .chase .dot": {
0: {
transform: "rotate(0deg) translate(0px, -99px) scale(1)",
},
2: {
transform: "rotate(360deg) scale(0.1)",
},
},
"[data-playspeed='2'] .chase ellipse": {
0: {
"stroke-dasharray": "0 1000",
},
2: {
"stroke-dasharray": "311 1000",
},
},
}, {
selector: true,
playSpeed: 2,
easing: "ease",
}).play();

Values

Number

In order to interpolate, it must be a number by default.

opacity: 0 to 1
new Scene({
"[data-number='0,1'] .square": i => ({
opacity: [0, 1],
options: {
duration: 1,
delay: (i % 7) * 0.1 + Math.floor(i / 7) * 0.2,
}
}),
}, {
selector: true,
}).play();

Unit

10px, 10%, 10em, etc. is a string that represents a number but has a unit. In this case, number and unit are divided and only numbers are interpolated.

100% to 0%
Scene.js
CSS
Animation
new Scene({
".overflow .text span": i => ({
0: {
transform: {
translateY: "100%",
}
},
1: {
transform: {
translateY: "0%",
}
},
options: {
delay: i * 0.2,
}
}),
}, {
easing: "ease-in-out",
selector: true,
}).play();

String

string indicates the first value before the time of 1, and then the second value when it is 1 because it determines that it cannot be interpolated.

Typing
new Scene.SceneItem({
attribute: {
"data-text": [
"",
"S",
"Sc",
"Sce",
"Scen",
"Scene",
"Scene.",
"Scene.j",
"Scene.js",
],
}
}, {
duration: 1,
selector: "#string .text",
}).play();

Colors

It supports color models such as hex, rgb(a), and hsl(a).

#000 to #ff5555
new Scene.SceneItem({
0: {
"background-color": "#000",
},
1: {
"background-color": "#ff5555",
},
}, {
selector: "[data-colors='#000,#ff5555'] .target",
}).play();
#000 to rgba(255, 100, 100, 1)
new Scene.SceneItem({
0: {
"background-color": "#000",
},
1: {
"background-color": "rgba(255, 100, 100, 1)",
},
}, {
selector: "[data-colors='#000,rgba(255, 100, 100, 1)'] .target",
}).play();
#000 to hsla(0, 100%, 67%, 1)
new Scene.SceneItem({
0: {
"background-color": "#000",
},
1: {
"background-color": "hsla(0, 100%, 67%, 1)",
},
}, {
selector: "[data-colors='#000,hsla(0, 100%, 67%, 1)'] .target",
}).play();

Array

Interpolates the value of the array.

[0, 0, 0] to [200, 100, 50]
0,0,0
var arrayTextElement = document.querySelector("#array .text");
new Scene.SceneItem({
0: {
arr: [0, 0, 0],
},
1: {
arr: [200, 100, 50],
},
}).on("animate", e => {
arrayTextElement.innerHTML =
e.frame.get("arr").map(num => num.toFixed(0))
}).play();

Object

Interpolates the value of the object.

transform
new Scene({
"[data-object] .circle": i => ({
0: {
transform: {
rotate: `${-90 * i}deg`,
translate: "0%, 0%",
},
},
1: {
transform: {
translate: "180%, 0%",
},
},
}),
}, {
selector: true,
iterationCount: "infinite",
easing: "ease-in-out",
}).play();

Timeline

Timeline

@scenejs/timeline is a library that represents the timeline of Scene.js. You can control time, properties, and items.

Name
+
0
1
2
3
4
.clapper
transform
translate
rotate
.clapper-container
transform
scale
.clapper .circle
transform
scale
.clapper .play
transform
translate
scale
.top .stick1
transform
rotate
.stick1 .rect
3992497
transform
scale
skew
8184303
transform
scale
skew
1979105
transform
scale
skew
6803506
transform
scale
skew
2072752
transform
scale
skew
3628653
transform
scale
skew
.stick2 .rect
858154
transform
scale
skew
2368387
transform
scale
skew
8186153
transform
scale
skew
4895680
transform
scale
skew
3791761
transform
scale
skew
5329223
transform
scale
skew
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
2 {transform: {translate: -50%,-50%, rotate: 0deg}}
2.5 {transform: {rotate: -15deg}}
3 {transform: {rotate: 0deg}}
3.5 {transform: {rotate: -10deg}}
2 {translate: -50%,-50%, rotate: 0deg}
2.5 {rotate: -15deg}
3 {rotate: 0deg}
3.5 {rotate: -10deg}
2 -50%,-50%
2 0deg
2.5 -15deg
3 0deg
3.5 -10deg
0 {transform: {scale: 0}}
1 {transform: {scale: 1}}
0 {scale: 0}
1 {scale: 1}
0 0
1 1
0.3 {transform: {scale: 0}}
1.3 {transform: {scale: 1}}
0.3 {scale: 0}
1.3 {scale: 1}
0.3 0
1.3 1
0 {transform: {translate: -50%,-50%}}
0.6 {transform: {scale: 0}}
1.6 {transform: {scale: 1}}
0 {translate: -50%,-50%}
0.6 {scale: 0}
1.6 {scale: 1}
0 -50%,-50%
0.6 0
1.6 1
2 {transform: {rotate: 0deg}}
2.5 {transform: {rotate: -20deg}}
3 {transform: {rotate: 0deg}}
3.5 {transform: {rotate: -10deg}}
2 {rotate: 0deg}
2.5 {rotate: -20deg}
3 {rotate: 0deg}
3.5 {rotate: -10deg}
2 0deg
2.5 -20deg
3 0deg
3.5 -10deg
0.6 {transform: {scale: 0, skew: 15deg}}
1.3 {transform: {scale: 1}}
0 {scale: 0, skew: 15deg}
0.6 {scale: 0, skew: 15deg}
1.3 {scale: 1}
0 0
0.6 0
1.3 1
0 15deg
0.6 15deg
0.7 {transform: {scale: 0, skew: 15deg}}
1.4 {transform: {scale: 1}}
0 {scale: 0, skew: 15deg}
0.7 {scale: 0, skew: 15deg}
1.4 {scale: 1}
0 0
0.7 0
1.4 1
0 15deg
0.7 15deg
0.8 {transform: {scale: 0, skew: 15deg}}
1.5 {transform: {scale: 1}}
0 {scale: 0, skew: 15deg}
0.8 {scale: 0, skew: 15deg}
1.5 {scale: 1}
0 0
0.8 0
1.5 1
0 15deg
0.8 15deg
0.9 {transform: {scale: 0, skew: 15deg}}
1.6 {transform: {scale: 1}}
0 {scale: 0, skew: 15deg}
0.9 {scale: 0, skew: 15deg}
1.6 {scale: 1}
0 0
0.9 0
1.6 1
0 15deg
0.9 15deg
1 {transform: {scale: 0, skew: 15deg}}
1.7 {transform: {scale: 1}}
0 {scale: 0, skew: 15deg}
1 {scale: 0, skew: 15deg}
1.7 {scale: 1}
0 0
1 0
1.7 1
0 15deg
1 15deg
1.1 {transform: {scale: 0, skew: 15deg}}
1.8 {transform: {scale: 1}}
0 {scale: 0, skew: 15deg}
1.1 {scale: 0, skew: 15deg}
1.8 {scale: 1}
0 0
1.1 0
1.8 1
0 15deg
1.1 15deg
0.8 {transform: {scale: 0, skew: -15deg}}
1.5 {transform: {scale: 1}}
0 {scale: 0, skew: -15deg}
0.8 {scale: 0, skew: -15deg}
1.5 {scale: 1}
0 0
0.8 0
1.5 1
0 -15deg
0.8 -15deg
0.9 {transform: {scale: 0, skew: -15deg}}
1.6 {transform: {scale: 1}}
0 {scale: 0, skew: -15deg}
0.9 {scale: 0, skew: -15deg}
1.6 {scale: 1}
0 0
0.9 0
1.6 1
0 -15deg
0.9 -15deg
1 {transform: {scale: 0, skew: -15deg}}
1.7 {transform: {scale: 1}}
0 {scale: 0, skew: -15deg}
1 {scale: 0, skew: -15deg}
1.7 {scale: 1}
0 0
1 0
1.7 1
0 -15deg
1 -15deg
1.1 {transform: {scale: 0, skew: -15deg}}
1.8 {transform: {scale: 1}}
0 {scale: 0, skew: -15deg}
1.1 {scale: 0, skew: -15deg}
1.8 {scale: 1}
0 0
1.1 0
1.8 1
0 -15deg
1.1 -15deg
1.2 {transform: {scale: 0, skew: -15deg}}
1.9 {transform: {scale: 1}}
0 {scale: 0, skew: -15deg}
1.2 {scale: 0, skew: -15deg}
1.9 {scale: 1}
0 0
1.2 0
1.9 1
0 -15deg
1.2 -15deg
1.3 {transform: {scale: 0, skew: -15deg}}
2 {transform: {scale: 1}}
0 {scale: 0, skew: -15deg}
1.3 {scale: 0, skew: -15deg}
2 {scale: 1}
0 0
1.3 0
2 1
0 -15deg
1.3 -15deg
var clapperScene = new Scene({
".clapper": {
2: "transform: translate(-50%, -50%) rotate(0deg)",
2.5: "transform: rotate(-15deg)",
3: "transform: rotate(0deg)",
3.5: "transform: rotate(-10deg)",
},
".clapper-container" : {
0: Scene.zoomIn({ duration: 1 }),
},
".clapper .circle": {
0.3: Scene.zoomIn({ duration: 1 }),
},
".clapper .play": {
0: "transform: translate(-50%, -50%)",
0.6: Scene.zoomIn({ duration: 1 }),
},
".top .stick1": {
2: "transform: rotate(0deg)",
2.5: "transform: rotate(-20deg)",
3: "transform: rotate(0deg)",
3.5: "transform: rotate(-10deg)",
},
".stick1 .rect": i => ({
0: "transform: scale(0) skew(15deg)",
0.7: "transform: scale(1)",
options: { delay: 0.6 + i * 0.1 },
}),
".stick2 .rect": i => ({
0: "transform: scale(0) skew(-15deg)",
0.7: "transform: scale(1)",
options: { delay: 0.8 + i * 0.1 },
}),
}, {
easing: "ease-in-out",
selector: (selector) => "[data-timeline] " + selector,
});
new Timeline(
clapperScene,
document.querySelector("#timeline .example_result"),
{ keyboard: false },
);

Keyframer

keyframer is a library that ake the CSS Keyframes the keyframes object. play CSS keyframes.

/*
<style>
@keyframes keyframer_keyframes {
7.69% {
border-width:35px;
transform: translate(-50%, -50%) scale(0);
}
84.61% {
border-width: 0px;
transform: translate(-50%, -50%) scale(1);
}
100% {
border-width: 0px;
transform: translate(-50%, -50%) scale(1);
}
}
</style>
*/
var keyframesObject = Keyframer.getKeyframes("keyframer_keyframes");

new Scene.SceneItem(keyframesObject)
.setIterationCount("infinite")
.setDuration(1)
.setSelector("[data-keyframer] .rect")
.play();

Progress

You can create a player that can tell progress from 0% to 100% over time and control the scene.

var scene = new Scene({
"[data-progress] .circle": i => ({
0: {"border-width": "150px", opacity: 1, transform: "translate(-50%, -50%) scale(0)"},
1.5: {"border-width": "0px", opacity: 0.3, transform: "scale(0.7)"},
options: {
delay: i * 0.4,
},
}),
}, {
easing: "ease-in-out",
fillMode: "forwards",
selector: true,
}).setTime(0);
var playEl = document.querySelector("[data-progress] .play");
var progressEl = document.querySelector("[data-progress] .progress");
var duration = scene.getDuration();

scene.on("play", e => {
playEl.className = "pause";
});
scene.on("paused", e => {
playEl.className = "play";
})
scene.on("animate", e => {
progressEl.value = 100 * e.time / duration;
});
playEl.addEventListener("click", e => {
scene.isPaused() ? scene.play() : scene.pause();
});
progressEl.addEventListener("input", e => {
scene.pause();
scene.setTime(progressEl.value + "%");
});

SVG Animation

Line Drawing

You can create handwriting-like effects with the css property called stroke-dasharray.

new Scene({
"[data-linedrawing] svg path": {
"0": "stroke-dasharray: 4450 4450",
"0>": "stroke-dasharray: 0 4450",
"0.3": "stroke-dasharray: 360 4450",
"1.2": "stroke-dasharray: 1450 4450",
"2": "stroke-dasharray: 2400 4450",
"2.6": "stroke-dasharray: 3000 4450",
"3.1": "stroke-dasharray: 4450 4450",
},
}, {
iterationCount: "infinite",
easing: "ease-in",
selector: true,
}).play();

Morph Shape

In path SVGElement, you can transform the shape through the attribute d.

new Scene({
"[data-morph] svg": {
transform: {
rotate: ["0deg", "180deg", "180deg", "0deg"],
},
},
"[data-morph] path": {
attribute: {
"d": [
"M 62.5 2.5 L 65 6.830127018922193 L 67.5 11.160254037844386 L 70 15.49038105676658 L 72.5 19.82050807568877 L 75 24.150635094610966 L 77.5 28.48076211353316 L 80 32.81088913245535 L 82.5 37.14101615137754 L 85 41.47114317029974 L 87.5 45.80127018922193 L 90 50.13139720814412 L 92.5 54.46152422706632 L 95 58.79165124598851 L 97.5 63.1217782649107 L 100 67.4519052838329 L 102.5 71.78203230275508 L 105 76.11215932167728 L 107.5 80.44228634059948 L 110 84.77241335952166 L 112.5 89.10254037844386 L 107.5 89.10254037844386 L 102.5 89.10254037844388 L 97.5 89.10254037844386 L 92.5 89.10254037844388 L 87.5 89.10254037844388 L 82.5 89.10254037844388 L 77.5 89.10254037844388 L 72.5 89.10254037844388 L 67.5 89.10254037844388 L 62.5 89.10254037844388 L 57.5 89.10254037844388 L 52.5 89.10254037844388 L 47.5 89.10254037844388 L 42.5 89.10254037844389 L 37.5 89.1025403784439 L 32.5 89.10254037844389 L 27.5 89.10254037844389 L 22.5 89.1025403784439 L 17.5 89.1025403784439 L 12.5 89.1025403784439 L 15 84.77241335952172 L 17.5 80.44228634059951 L 20 76.11215932167731 L 22.5 71.78203230275513 L 25 67.45190528383293 L 27.5 63.12177826491073 L 30 58.79165124598853 L 32.5 54.46152422706634 L 35 50.13139720814415 L 37.5 45.80127018922195 L 40 41.471143170299754 L 42.5 37.14101615137756 L 45 32.810889132455365 L 47.5 28.48076211353317 L 50 24.150635094610976 L 52.5 19.82050807568878 L 55 15.490381056766585 L 57.5 11.16025403784439 L 60 6.830127018922195 L 62.5 2.5 Z",
"M 62.5 2.5 L 64 7.407477288111819 L 65.5 12.314954576223638 L 67 17.22243186433546 L 68.5 22.129909152447276 L 70 27.037386440559096 L 71.5 31.944863728670917 L 73 36.85234101678274 L 74.5 41.75981830489455 L 76 46.66729559300637 L 77.5 51.57477288111819 L 81 55.32754963085076 L 84.5 59.08032638058332 L 88 62.8331031303159 L 91.5 66.58587988004847 L 95 70.33865662978103 L 98.5 74.09143337951359 L 102 77.84421012924615 L 105.5 81.59698687897873 L 109 85.3497636287113 L 112.5 89.10254037844386 L 107.5 87.94783984006462 L 102.5 86.79313930168536 L 97.5 85.63843876330611 L 92.5 84.48373822492685 L 87.5 83.3290376865476 L 82.5 82.17433714816836 L 77.5 81.0196366097891 L 72.5 79.86493607140986 L 67.5 78.71023553303061 L 62.5 77.55553499465135 L 57.5 78.71023553303061 L 52.5 79.86493607140986 L 47.5 81.01963660978912 L 42.5 82.17433714816838 L 37.5 83.32903768654762 L 32.5 84.48373822492688 L 27.5 85.63843876330614 L 22.5 86.79313930168539 L 17.5 87.94783984006465 L 12.5 89.1025403784439 L 16 85.34976362871133 L 19.5 81.59698687897875 L 22.999999999999996 77.84421012924619 L 26.499999999999996 74.09143337951363 L 29.999999999999996 70.33865662978106 L 33.49999999999999 66.5858798800485 L 36.99999999999999 62.83310313031592 L 40.49999999999999 59.080326380583344 L 43.99999999999999 55.327549630850775 L 47.49999999999999 51.5747728811182 L 48.99999999999999 46.667295593006386 L 50.49999999999999 41.759818304894566 L 51.99999999999999 36.852341016782745 L 53.49999999999999 31.944863728670924 L 55 27.0373864405591 L 56.5 22.129909152447283 L 58 17.222431864335462 L 59.5 12.314954576223641 L 61 7.407477288111821 L 62.5 2.5 Z",
"M 62.50000000000001 2.5 L 66.66666666666669 5.52726053335567 L 70.83333333333334 8.55452106671134 L 75 11.58178160006701 L 79.16666666666667 14.609042133422681 L 83.33333333333333 17.636302666778352 L 87.5 20.66356320013402 L 91.66666666666667 23.69082373348969 L 95.83333333333333 26.718084266845363 L 100 29.745344800201035 L 104.16666666666667 32.772605333556704 L 108.33333333333333 35.79986586691237 L 112.5 38.82712640026804 L 110.90847495312455 43.72533683603865 L 109.31694990624912 48.62354727180926 L 107.72542485937367 53.521757707579866 L 106.13389981249826 58.41996814335048 L 104.54237476562281 63.31817857912108 L 102.95084971874736 68.2163890148917 L 101.35932467187195 73.11459945066231 L 99.7677996249965 78.01280988643292 L 98.17627457812107 82.91102032220353 L 96.58474953124562 87.80923075797413 L 94.99322448437017 92.70744119374474 L 93.40169943749474 97.60565162951535 L 88.25141619791228 97.60565162951535 L 83.10113295832983 97.60565162951535 L 77.95084971874736 97.60565162951535 L 72.8005664791649 97.60565162951535 L 67.65028323958245 97.60565162951535 L 62.49999999999999 97.60565162951532 L 57.34971676041753 97.60565162951535 L 52.19943352083507 97.60565162951535 L 47.049150281252615 97.60565162951535 L 41.89886704167016 97.60565162951535 L 36.748583802087694 97.60565162951532 L 31.59830056250524 97.60565162951532 L 30.006775515629805 92.70744119374473 L 28.41525046875437 87.80923075797413 L 26.82372542187893 82.91102032220351 L 25.232200375003494 78.0128098864329 L 23.640675328128054 73.1145994506623 L 22.049150281252622 68.21638901489169 L 20.457625234377183 63.31817857912108 L 18.866100187501747 58.41996814335048 L 17.27457514062631 53.521757707579866 L 15.683050093750875 48.623547271809265 L 14.091525046875436 43.72533683603866 L 12.5 38.82712640026805 L 16.666666666666668 35.79986586691238 L 20.833333333333336 32.772605333556704 L 25 29.74534480020104 L 29.166666666666668 26.718084266845366 L 33.33333333333334 23.690823733489694 L 37.5 20.663563200134025 L 41.66666666666667 17.636302666778352 L 45.833333333333336 14.609042133422683 L 50.00000000000001 11.581781600067012 L 54.16666666666668 8.554521066711342 L 58.33333333333334 5.52726053335567 L 62.50000000000001 2.5 Z",
"M 62.50000000000001 2.5 L 64.04508497187476 9.135558181105461 L 65.59016994374949 15.77111636221092 L 67.13525491562422 22.40667454331638 L 68.68033988749895 29.04223272442184 L 70.22542485937367 35.6777909055273 L 71.7705098312484 42.31334908663276 L 78.55875819270702 41.73231197223864 L 85.34700655416562 41.15127485784452 L 92.1352549156242 40.5702377434504 L 98.92350327708282 39.989200629056285 L 105.7117516385414 39.408163514662164 L 112.5 38.82712640026804 L 106.66666666666667 42.34708977612453 L 100.83333333333333 45.86705315198102 L 94.99999999999999 49.38701652783749 L 89.16666666666666 52.90697990369398 L 83.33333333333333 56.42694327955047 L 77.49999999999999 59.94690665540694 L 80.15028323958245 66.22336415109169 L 82.8005664791649 72.49982164677641 L 85.45084971874736 78.77627914246115 L 88.10113295832981 85.05273663814587 L 90.75141619791229 91.32919413383063 L 93.40169943749474 97.60565162951535 L 88.25141619791229 93.14555045384402 L 83.10113295832983 88.6854492781727 L 77.95084971874736 84.22534810250136 L 72.80056647916493 79.76524692683002 L 67.65028323958245 75.30514575115869 L 62.5 70.84504457548736 L 57.34971676041754 75.30514575115869 L 52.19943352083508 79.76524692683002 L 47.04915028125262 84.22534810250134 L 41.89886704167016 88.68544927817267 L 36.74858380208771 93.14555045384401 L 31.59830056250524 97.60565162951532 L 34.24858380208771 91.3291941338306 L 36.89886704167016 85.05273663814587 L 39.54915028125262 78.77627914246114 L 42.19943352083508 72.49982164677641 L 44.84971676041754 66.22336415109169 L 47.5 59.94690665540694 L 41.66666666666667 56.42694327955047 L 35.83333333333333 52.90697990369398 L 30 49.387016527837496 L 24.166666666666664 45.86705315198102 L 18.333333333333336 42.347089776124534 L 12.5 38.82712640026805 L 19.288248361458596 39.40816351466217 L 26.07649672291719 39.989200629056285 L 32.864745084375784 40.570237743450406 L 39.65299344583438 41.15127485784453 L 46.441241807292975 41.73231197223864 L 53.229490168751575 42.31334908663276 L 54.77457514062632 35.6777909055273 L 56.319660112501055 29.04223272442184 L 57.86474508437579 22.40667454331638 L 59.409830056250534 15.77111636221092 L 60.95491502812527 9.135558181105461 L 62.50000000000001 2.5 Z",
],
},
},
}, {
easing: "ease-in-out",
duration: 3,
selector: true,
}).play();

Controls

Play JavaScript & Play CSS

Scene.js supports both JavaScript and CSS play methods.

Play JavaScript
Play CSS
var keyframes = {
".clapper": {
2: "transform: translate(-50%, -50%) rotate(0deg)",
2.5: "transform: rotate(-15deg)",
3: "transform: rotate(0deg)",
3.5: "transform: rotate(-10deg)",
},
".clapper-container" : {
0: Scene.zoomIn({ duration: 1 }),
},
".clapper .circle": {
0.3: Scene.zoomIn({ duration: 1 }),
},
".clapper .play": {
0: "transform: translate(-50%, -50%)",
0.6: Scene.zoomIn({ duration: 1 }),
},
".top .stick1": {
2: "transform: rotate(0deg)",
2.5: "transform: rotate(-20deg)",
3: "transform: rotate(0deg)",
3.5: "transform: rotate(-10deg)",
},
".stick1 .rect": i => ({
0: "transform: scale(0) skew(15deg)",
0.7: "transform: scale(1)",
options: { delay: 0.6 + i * 0.1 },
}),
".stick2 .rect": i => ({
0: "transform: scale(0) skew(-15deg)",
0.7: "transform: scale(1)",
options: { delay: 0.8 + i * 0.1 },
}),
};
new Scene(keyframes, {
selector: selector => ".play-method-js " + selector,
easing: "ease-in-out",
}).play();

new Scene(keyframes, {
selector: selector => ".play-method-css " + selector,
easing: "ease-in-out",
}).playCSS();

Effects

@scenejs/effects is a library that can create various animation effects in scenejs.

typing

Make a typing effect that is typed one character at a time like a typewriter. (see: .typing)

new Scene({
"[data-typing] .text span":
Scene.typing({
text: "Make a typing effect with Scene.js.",
duration: 7,
}),
"[data-typing] .cursor": {
0: { opacity: 0 },
0.5: { opacity: 0 },
"0.5>": { opacity: 1 },
1: { opacity: 1 },
options: {
iterationCount: "infinite",
}
},
}, {
selector: true,
}).play();

fadeIn

Make a fade in effect. (see: .fadeIn)

1
Scene
.fadeIn({ duration: 1 })
.setSelector("[data-fadein] .target")
.play();

fadeOut

Make a fade out effect. (see: .fadeIn)

1
Scene
.fadeOut()
.setDuration(1)
.setSelector("[data-fadeout] .target")
.play();

wipeIn

Make a wipe in effect. (see: .wipeIn)

1
Scene
.wipeIn({ duration: 1 })
.setSelector("[data-wipein] .target")
.play();

wipeOut

Make a wipe out effect. (see: .wipeOut)

1
Scene
.wipeOut({ duration: 1 })
.setSelector("[data-wipeout] .target")
.play();

zoomIn

Make a zoom in effect. (see: .zoomIn)

1
Scene
.zoomIn({ duration: 1 })
.setSelector("[data-zoomin] .target")
.play();

zoomOut

Make a zoom out effect. (see: .zoomOut)

1
Scene
.zoomOut({ duration: 1 })
.setSelector("[data-zoomout] .target")
.play();

shake

Make a shake effect. (see: .shake)

1
2
Scene
.shake()
.setDuration(0.2)
.setIterationCount("infinite")
.setSelector("[data-shake] .target")
.play();

Scene
.shake({
properties: {
transform: {
/* shakeX */
translateX: "5px",
/* shakeY */
translateY: "5px",
rotate: "5deg",
scale: [0.8, 1],
},
},
frequency: 10,
})
.setDuration(0.2)
.setIterationCount("infinite")
.setSelector("[data-shake] .target2")
.play();

shakeX

Make a horizontal shake effect. (see: .shakeX)

1
Scene
/* shakeX({ x: "5px", frequency: 10 }) */
.shakeX()
.setDuration(0.2)
.setIterationCount("infinite")
.setSelector("[data-shakex] .target")
.play();

shakeY

Make a vertical shake effect. (see: .shakeY)

1
Scene
/* shakeY({ y: "5px", frequency: 10 }) */
.shakeY()
.setDuration(0.2)
.setIterationCount("infinite")
.setSelector("[data-shakey] .target")
.play();

flip

You can create a flip effect horizontally, vertically, or diagonally. (see: .flip)

1
2
Scene
/* flip({ x: 1, y: 1, backside: false }) */
.flip()
.setDuration(1)
.setSelector("[data-flip] .target")
.play();
Scene
.flip({ backside: true })
.setDuration(1)
.setSelector("[data-flip] .target2")
.play();

flipX

You can create an effect that flips vertically around the x-axis. (see: .flipX)

1
2
Scene
/* flipX({ x: 1, backside: false }) */
.flipX()
.setDuration(1)
.setSelector("[data-flipx] .target")
.play();
Scene
.flipX({ backside: true })
.setDuration(1)
.setSelector("[data-flipx] .target2")
.play();

flipY

You can create an effect that flips horizontally around the y-axis. (see: .flipY)

1
2
Scene
/* flipY({ y: 1, backside: false }) */
.flipY()
.setDuration(1)
.setSelector("[data-flipy] .target")
.play();
Scene
.flipY({ backside: true })
.setDuration(1)
.setSelector("[data-flipy] .target2")
.play();

transition

Switch the scene from `item1` to `item2`. (see: .transition)

1
2
var transitionScene = new Scene({
"[data-transition] .target": {},
"[data-transition] .target2": {},
}, {
delay: 0.1,
easing: "ease-in-out",
selector: true,
});
Scene.transition(
transitionScene.getItem("[data-transition] .target"),
transitionScene.getItem("[data-transition] .target2"),
{
0: [
Scene.fadeOut({ duration: 1 }),
Scene.zoomIn({ from: 1, to: 2, duration: 1 }),
"opacity: 1; transform: rotate(0deg)",
],
1: "opacity: 0; transform: rotate(40deg)",
}
);
transitionScene.play();

Rendering

Export MP4

You can export CSS Animation to a video file with simple commands using ffmpeg and @scenejs/render.

Original Source

/*
# export mp4
$ render -i index.html --name scene
# export only mp3
$ render -i index.html --name scene -o output.mp3
# export mp3 file and mp4 file
$ render -i index.html --name scene -o output.mp3,output.mp4


-b, --bitrate [value] Bitrate of video (the higher the bit rate, the clearer the video quality) (defaults to "4096k")
-c, --cache <n> you can pass Capture. (0: false, 1: true) (defaults to 0)
-C, --codec Codec to encode video If you don't set it up, it's the default(mp4: libx264, webm:libvpx-vp9) (defaults to "")
-d, --duration <n> how many seconds to play (defaults to 0)
-f, --fps <n> fps (defaults to 60)
-h, --height <n> Video height to render (defaults to 1080)
-H, --help Output usage information
-i, --input [value] File URL to Rendering (defaults to "index.html")
-I, --iteration <n> iterationCount of the Scene set by the user himself. (defaults to 0)
-m, --media [value] Name of mediaScene to render (defaults to "mediaScene")
-M, --multi <n> Number of processes to create. (defaults to 1)
-n, --name [value] Name of scene to render (defaults to "scene")
-o, --output [value] Output file name (defaults to "output.mp4")
-p, --port <n> Port to Rendering (defaults to 3033)
-s, --scale <n> Scale of screen size (defaults to 1)
-S, --startTime <n> Time to start (defaults to 0)
-v, --version Output the version number
-w, --width <n> Video width to render (defaults to 1920)
*/