motion 10.2.1 → 10.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +1 -0
- package/dist/main.cjs.js +2 -0
- package/dist/main.es.js +1 -0
- package/dist/motion.min.js +1 -1
- package/dist/motion.umd.js +426 -280
- package/dist/size-animate-dom.js +1 -1
- package/dist/size-animate-style.js +1 -1
- package/dist/size-react.js +1 -1
- package/dist/size-spring.js +1 -1
- package/dist/size-timeline-dom.js +1 -1
- package/dist/size-webpack-animate.js +1 -1
- package/dist/targets/dom/animate-style.cjs.js +135 -134
- package/dist/targets/dom/animate-style.es.js +137 -136
- package/dist/targets/dom/animate.cjs.js +15 -4
- package/dist/targets/dom/animate.es.js +16 -5
- package/dist/targets/dom/data.cjs.js +4 -3
- package/dist/targets/dom/data.es.js +4 -3
- package/dist/targets/dom/style.cjs.js +1 -1
- package/dist/targets/dom/style.es.js +2 -2
- package/dist/targets/dom/timeline/index.cjs.js +7 -6
- package/dist/targets/dom/timeline/index.es.js +8 -7
- package/dist/targets/dom/timeline/utils/calc-time.cjs.js +3 -1
- package/dist/targets/dom/timeline/utils/calc-time.es.js +3 -1
- package/dist/targets/dom/utils/apply.cjs.js +4 -8
- package/dist/targets/dom/utils/apply.es.js +3 -7
- package/dist/targets/dom/utils/controls.cjs.js +6 -2
- package/dist/targets/dom/utils/controls.es.js +6 -2
- package/dist/targets/dom/utils/css-var.cjs.js +2 -2
- package/dist/targets/dom/utils/css-var.es.js +3 -3
- package/dist/targets/dom/utils/easing.cjs.js +4 -2
- package/dist/targets/dom/utils/easing.es.js +4 -2
- package/dist/targets/dom/utils/feature-detection.cjs.js +4 -4
- package/dist/targets/dom/utils/feature-detection.es.js +4 -4
- package/dist/targets/dom/utils/get-style-name.cjs.js +13 -0
- package/dist/targets/dom/utils/get-style-name.es.js +9 -0
- package/dist/targets/dom/utils/keyframes.cjs.js +2 -4
- package/dist/targets/dom/utils/keyframes.es.js +2 -4
- package/dist/targets/dom/utils/options.cjs.js +1 -1
- package/dist/targets/dom/utils/options.es.js +1 -1
- package/dist/targets/dom/utils/stop-animation.cjs.js +2 -0
- package/dist/targets/dom/utils/stop-animation.es.js +2 -0
- package/dist/targets/dom/utils/transforms.cjs.js +10 -7
- package/dist/targets/dom/utils/transforms.es.js +10 -7
- package/dist/targets/js/{animate-number.cjs.js → NumberAnimation.cjs.js} +40 -29
- package/dist/targets/js/{animate-number.es.js → NumberAnimation.es.js} +40 -28
- package/dist/targets/js/easing/glide/generator.cjs.js +99 -0
- package/dist/targets/js/easing/glide/generator.es.js +95 -0
- package/dist/targets/js/easing/glide/index.cjs.js +10 -0
- package/dist/targets/js/easing/glide/index.es.js +6 -0
- package/dist/targets/js/easing/spring/generator.cjs.js +9 -4
- package/dist/targets/js/easing/spring/generator.es.js +9 -5
- package/dist/targets/js/easing/spring/index.cjs.js +2 -62
- package/dist/targets/js/easing/spring/index.es.js +2 -62
- package/dist/targets/js/easing/utils/create-generator-easing.cjs.js +71 -0
- package/dist/targets/js/easing/utils/create-generator-easing.es.js +67 -0
- package/dist/targets/js/easing/utils/has-reached-target.cjs.js +10 -0
- package/dist/targets/js/easing/utils/has-reached-target.es.js +6 -0
- package/dist/targets/js/easing/utils/pregenerate-keyframes.cjs.js +13 -10
- package/dist/targets/js/easing/utils/pregenerate-keyframes.es.js +13 -10
- package/dist/targets/react/hooks/use-animation.cjs.js +5 -2
- package/dist/targets/react/hooks/use-animation.es.js +5 -2
- package/dist/targets/react/utils/keyframes.cjs.js +5 -3
- package/dist/targets/react/utils/keyframes.es.js +6 -4
- package/dist/utils/is-number.cjs.js +7 -0
- package/dist/utils/is-number.es.js +3 -0
- package/dist/utils/stagger.cjs.js +2 -1
- package/dist/utils/stagger.es.js +2 -1
- package/package.json +4 -10
- package/types/index.d.ts +1 -0
- package/types/targets/dom/animate-style.d.ts +2 -2
- package/types/targets/dom/style.d.ts +1 -1
- package/types/targets/dom/types.d.ts +8 -4
- package/types/targets/dom/utils/apply.d.ts +3 -2
- package/types/targets/dom/utils/controls.d.ts +3 -3
- package/types/targets/dom/utils/get-style-name.d.ts +1 -0
- package/types/targets/dom/utils/keyframes.d.ts +1 -1
- package/types/targets/dom/utils/stop-animation.d.ts +1 -1
- package/types/targets/dom/utils/transforms.d.ts +2 -2
- package/types/targets/js/{animate-number.d.ts → NumberAnimation.d.ts} +2 -3
- package/types/targets/js/easing/glide/generator.d.ts +5 -0
- package/types/targets/js/easing/glide/index.d.ts +2 -0
- package/types/targets/js/easing/glide/types.d.ts +14 -0
- package/types/targets/js/easing/spring/generator.d.ts +1 -0
- package/types/targets/js/easing/spring/index.d.ts +1 -2
- package/types/targets/js/easing/utils/create-generator-easing.d.ts +3 -0
- package/types/targets/js/easing/utils/has-reached-target.d.ts +1 -0
- package/types/targets/js/easing/utils/pregenerate-keyframes.d.ts +1 -1
- package/types/targets/js/types.d.ts +3 -0
- package/types/utils/is-number.d.ts +1 -0
|
@@ -7,175 +7,176 @@ var cssVar = require('./utils/css-var.cjs.js');
|
|
|
7
7
|
var noop = require('../../utils/noop.cjs.js');
|
|
8
8
|
var time = require('./utils/time.cjs.js');
|
|
9
9
|
var transforms = require('./utils/transforms.cjs.js');
|
|
10
|
-
var stopAnimation = require('./utils/stop-animation.cjs.js');
|
|
11
10
|
var easing = require('./utils/easing.cjs.js');
|
|
12
11
|
var featureDetection = require('./utils/feature-detection.cjs.js');
|
|
13
12
|
var apply = require('./utils/apply.cjs.js');
|
|
14
|
-
var
|
|
13
|
+
var NumberAnimation = require('../js/NumberAnimation.cjs.js');
|
|
15
14
|
var keyframes = require('./utils/keyframes.cjs.js');
|
|
16
15
|
var style = require('./style.cjs.js');
|
|
17
16
|
var defaults = require('./utils/defaults.cjs.js');
|
|
17
|
+
var getStyleName = require('./utils/get-style-name.cjs.js');
|
|
18
|
+
var isNumber = require('../../utils/is-number.cjs.js');
|
|
19
|
+
var stopAnimation = require('./utils/stop-animation.cjs.js');
|
|
18
20
|
|
|
19
|
-
function animateStyle(element,
|
|
21
|
+
function animateStyle(element, key, keyframesDefinition, options = {}) {
|
|
20
22
|
let animation;
|
|
21
23
|
let { duration = defaults.defaults.duration, delay = defaults.defaults.delay, endDelay = defaults.defaults.endDelay, repeat = defaults.defaults.repeat, easing: easing$1 = defaults.defaults.easing, direction, offset, allowWebkitAcceleration = false, } = options;
|
|
22
24
|
const data$1 = data.getAnimationData(element);
|
|
23
25
|
let canAnimateNatively = featureDetection.supports.waapi();
|
|
24
26
|
let render = noop.noop;
|
|
25
|
-
const valueIsTransform = transforms.isTransform(
|
|
27
|
+
const valueIsTransform = transforms.isTransform(key);
|
|
26
28
|
/**
|
|
27
29
|
* If this is an individual transform, we need to map its
|
|
28
30
|
* key to a CSS variable and update the element's transform style
|
|
29
31
|
*/
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
name = transforms.transformAlias[name];
|
|
33
|
-
transforms.addTransformToElement(element, name);
|
|
34
|
-
name = transforms.asTransformCssVar(name);
|
|
35
|
-
}
|
|
32
|
+
valueIsTransform && transforms.addTransformToElement(element, key);
|
|
33
|
+
const name = getStyleName.getStyleName(key);
|
|
36
34
|
/**
|
|
37
35
|
* Get definition of value, this will be used to convert numerical
|
|
38
36
|
* keyframes into the default value type.
|
|
39
37
|
*/
|
|
40
|
-
const definition = transforms.
|
|
41
|
-
/**
|
|
42
|
-
* Replace null values with the previous keyframe value, or read
|
|
43
|
-
* it from the DOM if it's the first keyframe.
|
|
44
|
-
*
|
|
45
|
-
* TODO: This needs to come after the valueIsTransform
|
|
46
|
-
* check so it can correctly read the underlying value.
|
|
47
|
-
* Should make a test for this.
|
|
48
|
-
*/
|
|
49
|
-
let keyframes$1 = keyframes.hydrateKeyframes(keyframes.keyframesList(keyframesDefinition), element, name);
|
|
50
|
-
if (easing.isCustomEasing(easing$1)) {
|
|
51
|
-
const custom = easing$1.createAnimation(keyframes$1, () => style.style.get(element, name), valueIsTransform, name, data$1);
|
|
52
|
-
easing$1 = custom.easing;
|
|
53
|
-
if (custom.keyframes)
|
|
54
|
-
keyframes$1 = custom.keyframes;
|
|
55
|
-
if (custom.duration)
|
|
56
|
-
duration = custom.duration;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* If this is a CSS variable we need to register it with the browser
|
|
60
|
-
* before it can be animated natively. We also set it with setProperty
|
|
61
|
-
* rather than directly onto the element.style object.
|
|
62
|
-
*/
|
|
63
|
-
if (cssVar.isCssVar(name)) {
|
|
64
|
-
render = apply.createCssVariableRenderer(element, name);
|
|
65
|
-
if (featureDetection.supports.cssRegisterProperty()) {
|
|
66
|
-
cssVar.registerCssVariable(name);
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
canAnimateNatively = false;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
render = apply.createStyleRenderer(element, name);
|
|
74
|
-
}
|
|
38
|
+
const definition = transforms.transformDefinitions.get(name);
|
|
75
39
|
/**
|
|
76
|
-
* Stop the current animation, if any
|
|
77
|
-
*
|
|
78
|
-
*
|
|
40
|
+
* Stop the current animation, if any. Because this will trigger
|
|
41
|
+
* commitStyles (DOM writes) and we might later trigger DOM reads,
|
|
42
|
+
* this is fired now and we return a factory function to create
|
|
43
|
+
* the actual animation that can get called in batch,
|
|
79
44
|
*/
|
|
80
|
-
|
|
45
|
+
stopAnimation.stopAnimation(data$1.animations[name]);
|
|
81
46
|
/**
|
|
82
|
-
*
|
|
83
|
-
* feature detects CSS.registerProperty but could check WAAPI too.
|
|
47
|
+
* Batchable factory function containing all DOM reads.
|
|
84
48
|
*/
|
|
85
|
-
|
|
49
|
+
return () => {
|
|
50
|
+
const readInitialValue = () => { var _a, _b; return (_b = (_a = style.style.get(element, name)) !== null && _a !== void 0 ? _a : definition === null || definition === void 0 ? void 0 : definition.initialValue) !== null && _b !== void 0 ? _b : 0; };
|
|
86
51
|
/**
|
|
87
|
-
*
|
|
88
|
-
*
|
|
52
|
+
* Replace null values with the previous keyframe value, or read
|
|
53
|
+
* it from the DOM if it's the first keyframe.
|
|
89
54
|
*/
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
55
|
+
let keyframes$1 = keyframes.hydrateKeyframes(keyframes.keyframesList(keyframesDefinition), readInitialValue);
|
|
56
|
+
if (easing.isCustomEasing(easing$1)) {
|
|
57
|
+
const custom = easing$1.createAnimation(keyframes$1, readInitialValue, valueIsTransform, name, data$1);
|
|
58
|
+
easing$1 = custom.easing;
|
|
59
|
+
if (custom.keyframes !== undefined)
|
|
60
|
+
keyframes$1 = custom.keyframes;
|
|
61
|
+
if (custom.duration !== undefined)
|
|
62
|
+
duration = custom.duration;
|
|
95
63
|
}
|
|
96
|
-
const animationOptions = {
|
|
97
|
-
delay: time.ms(delay),
|
|
98
|
-
duration: time.ms(duration),
|
|
99
|
-
endDelay: time.ms(endDelay),
|
|
100
|
-
easing: !easing.isEasingList(easing$1) ? easing.convertEasing(easing$1) : undefined,
|
|
101
|
-
direction,
|
|
102
|
-
iterations: repeat + 1,
|
|
103
|
-
fill: "both",
|
|
104
|
-
};
|
|
105
|
-
animation = element.animate({
|
|
106
|
-
[name]: keyframes$1,
|
|
107
|
-
offset,
|
|
108
|
-
easing: easing.isEasingList(easing$1) ? easing$1.map(easing.convertEasing) : undefined,
|
|
109
|
-
}, animationOptions);
|
|
110
64
|
/**
|
|
111
|
-
*
|
|
65
|
+
* If this is a CSS variable we need to register it with the browser
|
|
66
|
+
* before it can be animated natively. We also set it with setProperty
|
|
67
|
+
* rather than directly onto the element.style object.
|
|
112
68
|
*/
|
|
113
|
-
if (
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
69
|
+
if (cssVar.isCssVar(name)) {
|
|
70
|
+
render = apply.cssVariableRenderer(element, name);
|
|
71
|
+
if (featureDetection.supports.cssRegisterProperty()) {
|
|
72
|
+
cssVar.registerCssVariable(name);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
canAnimateNatively = false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
render = apply.styleRenderer(element, name);
|
|
118
80
|
}
|
|
119
|
-
const target = keyframes$1[keyframes$1.length - 1];
|
|
120
|
-
animation.finished
|
|
121
|
-
.then(() => {
|
|
122
|
-
// Apply styles to target
|
|
123
|
-
render(target);
|
|
124
|
-
// Ensure fill modes don't persist
|
|
125
|
-
animation.cancel();
|
|
126
|
-
})
|
|
127
|
-
.catch(noop.noop);
|
|
128
81
|
/**
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp?rev=281238#L1099
|
|
132
|
-
*
|
|
133
|
-
* This fixes Webkit's timing bugs, like accelerated animations falling
|
|
134
|
-
* out of sync with main thread animations and massive delays in starting
|
|
135
|
-
* accelerated animations in WKWebView.
|
|
82
|
+
* If we can animate this value with WAAPI, do so. Currently this only
|
|
83
|
+
* feature detects CSS.registerProperty but could check WAAPI too.
|
|
136
84
|
*/
|
|
137
|
-
if (
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
85
|
+
if (canAnimateNatively) {
|
|
86
|
+
/**
|
|
87
|
+
* Convert numbers to default value types. Currently this only supports
|
|
88
|
+
* transforms but it could also support other value types.
|
|
89
|
+
*/
|
|
90
|
+
if (definition) {
|
|
91
|
+
keyframes$1 = keyframes$1.map((value) => isNumber.isNumber(value) ? definition.toDefaultUnit(value) : value);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* If this browser doesn't support partial/implicit keyframes we need to
|
|
95
|
+
* explicitly provide one.
|
|
96
|
+
*/
|
|
97
|
+
if (!featureDetection.supports.partialKeyframes() && keyframes$1.length === 1) {
|
|
98
|
+
keyframes$1.unshift(readInitialValue());
|
|
99
|
+
}
|
|
100
|
+
const animationOptions = {
|
|
101
|
+
delay: time.ms(delay),
|
|
102
|
+
duration: time.ms(duration),
|
|
103
|
+
endDelay: time.ms(endDelay),
|
|
104
|
+
easing: !easing.isEasingList(easing$1) ? easing.convertEasing(easing$1) : undefined,
|
|
105
|
+
direction,
|
|
106
|
+
iterations: repeat + 1,
|
|
107
|
+
fill: "both",
|
|
108
|
+
};
|
|
109
|
+
animation = element.animate({
|
|
110
|
+
[name]: keyframes$1,
|
|
111
|
+
offset,
|
|
112
|
+
easing: easing.isEasingList(easing$1) ? easing$1.map(easing.convertEasing) : undefined,
|
|
113
|
+
}, animationOptions);
|
|
114
|
+
/**
|
|
115
|
+
* Polyfill finished Promise in browsers that don't support it
|
|
116
|
+
*/
|
|
117
|
+
if (!animation.finished) {
|
|
118
|
+
animation.finished = new Promise((resolve, reject) => {
|
|
119
|
+
animation.onfinish = resolve;
|
|
120
|
+
animation.oncancel = reject;
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
const target = keyframes$1[keyframes$1.length - 1];
|
|
124
|
+
animation.finished
|
|
125
|
+
.then(() => {
|
|
126
|
+
// Apply styles to target
|
|
127
|
+
render(target);
|
|
128
|
+
// Ensure fill modes don't persist
|
|
129
|
+
animation.cancel();
|
|
130
|
+
})
|
|
131
|
+
.catch(noop.noop);
|
|
132
|
+
/**
|
|
133
|
+
* This forces Webkit to run animations on the main thread by exploiting
|
|
134
|
+
* this condition:
|
|
135
|
+
* https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp?rev=281238#L1099
|
|
136
|
+
*
|
|
137
|
+
* This fixes Webkit's timing bugs, like accelerated animations falling
|
|
138
|
+
* out of sync with main thread animations and massive delays in starting
|
|
139
|
+
* accelerated animations in WKWebView.
|
|
140
|
+
*/
|
|
141
|
+
if (!allowWebkitAcceleration)
|
|
142
|
+
animation.playbackRate = 1.000001;
|
|
143
|
+
/**
|
|
144
|
+
* If we can't animate the value natively then we can fallback to the numbers-only
|
|
145
|
+
* polyfill for transforms. All keyframes must be numerical.
|
|
146
|
+
*/
|
|
147
|
+
}
|
|
148
|
+
else if (valueIsTransform && keyframes$1.every(isNumber.isNumber)) {
|
|
149
|
+
/**
|
|
150
|
+
* If we only have a single keyframe, we need to create an initial keyframe by reading
|
|
151
|
+
* the current value from the DOM.
|
|
152
|
+
*/
|
|
153
|
+
if (keyframes$1.length === 1) {
|
|
154
|
+
keyframes$1.unshift(parseFloat(readInitialValue()));
|
|
155
|
+
}
|
|
156
|
+
if (definition) {
|
|
157
|
+
const applyStyle = render;
|
|
158
|
+
render = (v) => applyStyle(definition.toDefaultUnit(v));
|
|
159
|
+
}
|
|
160
|
+
animation = new NumberAnimation.NumberAnimation(render, keyframes$1, Object.assign(Object.assign({}, options), { duration,
|
|
161
|
+
easing: easing$1 }));
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
const target = keyframes$1[keyframes$1.length - 1];
|
|
165
|
+
render(definition && isNumber.isNumber(target)
|
|
166
|
+
? definition.toDefaultUnit(target)
|
|
167
|
+
: target);
|
|
143
168
|
}
|
|
169
|
+
data$1.animations[name] = animation;
|
|
144
170
|
/**
|
|
145
|
-
*
|
|
146
|
-
* their default value type, so here we loop through and map
|
|
147
|
-
* them to numbers.
|
|
171
|
+
* When an animation finishes, delete the reference to the previous animation.
|
|
148
172
|
*/
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
154
|
-
animation
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
const target = keyframes$1[keyframes$1.length - 1];
|
|
159
|
-
render(definition && typeof target === "number"
|
|
160
|
-
? definition.toDefaultUnit(target)
|
|
161
|
-
: target);
|
|
162
|
-
}
|
|
163
|
-
data$1.activeAnimations[name] = animation;
|
|
164
|
-
/**
|
|
165
|
-
* When an animation finishes, delete the reference to the previous animation.
|
|
166
|
-
*/
|
|
167
|
-
animation === null || animation === void 0 ? void 0 : animation.finished.then(() => clearData(data$1, name)).catch(noop.noop);
|
|
168
|
-
return animation;
|
|
169
|
-
}
|
|
170
|
-
function stopCurrentAnimation(data, name) {
|
|
171
|
-
if (data.activeAnimations[name]) {
|
|
172
|
-
stopAnimation.stopAnimation(data.activeAnimations[name]);
|
|
173
|
-
clearData(data, name);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
function clearData(data, name) {
|
|
177
|
-
data.activeGenerators[name] = data.activeAnimations[name] = undefined;
|
|
173
|
+
animation === null || animation === void 0 ? void 0 : animation.finished.then(() => {
|
|
174
|
+
data$1.animations[name] = undefined;
|
|
175
|
+
data$1.generators[name] = undefined;
|
|
176
|
+
data$1.prevGeneratorState[name] = undefined;
|
|
177
|
+
}).catch(noop.noop);
|
|
178
|
+
return animation;
|
|
179
|
+
};
|
|
178
180
|
}
|
|
179
|
-
const isNumber = (value) => typeof value === "number";
|
|
180
181
|
|
|
181
182
|
exports.animateStyle = animateStyle;
|
|
@@ -2,176 +2,177 @@ import { getAnimationData } from './data.es.js';
|
|
|
2
2
|
import { isCssVar, registerCssVariable } from './utils/css-var.es.js';
|
|
3
3
|
import { noop } from '../../utils/noop.es.js';
|
|
4
4
|
import { ms } from './utils/time.es.js';
|
|
5
|
-
import { isTransform,
|
|
6
|
-
import { stopAnimation } from './utils/stop-animation.es.js';
|
|
5
|
+
import { isTransform, addTransformToElement, transformDefinitions } from './utils/transforms.es.js';
|
|
7
6
|
import { isCustomEasing, isEasingList, convertEasing } from './utils/easing.es.js';
|
|
8
7
|
import { supports } from './utils/feature-detection.es.js';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
8
|
+
import { cssVariableRenderer, styleRenderer } from './utils/apply.es.js';
|
|
9
|
+
import { NumberAnimation } from '../js/NumberAnimation.es.js';
|
|
11
10
|
import { hydrateKeyframes, keyframesList } from './utils/keyframes.es.js';
|
|
12
11
|
import { style } from './style.es.js';
|
|
13
12
|
import { defaults } from './utils/defaults.es.js';
|
|
13
|
+
import { getStyleName } from './utils/get-style-name.es.js';
|
|
14
|
+
import { isNumber } from '../../utils/is-number.es.js';
|
|
15
|
+
import { stopAnimation } from './utils/stop-animation.es.js';
|
|
14
16
|
|
|
15
|
-
function animateStyle(element,
|
|
17
|
+
function animateStyle(element, key, keyframesDefinition, options = {}) {
|
|
16
18
|
let animation;
|
|
17
19
|
let { duration = defaults.duration, delay = defaults.delay, endDelay = defaults.endDelay, repeat = defaults.repeat, easing = defaults.easing, direction, offset, allowWebkitAcceleration = false, } = options;
|
|
18
20
|
const data = getAnimationData(element);
|
|
19
21
|
let canAnimateNatively = supports.waapi();
|
|
20
22
|
let render = noop;
|
|
21
|
-
const valueIsTransform = isTransform(
|
|
23
|
+
const valueIsTransform = isTransform(key);
|
|
22
24
|
/**
|
|
23
25
|
* If this is an individual transform, we need to map its
|
|
24
26
|
* key to a CSS variable and update the element's transform style
|
|
25
27
|
*/
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
name = transformAlias[name];
|
|
29
|
-
addTransformToElement(element, name);
|
|
30
|
-
name = asTransformCssVar(name);
|
|
31
|
-
}
|
|
28
|
+
valueIsTransform && addTransformToElement(element, key);
|
|
29
|
+
const name = getStyleName(key);
|
|
32
30
|
/**
|
|
33
31
|
* Get definition of value, this will be used to convert numerical
|
|
34
32
|
* keyframes into the default value type.
|
|
35
33
|
*/
|
|
36
|
-
const definition =
|
|
37
|
-
/**
|
|
38
|
-
* Replace null values with the previous keyframe value, or read
|
|
39
|
-
* it from the DOM if it's the first keyframe.
|
|
40
|
-
*
|
|
41
|
-
* TODO: This needs to come after the valueIsTransform
|
|
42
|
-
* check so it can correctly read the underlying value.
|
|
43
|
-
* Should make a test for this.
|
|
44
|
-
*/
|
|
45
|
-
let keyframes = hydrateKeyframes(keyframesList(keyframesDefinition), element, name);
|
|
46
|
-
if (isCustomEasing(easing)) {
|
|
47
|
-
const custom = easing.createAnimation(keyframes, () => style.get(element, name), valueIsTransform, name, data);
|
|
48
|
-
easing = custom.easing;
|
|
49
|
-
if (custom.keyframes)
|
|
50
|
-
keyframes = custom.keyframes;
|
|
51
|
-
if (custom.duration)
|
|
52
|
-
duration = custom.duration;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* If this is a CSS variable we need to register it with the browser
|
|
56
|
-
* before it can be animated natively. We also set it with setProperty
|
|
57
|
-
* rather than directly onto the element.style object.
|
|
58
|
-
*/
|
|
59
|
-
if (isCssVar(name)) {
|
|
60
|
-
render = createCssVariableRenderer(element, name);
|
|
61
|
-
if (supports.cssRegisterProperty()) {
|
|
62
|
-
registerCssVariable(name);
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
canAnimateNatively = false;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
render = createStyleRenderer(element, name);
|
|
70
|
-
}
|
|
34
|
+
const definition = transformDefinitions.get(name);
|
|
71
35
|
/**
|
|
72
|
-
* Stop the current animation, if any
|
|
73
|
-
*
|
|
74
|
-
*
|
|
36
|
+
* Stop the current animation, if any. Because this will trigger
|
|
37
|
+
* commitStyles (DOM writes) and we might later trigger DOM reads,
|
|
38
|
+
* this is fired now and we return a factory function to create
|
|
39
|
+
* the actual animation that can get called in batch,
|
|
75
40
|
*/
|
|
76
|
-
|
|
41
|
+
stopAnimation(data.animations[name]);
|
|
77
42
|
/**
|
|
78
|
-
*
|
|
79
|
-
* feature detects CSS.registerProperty but could check WAAPI too.
|
|
43
|
+
* Batchable factory function containing all DOM reads.
|
|
80
44
|
*/
|
|
81
|
-
|
|
45
|
+
return () => {
|
|
46
|
+
const readInitialValue = () => { var _a, _b; return (_b = (_a = style.get(element, name)) !== null && _a !== void 0 ? _a : definition === null || definition === void 0 ? void 0 : definition.initialValue) !== null && _b !== void 0 ? _b : 0; };
|
|
82
47
|
/**
|
|
83
|
-
*
|
|
84
|
-
*
|
|
48
|
+
* Replace null values with the previous keyframe value, or read
|
|
49
|
+
* it from the DOM if it's the first keyframe.
|
|
85
50
|
*/
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
51
|
+
let keyframes = hydrateKeyframes(keyframesList(keyframesDefinition), readInitialValue);
|
|
52
|
+
if (isCustomEasing(easing)) {
|
|
53
|
+
const custom = easing.createAnimation(keyframes, readInitialValue, valueIsTransform, name, data);
|
|
54
|
+
easing = custom.easing;
|
|
55
|
+
if (custom.keyframes !== undefined)
|
|
56
|
+
keyframes = custom.keyframes;
|
|
57
|
+
if (custom.duration !== undefined)
|
|
58
|
+
duration = custom.duration;
|
|
91
59
|
}
|
|
92
|
-
const animationOptions = {
|
|
93
|
-
delay: ms(delay),
|
|
94
|
-
duration: ms(duration),
|
|
95
|
-
endDelay: ms(endDelay),
|
|
96
|
-
easing: !isEasingList(easing) ? convertEasing(easing) : undefined,
|
|
97
|
-
direction,
|
|
98
|
-
iterations: repeat + 1,
|
|
99
|
-
fill: "both",
|
|
100
|
-
};
|
|
101
|
-
animation = element.animate({
|
|
102
|
-
[name]: keyframes,
|
|
103
|
-
offset,
|
|
104
|
-
easing: isEasingList(easing) ? easing.map(convertEasing) : undefined,
|
|
105
|
-
}, animationOptions);
|
|
106
60
|
/**
|
|
107
|
-
*
|
|
61
|
+
* If this is a CSS variable we need to register it with the browser
|
|
62
|
+
* before it can be animated natively. We also set it with setProperty
|
|
63
|
+
* rather than directly onto the element.style object.
|
|
108
64
|
*/
|
|
109
|
-
if (
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
65
|
+
if (isCssVar(name)) {
|
|
66
|
+
render = cssVariableRenderer(element, name);
|
|
67
|
+
if (supports.cssRegisterProperty()) {
|
|
68
|
+
registerCssVariable(name);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
canAnimateNatively = false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
render = styleRenderer(element, name);
|
|
114
76
|
}
|
|
115
|
-
const target = keyframes[keyframes.length - 1];
|
|
116
|
-
animation.finished
|
|
117
|
-
.then(() => {
|
|
118
|
-
// Apply styles to target
|
|
119
|
-
render(target);
|
|
120
|
-
// Ensure fill modes don't persist
|
|
121
|
-
animation.cancel();
|
|
122
|
-
})
|
|
123
|
-
.catch(noop);
|
|
124
77
|
/**
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
* https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp?rev=281238#L1099
|
|
128
|
-
*
|
|
129
|
-
* This fixes Webkit's timing bugs, like accelerated animations falling
|
|
130
|
-
* out of sync with main thread animations and massive delays in starting
|
|
131
|
-
* accelerated animations in WKWebView.
|
|
78
|
+
* If we can animate this value with WAAPI, do so. Currently this only
|
|
79
|
+
* feature detects CSS.registerProperty but could check WAAPI too.
|
|
132
80
|
*/
|
|
133
|
-
if (
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
81
|
+
if (canAnimateNatively) {
|
|
82
|
+
/**
|
|
83
|
+
* Convert numbers to default value types. Currently this only supports
|
|
84
|
+
* transforms but it could also support other value types.
|
|
85
|
+
*/
|
|
86
|
+
if (definition) {
|
|
87
|
+
keyframes = keyframes.map((value) => isNumber(value) ? definition.toDefaultUnit(value) : value);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* If this browser doesn't support partial/implicit keyframes we need to
|
|
91
|
+
* explicitly provide one.
|
|
92
|
+
*/
|
|
93
|
+
if (!supports.partialKeyframes() && keyframes.length === 1) {
|
|
94
|
+
keyframes.unshift(readInitialValue());
|
|
95
|
+
}
|
|
96
|
+
const animationOptions = {
|
|
97
|
+
delay: ms(delay),
|
|
98
|
+
duration: ms(duration),
|
|
99
|
+
endDelay: ms(endDelay),
|
|
100
|
+
easing: !isEasingList(easing) ? convertEasing(easing) : undefined,
|
|
101
|
+
direction,
|
|
102
|
+
iterations: repeat + 1,
|
|
103
|
+
fill: "both",
|
|
104
|
+
};
|
|
105
|
+
animation = element.animate({
|
|
106
|
+
[name]: keyframes,
|
|
107
|
+
offset,
|
|
108
|
+
easing: isEasingList(easing) ? easing.map(convertEasing) : undefined,
|
|
109
|
+
}, animationOptions);
|
|
110
|
+
/**
|
|
111
|
+
* Polyfill finished Promise in browsers that don't support it
|
|
112
|
+
*/
|
|
113
|
+
if (!animation.finished) {
|
|
114
|
+
animation.finished = new Promise((resolve, reject) => {
|
|
115
|
+
animation.onfinish = resolve;
|
|
116
|
+
animation.oncancel = reject;
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
const target = keyframes[keyframes.length - 1];
|
|
120
|
+
animation.finished
|
|
121
|
+
.then(() => {
|
|
122
|
+
// Apply styles to target
|
|
123
|
+
render(target);
|
|
124
|
+
// Ensure fill modes don't persist
|
|
125
|
+
animation.cancel();
|
|
126
|
+
})
|
|
127
|
+
.catch(noop);
|
|
128
|
+
/**
|
|
129
|
+
* This forces Webkit to run animations on the main thread by exploiting
|
|
130
|
+
* this condition:
|
|
131
|
+
* https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp?rev=281238#L1099
|
|
132
|
+
*
|
|
133
|
+
* This fixes Webkit's timing bugs, like accelerated animations falling
|
|
134
|
+
* out of sync with main thread animations and massive delays in starting
|
|
135
|
+
* accelerated animations in WKWebView.
|
|
136
|
+
*/
|
|
137
|
+
if (!allowWebkitAcceleration)
|
|
138
|
+
animation.playbackRate = 1.000001;
|
|
139
|
+
/**
|
|
140
|
+
* If we can't animate the value natively then we can fallback to the numbers-only
|
|
141
|
+
* polyfill for transforms. All keyframes must be numerical.
|
|
142
|
+
*/
|
|
143
|
+
}
|
|
144
|
+
else if (valueIsTransform && keyframes.every(isNumber)) {
|
|
145
|
+
/**
|
|
146
|
+
* If we only have a single keyframe, we need to create an initial keyframe by reading
|
|
147
|
+
* the current value from the DOM.
|
|
148
|
+
*/
|
|
149
|
+
if (keyframes.length === 1) {
|
|
150
|
+
keyframes.unshift(parseFloat(readInitialValue()));
|
|
151
|
+
}
|
|
152
|
+
if (definition) {
|
|
153
|
+
const applyStyle = render;
|
|
154
|
+
render = (v) => applyStyle(definition.toDefaultUnit(v));
|
|
155
|
+
}
|
|
156
|
+
animation = new NumberAnimation(render, keyframes, Object.assign(Object.assign({}, options), { duration,
|
|
157
|
+
easing }));
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
const target = keyframes[keyframes.length - 1];
|
|
161
|
+
render(definition && isNumber(target)
|
|
162
|
+
? definition.toDefaultUnit(target)
|
|
163
|
+
: target);
|
|
139
164
|
}
|
|
165
|
+
data.animations[name] = animation;
|
|
140
166
|
/**
|
|
141
|
-
*
|
|
142
|
-
* their default value type, so here we loop through and map
|
|
143
|
-
* them to numbers.
|
|
167
|
+
* When an animation finishes, delete the reference to the previous animation.
|
|
144
168
|
*/
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
animation
|
|
151
|
-
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
const target = keyframes[keyframes.length - 1];
|
|
155
|
-
render(definition && typeof target === "number"
|
|
156
|
-
? definition.toDefaultUnit(target)
|
|
157
|
-
: target);
|
|
158
|
-
}
|
|
159
|
-
data.activeAnimations[name] = animation;
|
|
160
|
-
/**
|
|
161
|
-
* When an animation finishes, delete the reference to the previous animation.
|
|
162
|
-
*/
|
|
163
|
-
animation === null || animation === void 0 ? void 0 : animation.finished.then(() => clearData(data, name)).catch(noop);
|
|
164
|
-
return animation;
|
|
165
|
-
}
|
|
166
|
-
function stopCurrentAnimation(data, name) {
|
|
167
|
-
if (data.activeAnimations[name]) {
|
|
168
|
-
stopAnimation(data.activeAnimations[name]);
|
|
169
|
-
clearData(data, name);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
function clearData(data, name) {
|
|
173
|
-
data.activeGenerators[name] = data.activeAnimations[name] = undefined;
|
|
169
|
+
animation === null || animation === void 0 ? void 0 : animation.finished.then(() => {
|
|
170
|
+
data.animations[name] = undefined;
|
|
171
|
+
data.generators[name] = undefined;
|
|
172
|
+
data.prevGeneratorState[name] = undefined;
|
|
173
|
+
}).catch(noop);
|
|
174
|
+
return animation;
|
|
175
|
+
};
|
|
174
176
|
}
|
|
175
|
-
const isNumber = (value) => typeof value === "number";
|
|
176
177
|
|
|
177
178
|
export { animateStyle };
|
|
@@ -12,19 +12,30 @@ var defaults = require('./utils/defaults.cjs.js');
|
|
|
12
12
|
function animate(elements, keyframes, options$1 = {}) {
|
|
13
13
|
var _a;
|
|
14
14
|
elements = resolveElements.resolveElements(elements);
|
|
15
|
-
const animations = [];
|
|
16
15
|
const numElements = elements.length;
|
|
16
|
+
/**
|
|
17
|
+
* Create and start new animations
|
|
18
|
+
*/
|
|
19
|
+
const animationFactories = [];
|
|
17
20
|
for (let i = 0; i < numElements; i++) {
|
|
18
21
|
const element = elements[i];
|
|
19
22
|
for (const key in keyframes) {
|
|
20
23
|
const valueOptions = options.getOptions(options$1, key);
|
|
21
24
|
valueOptions.delay = stagger.resolveOption(valueOptions.delay, i, numElements);
|
|
22
25
|
const animation = animateStyle.animateStyle(element, key, keyframes[key], valueOptions);
|
|
23
|
-
|
|
26
|
+
animationFactories.push(animation);
|
|
24
27
|
}
|
|
25
28
|
}
|
|
26
|
-
return controls.
|
|
27
|
-
|
|
29
|
+
return controls.createAnimations(animationFactories,
|
|
30
|
+
/**
|
|
31
|
+
* TODO:
|
|
32
|
+
* If easing is set to spring or glide, duration will be dynamically
|
|
33
|
+
* generated. Ideally we would dynamically generate this from
|
|
34
|
+
* animation.effect.getComputedTiming().duration but this isn't
|
|
35
|
+
* supported in iOS13 or our number polyfill. Perhaps it's possible
|
|
36
|
+
* to Proxy animations returned from animateStyle that has duration
|
|
37
|
+
* as a getter.
|
|
38
|
+
*/
|
|
28
39
|
(_a = options$1.duration) !== null && _a !== void 0 ? _a : defaults.defaults.duration);
|
|
29
40
|
}
|
|
30
41
|
|