Skip to content

Commit 456dfb9

Browse files
authored
Add pause/resume to shader and CSS animations (css-doodle#78)
* Add pause/resume to shader animations * A quick implementation to pause/resume CSS animation * Reduce min frame rate to 1fps * Use last step value if possible
1 parent 2fdc2c4 commit 456dfb9

File tree

2 files changed

+57
-15
lines changed

2 files changed

+57
-15
lines changed

src/index.js

+21-9
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ if (typeof customElements !== 'undefined') {
4747

4848
disconnectedCallback() {
4949
Cache.clear();
50-
this.clear_animations();
50+
for (let animation of this.animations) {
51+
animation.cancel();
52+
}
53+
this.animations = [];
5154
}
5255

5356
update(styles) {
@@ -241,11 +244,18 @@ if (typeof customElements !== 'undefined') {
241244
draw_canvas(code).then(fn);
242245
}
243246

244-
clear_animations() {
247+
pause() {
248+
this.setAttribute('cssd-paused-animation', true);
245249
for (let animation of this.animations) {
246-
animation.cancel();
250+
animation.pause();
251+
}
252+
}
253+
254+
resume() {
255+
this.removeAttribute('cssd-paused-animation');
256+
for (let animation of this.animations) {
257+
animation.resume();
247258
}
248-
this.animations = [];
249259
}
250260

251261
shader_to_image({ shader, cell, id }, fn) {
@@ -581,11 +591,9 @@ function get_basic_styles() {
581591
.map(n => `${ n }: inherit;`)
582592
.join('');
583593
return `
584-
* {
585-
box-sizing: border-box
586-
}
587-
*::after, *::before {
588-
box-sizing: inherit
594+
*, *::after, *::before {
595+
box-sizing: border-box;
596+
animation-play-state: var(--cssd-animation-play-state) !important;
589597
}
590598
:host, .host {
591599
display: block;
@@ -615,6 +623,10 @@ function get_basic_styles() {
615623
width: 100%;
616624
height: 100%;
617625
}
626+
:host([cssd-paused-animation]) {
627+
--cssd-animation-play-state: paused;
628+
animation-play-state: paused !important;
629+
}
618630
`;
619631
}
620632

src/utils/create-animation-frame.js

+36-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,44 @@
1+
const STEP60 = 1000 / 60; // 60fps
2+
const STEP1 = 1000 / 1; // 1fps
3+
14
function createAnimationFrame(fn) {
25
let id;
3-
function _loop(stamp) {
4-
fn(stamp);
5-
id = requestAnimationFrame(_loop);
6+
let time = 0;
7+
let lastTime = 0;
8+
let lastStep = 0;
9+
let paused = false;
10+
function loop(stamp) {
11+
if (!time) time = stamp;
12+
fn(time);
13+
let step = (stamp - lastTime);
14+
if (step < STEP60) step = STEP60;
15+
if (step > STEP1) step = lastStep || STEP1;
16+
if (lastTime) time += step;
17+
lastStep = step;
18+
lastTime = stamp;
19+
id = requestAnimationFrame(loop);
620
}
7-
id = requestAnimationFrame(_loop);
21+
id = requestAnimationFrame(loop);
822
return {
23+
resume() {
24+
if (id && paused) {
25+
paused = false;
26+
id = requestAnimationFrame(loop);
27+
}
28+
},
29+
pause() {
30+
if (id) {
31+
cancelAnimationFrame(id);
32+
paused = true;
33+
}
34+
},
935
cancel() {
10-
cancelAnimationFrame(id);
11-
}
36+
if (id) {
37+
paused = false;
38+
cancelAnimationFrame(id);
39+
id = null;
40+
}
41+
},
1242
}
1343
}
1444

0 commit comments

Comments
 (0)