UNPKG

just-animate

Version:
102 lines (101 loc) 3.32 kB
import { interpolator } from '../lib/core/interpolate'; import { _ } from '../lib/utils/constants'; import { isDOM } from '../lib/utils/inspect'; import { hyphenate } from '../lib/utils/strings'; import { includes } from '../lib/utils/lists'; const PROPERTY = 0; const ATTRIBUTE = 1; const ATTRIBUTE_HYPHENATE = 2; const CSSVAR = 3; const cssVarExp = /^\-\-[a-z0-9\-]+$/i; const viewbox = 'viewBox'; const svgReadonly = 'rx ry viewBox transform x x1 x2 y y1 y2'.split(' '); const noHyphenate = [viewbox]; export const propsPlugin = { name: 'props', animate(effect) { const { target, prop } = effect; const interpolate = interpolator(effect.to - effect.from, effect.keyframes); const propSetter = getTargetSetter(target, prop); const propGetter = getTargetGetter(target, prop); let initial = _; return { cancel() { if (initial !== _) { propSetter(initial); } initial = _; }, update(localTime, _playbackRate, _isActive) { if (initial === _) { initial = propGetter(); } propSetter(interpolate(localTime)); } }; }, getValue(target, prop) { return getTargetGetter(target, prop)(); } }; function getTargetType(target, prop) { if (!isDOM(target)) { return PROPERTY; } if (cssVarExp.test(prop)) { return CSSVAR; } if (typeof target[prop] !== 'undefined' && !includes(svgReadonly, prop)) { return PROPERTY; } if (includes(noHyphenate, prop)) { return ATTRIBUTE; } return ATTRIBUTE_HYPHENATE; } function getTargetGetter(target, prop) { const targetType = getTargetType(target, prop); return targetType === CSSVAR ? getVariable(target, prop) : targetType === ATTRIBUTE ? getAttribute(target, prop) : targetType === ATTRIBUTE_HYPHENATE ? getAttributeHyphenate(target, prop) : getProperty(target, prop); } function getTargetSetter(target, prop) { const targetType = getTargetType(target, prop); return targetType === CSSVAR ? setVariable(target, prop) : targetType === ATTRIBUTE ? setAttribute(target, prop) : targetType === ATTRIBUTE_HYPHENATE ? setAttributeHyphenate(target, prop) : setProperty(target, prop); } function getAttribute(target, name) { return () => target.getAttribute(name); } function setAttribute(target, name) { return (value) => target.setAttribute(name, value); } function setAttributeHyphenate(target, name) { const attName = hyphenate(name); return (value) => target.setAttribute(attName, value); } function getAttributeHyphenate(target, name) { const attName = hyphenate(name); return () => target.getAttribute(attName); } function getVariable(target, name) { return () => target.style.getPropertyValue(name); } function setVariable(target, name) { return (value) => target.style.setProperty(name, value ? value + '' : ''); } function setProperty(target, name) { return (value) => (target[name] = value); } function getProperty(target, name) { return () => target[name]; }