mirror of https://github.com/sveltejs/svelte
allow animations to be aborted - fixes #1458
parent
ee052dc7bd
commit
31e387e76c
@ -0,0 +1,92 @@
|
|||||||
|
import { transitionManager, linear, generateRule, hash } from './transitions.js';
|
||||||
|
|
||||||
|
export function wrapAnimation(node, from, fn, params) {
|
||||||
|
if (!from) return;
|
||||||
|
|
||||||
|
const to = node.getBoundingClientRect();
|
||||||
|
if (from.left === to.left && from.right === to.right && from.top === to.top && from.bottom === to.bottom) return;
|
||||||
|
|
||||||
|
// console.log({ x: from.x, y: from.y }, { x: to.x, y: to.y }, node.textContent.trim())
|
||||||
|
|
||||||
|
const info = fn(node, { from, to }, params);
|
||||||
|
|
||||||
|
const duration = 'duration' in info ? info.duration : 300;
|
||||||
|
const delay = 'delay' in info ? info.delay : 0;
|
||||||
|
const ease = info.easing || linear;
|
||||||
|
const start = window.performance.now() + delay;
|
||||||
|
const end = start + duration;
|
||||||
|
|
||||||
|
const program = {
|
||||||
|
a: 0,
|
||||||
|
t: 0,
|
||||||
|
b: 1,
|
||||||
|
delta: 1,
|
||||||
|
duration,
|
||||||
|
start,
|
||||||
|
end
|
||||||
|
};
|
||||||
|
|
||||||
|
const animation = {
|
||||||
|
pending: delay ? program : null,
|
||||||
|
program: delay ? null : program,
|
||||||
|
running: !delay,
|
||||||
|
|
||||||
|
start() {
|
||||||
|
if (info.css) {
|
||||||
|
const rule = generateRule(program, ease, info.css);
|
||||||
|
program.name = `__svelte_${hash(rule)}`;
|
||||||
|
|
||||||
|
transitionManager.addRule(rule, program.name);
|
||||||
|
|
||||||
|
node.style.animation = (node.style.animation || '')
|
||||||
|
.split(', ')
|
||||||
|
.filter(anim => anim && (program.delta < 0 || !/__svelte/.test(anim)))
|
||||||
|
.concat(`${program.name} ${program.duration}ms linear 1 forwards`)
|
||||||
|
.join(', ');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
update: now => {
|
||||||
|
const p = now - program.start;
|
||||||
|
const t = program.a + program.delta * ease(p / program.duration);
|
||||||
|
if (info.tick) info.tick(t, 1 - t);
|
||||||
|
},
|
||||||
|
|
||||||
|
done() {
|
||||||
|
if (info.tick) info.tick(1, 0);
|
||||||
|
this.stop();
|
||||||
|
},
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
if (info.css) transitionManager.deleteRule(node, program.name);
|
||||||
|
animation.running = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
transitionManager.add(animation);
|
||||||
|
|
||||||
|
if (info.tick) info.tick(0, 1);
|
||||||
|
if (!delay) animation.start();
|
||||||
|
|
||||||
|
return animation;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fixPosition(node) {
|
||||||
|
const style = getComputedStyle(node);
|
||||||
|
|
||||||
|
if (style.position !== 'absolute' && style.position !== 'fixed') {
|
||||||
|
const { width, height } = style;
|
||||||
|
const a = node.getBoundingClientRect();
|
||||||
|
node.style.position = 'absolute';
|
||||||
|
node.style.width = width;
|
||||||
|
node.style.height = height;
|
||||||
|
const b = node.getBoundingClientRect();
|
||||||
|
|
||||||
|
if (a.left !== b.left || a.top !== b.top) {
|
||||||
|
const style = getComputedStyle(node);
|
||||||
|
const transform = style.transform === 'none' ? '' : style.transform;
|
||||||
|
|
||||||
|
node.style.transform = `${transform} translate(${a.left - b.left}px, ${a.top - b.top}px)`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue