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%
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]
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.
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)
Scene
.fadeIn({ duration: 1 })
.setSelector("[data-fadein] .target")
.play();
fadeOut
Make a fade out effect. (see: .fadeIn)
Scene
.fadeOut()
.setDuration(1)
.setSelector("[data-fadeout] .target")
.play();
blink
Make a blinking effect. (see: .blink)
Scene
.blink({ duration: 1 })
.setSelector("[data-blink] .target")
.play();
wipeIn
Make a wipe in effect. (see: .wipeIn)
Scene
.wipeIn({ duration: 1 })
.setSelector("[data-wipein] .target")
.play();
wipeOut
Make a wipe out effect. (see: .wipeOut)
Scene
.wipeOut({ duration: 1 })
.setSelector("[data-wipeout] .target")
.play();
zoomIn
Make a zoom in effect. (see: .zoomIn)
Scene
.zoomIn({ duration: 1 })
.setSelector("[data-zoomin] .target")
.play();
zoomOut
Make a zoom out effect. (see: .zoomOut)
Scene
.zoomOut({ duration: 1 })
.setSelector("[data-zoomout] .target")
.play();
shake
Make a shake effect. (see: .shake)
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)
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)
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)
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)
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)
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)
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)
*/