just-animate
Version:
_Making Animation Simple_
123 lines (122 loc) • 4.77 kB
JavaScript
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';
}
}