UNPKG

1.76 kBJavaScriptView Raw
1import flattenStyle from './flattenStyle';
2
3function compareNumbers(a, b) {
4 return a - b;
5}
6
7function notNull(value) {
8 return value !== null;
9}
10
11function parsePosition(value) {
12 if (value === 'from') {
13 return 0;
14 } else if (value === 'to') {
15 return 1;
16 }
17 const parsed = parseFloat(value, 10);
18 if (isNaN(parsed) || parsed < 0 || parsed > 1) {
19 return null;
20 }
21 return parsed;
22}
23
24const cache = {};
25
26export default function createAnimation(definition) {
27 const cacheKey = JSON.stringify(definition);
28 if (cache[cacheKey]) {
29 return cache[cacheKey];
30 }
31
32 const positions = Object.keys(definition)
33 .map(parsePosition)
34 .filter(notNull);
35 positions.sort(compareNumbers);
36
37 if (positions.length < 2) {
38 throw new Error('Animation definitions must have at least two values.');
39 }
40
41 const compiled = {};
42 if (definition.easing) {
43 compiled.easing = definition.easing;
44 }
45 if (definition.style) {
46 compiled.style = definition.style;
47 }
48
49 for (let i = 0; i < positions.length; i += 1) {
50 const position = positions[i];
51 let keyframe = definition[position];
52 if (!keyframe) {
53 if (position === 0) {
54 keyframe = definition.from;
55 } else if (position === 1) {
56 keyframe = definition.to;
57 }
58 }
59 if (!keyframe) {
60 throw new Error('Missing animation keyframe, this should not happen');
61 }
62
63 keyframe = flattenStyle(keyframe);
64 Object.keys(keyframe).forEach(key => {
65 if (!(key in compiled)) {
66 compiled[key] = {
67 inputRange: [],
68 outputRange: [],
69 };
70 }
71 compiled[key].inputRange.push(position);
72 compiled[key].outputRange.push(keyframe[key]);
73 });
74 }
75
76 cache[cacheKey] = compiled;
77
78 return compiled;
79}