feat: Convert src/runtime/internal/animations.ts to JavaScript

pull/8569/head
S. Elliott Johnson 3 years ago
parent b6a400a549
commit 7d94c82fb2

@ -2,115 +2,99 @@ import { identity as linear, noop } from './utils';
import { now } from './environment'; import { now } from './environment';
import { loop } from './loop'; import { loop } from './loop';
import { create_rule, delete_rule } from './style_manager'; import { create_rule, delete_rule } from './style_manager';
import { AnimationConfig } from '../animate'; /** @param {Element & ElementCSSInlineStyle} node
* @param {PositionRect} from
//todo: documentation says it is DOMRect, but in IE it would be ClientRect * @param {AnimationFn} fn
type PositionRect = DOMRect | ClientRect; * @returns {any}
*/
type AnimationFn = ( export function create_animation(node, from, fn, params) {
node: Element, if (!from)
{ from, to }: { from: PositionRect; to: PositionRect }, return noop;
params: any const to = node.getBoundingClientRect();
) => AnimationConfig; if (from.left === to.left &&
from.right === to.right &&
export function create_animation( from.top === to.top &&
node: Element & ElementCSSInlineStyle, from.bottom === to.bottom)
from: PositionRect, return noop;
fn: AnimationFn, const { delay = 0, duration = 300, easing = linear,
params // @ts-ignore todo: should this be separated from destructuring? Or start/end added to public api and documentation?
) { start: start_time = now() + delay,
if (!from) return noop; // @ts-ignore todo:
end = start_time + duration, tick = noop, css } = fn(node, { from, to }, params);
const to = node.getBoundingClientRect(); let running = true;
if ( let started = false;
from.left === to.left && let name;
from.right === to.right && /** @returns {void} */
from.top === to.top && function start() {
from.bottom === to.bottom if (css) {
) name = create_rule(node, 0, 1, duration, delay, easing, css);
return noop; }
if (!delay) {
const { started = true;
delay = 0, }
duration = 300, }
easing = linear, /** @returns {void} */
// @ts-ignore todo: should this be separated from destructuring? Or start/end added to public api and documentation? function stop() {
start: start_time = now() + delay, if (css)
// @ts-ignore todo: delete_rule(node, name);
end = start_time + duration, running = false;
tick = noop, }
css loop((now) => {
} = fn(node, { from, to }, params); if (!started && now >= start_time) {
started = true;
let running = true; }
let started = false; if (started && now >= end) {
let name; tick(1, 0);
stop();
function start() { }
if (css) { if (!running) {
name = create_rule(node, 0, 1, duration, delay, easing, css); return false;
} }
if (started) {
if (!delay) { const p = now - start_time;
started = true; const t = 0 + 1 * easing(p / duration);
} tick(t, 1 - t);
} }
return true;
function stop() { });
if (css) delete_rule(node, name); start();
running = false; tick(0, 1);
} return stop;
loop((now) => {
if (!started && now >= start_time) {
started = true;
}
if (started && now >= end) {
tick(1, 0);
stop();
}
if (!running) {
return false;
}
if (started) {
const p = now - start_time;
const t = 0 + 1 * easing(p / duration);
tick(t, 1 - t);
}
return true;
});
start();
tick(0, 1);
return stop;
} }
/** @param {Element & ElementCSSInlineStyle} node
export function fix_position(node: Element & ElementCSSInlineStyle) { * @returns {void}
const style = getComputedStyle(node); */
export function fix_position(node) {
if (style.position !== 'absolute' && style.position !== 'fixed') { const style = getComputedStyle(node);
const { width, height } = style; if (style.position !== 'absolute' && style.position !== 'fixed') {
const a = node.getBoundingClientRect(); const { width, height } = style;
node.style.position = 'absolute'; const a = node.getBoundingClientRect();
node.style.width = width; node.style.position = 'absolute';
node.style.height = height; node.style.width = width;
add_transform(node, a); node.style.height = height;
} add_transform(node, a);
}
}
/** @param {Element & ElementCSSInlineStyle} node
* @param {PositionRect} a
* @returns {void}
*/
export function add_transform(node, a) {
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)`;
}
} }
export function add_transform(node: Element & ElementCSSInlineStyle, a: PositionRect) {
const b = node.getBoundingClientRect();
if (a.left !== b.left || a.top !== b.top) { /** @typedef {DOMRect | ClientRect} PositionRect */
const style = getComputedStyle(node); /**
const transform = style.transform === 'none' ? '' : style.transform; * @typedef {(
* node: Element,
* { from, to }: { from: PositionRect; to: PositionRect },
* params: any
* ) => AnimationConfig} AnimationFn
*/
node.style.transform = `${transform} translate(${a.left - b.left}px, ${a.top - b.top}px)`;
}
}

Loading…
Cancel
Save