UNPKG

@smoovy/tween

Version:
128 lines (127 loc) 3.8 kB
"use strict"; import { TweenController } from "./controller"; import { getDomProps, mergeDomProps, setDomProps } from "./dom"; function isTargetValid(target) { return target instanceof HTMLElement || target instanceof SVGElement; } function getChanges(from, to) { const changes = {}; for (const key in from) { if (Object.prototype.hasOwnProperty.call(from, key) && Object.prototype.hasOwnProperty.call(to, key)) { const change = to[key] - from[key]; if (change !== 0) { changes[key] = change; } } } return changes; } const _Tween = class extends TweenController { constructor(config) { super(config); this.config = config; this.registry = _Tween.registry; this.originState = {}; this.changedState = {}; this.resultState = {}; this.update(); if (config.reversed) { this.reverse(); } if (config.initSeek) { this.seek(0, true, true); } if (config.autoStart !== false) { this.start(); } } get key() { return this.config.key || this.config.target || this.config.from; } updateRegistry() { const tween = this.registry.get(this.key); if (this.config.overwrite !== false && tween) { this.overwrite(this.key); } this.registry.set(this.key, this); } beforeStop() { this.registry.delete(this.key); } beforeSeek() { this.updateRegistry(); if (this.config.seekUpdate !== false) { this.update(); } } overwrite(key) { const tween = this.registry.get(key); if (tween) { if (!this._overridden && tween.ticking) { tween.stop(); } this.registry.delete(key); this.callback(this.config.onOverwrite, [tween]); } } update() { const config = this.config; const fromState = config.from; if (config.target && isTargetValid(config.target)) { this.domTarget = config.target; } else if (isTargetValid(fromState)) { this.domTarget = fromState; } if (this.domTarget) { const { values: currentState } = getDomProps(this.domTarget); const initialState = fromState instanceof HTMLElement ? { ...currentState } : mergeDomProps(currentState, fromState); const desiredState = mergeDomProps( currentState, config.to ); const changedState = getChanges(initialState, desiredState); this.originState = initialState; this.changedState = changedState; this.resultState = { ...this.originState }; for (const x in this.resultState) { if (!Object.hasOwnProperty.call(config.to, x)) { delete this.resultState[x]; } } } else { const initialState = fromState; const desiredState = config.to; this.originState = { ...initialState }; this.changedState = getChanges(this.originState, desiredState); if (config.target && !isTargetValid(config.target)) { this.resultState = config.target; } else { this.resultState = config.mutate !== false ? initialState : { ...this.originState }; } } return this; } process(eased, linear) { let changed = false; for (const prop in this.changedState) { if (this.changedState[prop] !== void 0) { const change = this.changedState[prop]; const origin = this.originState[prop]; if (origin !== void 0) { this.resultState[prop] = origin + change * eased; changed = true; } } } if (this.domTarget && changed) { setDomProps(this.domTarget, this.resultState, this.config.units); } this.callback( this.config.onUpdate, [this.resultState, { target: this, linear, eased }] ); return this; } }; export let Tween = _Tween; Tween.registry = /* @__PURE__ */ new WeakMap();