This is an automated email from the ASF dual-hosted git repository.
shenyi pushed a commit to branch graphic-animation
in repository https://gitbox.apache.org/repos/asf/echarts.git
The following commit(s) were added to refs/heads/graphic-animation by this push:
new 48ba921 feat(animation): restore props after keyframe animation is
stopped
48ba921 is described below
commit 48ba9213aeddb10c85b66a101d42ebd3c27cdf6f
Author: pissang <[email protected]>
AuthorDate: Wed Dec 1 12:27:13 2021 +0800
feat(animation): restore props after keyframe animation is stopped
---
src/animation/customGraphicKeyframeAnimation.ts | 40 +++++++++++++++++++------
src/component/graphic/GraphicView.ts | 8 ++++-
test/graphic-animation-wave.html | 8 -----
test/graphic-animation.html | 4 +--
4 files changed, 40 insertions(+), 20 deletions(-)
diff --git a/src/animation/customGraphicKeyframeAnimation.ts
b/src/animation/customGraphicKeyframeAnimation.ts
index 3116a33..20c9d7e 100644
--- a/src/animation/customGraphicKeyframeAnimation.ts
+++ b/src/animation/customGraphicKeyframeAnimation.ts
@@ -21,10 +21,11 @@ import { AnimationEasing } from
'zrender/src/animation/easing';
import Element from 'zrender/src/Element';
import { keys, filter, each } from 'zrender/src/core/util';
import { ELEMENT_ANIMATABLE_PROPS } from './customGraphicTransition';
-import { AnimationOption, AnimationOptionMixin } from '../util/types';
+import { AnimationOption, AnimationOptionMixin, Dictionary } from
'../util/types';
import { Model } from '../echarts.all';
import { getAnimationConfig } from './basicTrasition';
import { warn } from '../util/log';
+import { makeInner } from '../util/model';
// Helpers for creating keyframe based animations in custom series and graphic
components.
@@ -33,12 +34,26 @@ type AnimationKeyframe<T extends Record<string, any>> = T &
{
percent?: number // 0 - 1
};
+type StateToRestore = Dictionary<any>;
+const getStateToRestore = makeInner<StateToRestore, Element>();
+
export interface ElementKeyframeAnimationOption<Props extends Record<string,
any>> extends AnimationOption {
// Animation configuration for keyframe based animation.
loop?: boolean
keyframes?: AnimationKeyframe<Props>[]
}
+/**
+ * Stopped previous keyframe animation and restore the attributes.
+ * Avoid new keyframe animation starts with wrong internal state when the
percent: 0 is not set.
+ */
+export function stopPreviousKeyframeAnimationAndRestore(el: Element) {
+ // Stop previous keyframe animation.
+ el.stopAnimation('keyframe');
+ // Restore
+ el.attr(getStateToRestore(el));
+}
+
export function applyKeyframeAnimation<T extends Record<string, any>>(
el: Element,
animationOpts: ElementKeyframeAnimationOption<T>,
@@ -48,9 +63,6 @@ export function applyKeyframeAnimation<T extends
Record<string, any>>(
return;
}
- // Stop previous keyframe animation.
- el.stopAnimation('keyframe');
-
const keyframes = animationOpts.keyframes;
let duration = animationOpts.duration;
@@ -63,8 +75,10 @@ export function applyKeyframeAnimation<T extends
Record<string, any>>(
return;
}
- function applyKeyframeAnimationOnProp(propName: typeof
ELEMENT_ANIMATABLE_PROPS[number]) {
- if (propName && !(el as any)[propName]) {
+ const stateToRestore: StateToRestore = getStateToRestore(el);
+
+ function applyKeyframeAnimationOnProp(targetPropName: typeof
ELEMENT_ANIMATABLE_PROPS[number]) {
+ if (targetPropName && !(el as any)[targetPropName]) {
return;
}
@@ -73,13 +87,13 @@ export function applyKeyframeAnimation<T extends
Record<string, any>>(
each(keyframes, kf => {
// Stop current animation.
const animators = el.animators;
- const kfValues = propName ? kf[propName] : kf;
+ const kfValues = targetPropName ? kf[targetPropName] : kf;
if (!kfValues) {
return;
}
let propKeys = keys(kfValues);
- if (!propName) {
+ if (!targetPropName) {
// PENDING performance?
propKeys = filter(
propKeys, key => key !== 'percent' && key !== 'easing'
@@ -97,7 +111,7 @@ export function applyKeyframeAnimation<T extends
Record<string, any>>(
}
if (!animator) {
- animator = el.animate(propName, animationOpts.loop);
+ animator = el.animate(targetPropName, animationOpts.loop);
animator.scope = 'keyframe';
}
for (let i = 0; i < animators.length; i++) {
@@ -107,6 +121,14 @@ export function applyKeyframeAnimation<T extends
Record<string, any>>(
}
}
+ targetPropName && (stateToRestore[targetPropName] =
stateToRestore[targetPropName] || {});
+
+ const savedTarget = targetPropName ?
stateToRestore[targetPropName] : stateToRestore;
+ each(propKeys, key => {
+ // Save original value.
+ savedTarget[key] = ((targetPropName ? (el as
any)[targetPropName] : el) || {})[key];
+ });
+
animator.whenWithKeys(duration * kf.percent, kfValues, propKeys,
kf.easing);
});
if (!animator) {
diff --git a/src/component/graphic/GraphicView.ts
b/src/component/graphic/GraphicView.ts
index 4ca8b95..f790db8 100644
--- a/src/component/graphic/GraphicView.ts
+++ b/src/component/graphic/GraphicView.ts
@@ -45,7 +45,10 @@ import {
updateLeaveTo
} from '../../animation/customGraphicTransition';
import { updateProps } from '../../animation/basicTrasition';
-import { applyKeyframeAnimation } from
'../../animation/customGraphicKeyframeAnimation';
+import {
+ applyKeyframeAnimation,
+ stopPreviousKeyframeAnimationAndRestore
+} from '../../animation/customGraphicKeyframeAnimation';
const nonShapeGraphicElements = {
// Reserved but not supported in graphic component.
@@ -154,6 +157,7 @@ export class GraphicComponentView extends ComponentView {
// Remove unnecessary props to avoid potential problems.
const elOptionCleaned = getCleanedElOption(elOption);
+
// For simple, do not support parent change, otherwise reorder is
needed.
if (__DEV__) {
elExisting && zrUtil.assert(
@@ -171,6 +175,8 @@ export class GraphicComponentView extends ComponentView {
}
else {
el && (inner(el).isNew = false);
+ // Stop and restore before update any other attributes.
+ stopPreviousKeyframeAnimationAndRestore(el);
}
if (el) {
applyUpdateTransition(
diff --git a/test/graphic-animation-wave.html b/test/graphic-animation-wave.html
index c2477a1..44a4864 100644
--- a/test/graphic-animation-wave.html
+++ b/test/graphic-animation-wave.html
@@ -101,14 +101,6 @@ under the License.
loop: true,
delay: (rand - 1) * 4000,
keyframes: [{
- percent: 0.,
- easing: 'sinusoidalInOut',
- style: {
- fill: config.color1
- },
- scaleX: 1,
- scaleY: 1
- }, {
percent: 0.5,
easing: 'sinusoidalInOut',
style: {
diff --git a/test/graphic-animation.html b/test/graphic-animation.html
index 2cb5ec6..4ebf2db 100644
--- a/test/graphic-animation.html
+++ b/test/graphic-animation.html
@@ -44,7 +44,7 @@ under the License.
-<!--
+
<script>
require(['echarts'/*, 'map/js/china' */], function (echarts) {
var option = {
@@ -89,7 +89,7 @@ under the License.
});
});
- </script> -->
+ </script>
<script>
require(['echarts'/*, 'map/js/china' */], function (echarts) {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]