diff --git a/src/internal/animations.js b/src/internal/animations.js index b8ed7407ef..7e6b112fd0 100644 --- a/src/internal/animations.js +++ b/src/internal/animations.js @@ -1,4 +1,4 @@ -import { identity as linear } from './utils.js'; +import { identity as linear, noop } from './utils.js'; import { loop } from './loop.js'; import { create_rule, delete_rule } from './style_manager.js'; @@ -8,59 +8,50 @@ export function wrapAnimation(node, from, fn, params) { const to = node.getBoundingClientRect(); if (from.left === to.left && from.right === to.right && from.top === to.top && from.bottom === to.bottom) return; - const info = fn(node, { from, to }, params); + const { + delay = 0, + duration = 300, + easing = linear, + start: start_time = window.performance.now() + delay, + end = start_time + duration, + tick = noop, + css + } = 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_time = window.performance.now() + delay; - const end = start_time + duration; - - const program = { - a: 0, - t: 0, - b: 1, - delta: 1, - duration, - start: start_time, - end - }; + let running = true; + let started = false; + let name; const cssText = node.style.cssText; function start() { - if (info.css) { + if (css) { if (delay) node.style.cssText = cssText; - program.name = create_rule(program, ease, info.css); + name = create_rule({ a: 0, b: 1, delta: 1, duration }, easing, css); 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`) + .filter(anim => anim && !/__svelte/.test(anim)) + .concat(`${name} ${duration}ms linear 1 forwards`) .join(', '); } - running_program = program; - pending_program = null; + started = true; } - let running = true; - let pending_program = delay ? program : null; - let running_program = delay ? null : program; - function stop() { - if (info.css) delete_rule(node, program.name); + if (css) delete_rule(node, name); running = false; } const { abort, promise } = loop(now => { - if (pending_program && now >= pending_program.start) { + if (!started && now >= start_time) { start(); } - if (running_program && now >= running_program.end) { - if (info.tick) info.tick(1, 0); + if (started && now >= end) { + tick(1, 0); stop(); } @@ -68,19 +59,19 @@ export function wrapAnimation(node, from, fn, params) { return false; } - if (running_program) { - const p = now - program.start; - const t = program.a + program.delta * ease(p / program.duration); - if (info.tick) info.tick(t, 1 - t); + if (started) { + const p = now - start_time; + const t = 0 + 1 * easing(p / duration); + tick(t, 1 - t); } return true; }); - if (info.tick) info.tick(0, 1); + tick(0, 1); if (delay) { - if (info.css) node.style.cssText += info.css(0, 1); + if (css) node.style.cssText += css(0, 1); } else { start(); }