UNPKG

just-animate

Version:
123 lines (122 loc) 4.77 kB
import { includes, pushDistinct, all, find } from '../lib/utils/lists'; import { _ } from '../lib/utils/constants'; import { isDefined } from '../lib/utils/inspect'; import { TRANSFORM, transforms, aliases, PX, transformAngles, DEG, transformLengths } from './constants'; import { parseUnit } from './parse-unit'; export function combineTransforms(target, effects, propToPlugin) { const transformNames = target.propNames.filter(t => includes(transforms, t)); if (!transformNames.length) { return; } if (includes(target.propNames, TRANSFORM)) { throw new Error('transform + shorthand is not allowed'); } const offsets = []; const easings = {}; all(transformNames, name => { const effects2 = effects[name]; if (effects2) { all(effects2, effect => { easings[effect.offset] = effect.easing; pushDistinct(offsets, effect.offset); }); } }); offsets.sort(); const transformEffects = offsets.map(offset => { const values = {}; all(transformNames, name => { const effect = find(effects[name], e => e.offset === offset); values[name] = effect ? effect.value : _; }); return { offset, easing: easings[offset], values }; }); const len = transformEffects.length; for (let i = len - 1; i > -1; --i) { const effect = transformEffects[i]; for (const transform in effect.values) { let value = effect.values[transform]; if (isDefined(value)) { continue; } let startingPos = _; for (var j = i - 1; j > -1; j--) { if (isDefined(transformEffects[j].values[transform])) { startingPos = j; break; } } let endingPos = _; for (var k = i + 1; k < len; k++) { if (isDefined(transformEffects[k].values[transform])) { endingPos = k; break; } } const startingPosFound = startingPos !== _; const endingPosFound = endingPos !== _; if (startingPosFound && endingPosFound) { const startEffect = transformEffects[startingPos]; const endEffect = transformEffects[endingPos]; const startVal = parseUnit(startEffect.values[transform]); const endVal = parseUnit(endEffect.values[transform]); for (let g = startingPos + 1; g < endingPos; g++) { const currentOffset = offsets[g]; const offsetDelta = (currentOffset - startEffect.offset) / (endEffect.offset - startEffect.offset); const currentValue = startVal.value + (endVal.value - startVal.value) * offsetDelta; const currentValueWithUnit = currentValue + (endVal.unit || startVal.unit || ''); const currentKeyframe = transformEffects[g]; currentKeyframe.values[transform] = currentValueWithUnit; } } else if (startingPosFound) { for (let g = startingPos + 1; g < len; g++) { transformEffects[g].values[transform] = transformEffects[startingPos].values[transform]; } } } } if (transformEffects.length) { all(transformNames, name => { effects[name] = _; }); const transformEffects2 = []; all(transformEffects, effect => { let val = _; for (var prop in effect.values) { const unit = parseUnit(effect.values[prop]); if (unit.value === _) { continue; } if (!unit.unit) { unit.unit = includes(transformLengths, prop) ? PX : includes(transformAngles, prop) ? DEG : ''; } val = (val ? val + ' ' : '') + (aliases[prop] || prop) + '(' + unit.value + unit.unit + ')'; } transformEffects2.push({ offset: effect.offset, value: val, easing: effect.easing, interpolate: _ }); }); effects[TRANSFORM] = transformEffects2; propToPlugin[TRANSFORM] = 'web'; } }