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

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

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

Loading…
Cancel
Save