You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by sh...@apache.org on 2021/11/25 11:05:56 UTC

[echarts] branch graphic-animation updated: feat(animation): fix some animation abort bug

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 b5b2185  feat(animation): fix some animation abort bug
b5b2185 is described below

commit b5b21856944d2b19c75872267b0509d305da7c31
Author: pissang <bm...@gmail.com>
AuthorDate: Thu Nov 25 19:01:50 2021 +0800

    feat(animation): fix some animation abort bug
---
 src/animation/customGraphicKeyframeAnimation.ts |  27 ++--
 src/chart/custom/CustomView.ts                  |   4 +-
 src/component/graphic/GraphicView.ts            |   7 +-
 test/graphic-animation-wave.html                | 186 ++++++++++++++++++++++++
 test/graphic-animation.html                     |  56 -------
 5 files changed, 206 insertions(+), 74 deletions(-)

diff --git a/src/animation/customGraphicKeyframeAnimation.ts b/src/animation/customGraphicKeyframeAnimation.ts
index af1a980..a483090 100644
--- a/src/animation/customGraphicKeyframeAnimation.ts
+++ b/src/animation/customGraphicKeyframeAnimation.ts
@@ -42,9 +42,8 @@ export interface ElementKeyframeAnimationOption<Props extends Record<string, any
 export function applyKeyframeAnimation<T extends Record<string, any>>(
     el: Element, animationOpts: ElementKeyframeAnimationOption<T>, animatableModel: Model<AnimationOptionMixin>
 ) {
-    if (!animationOpts) {
-        return;
-    }
+    // Stop previous keyframe animation.
+    el.stopAnimation('keyframe');
 
     const keyframes = animationOpts.keyframes;
     let duration = animationOpts.duration;
@@ -63,9 +62,8 @@ export function applyKeyframeAnimation<T extends Record<string, any>>(
             return;
         }
 
-        const animator = el.animate(propName, animationOpts.loop);
+        let animator: ReturnType<Element['animate']>;
         let endFrameIsSet = false;
-        let hasAnimation = false;
         each(keyframes, kf => {
             // Stop current animation.
             const animators = el.animators;
@@ -85,11 +83,6 @@ export function applyKeyframeAnimation<T extends Record<string, any>>(
             if (!propKeys.length) {
                 return;
             }
-            for (let i = 0; i < animators.length; i++) {
-                if (animators[i] !== animator) {
-                    animators[i].stopTracks(propKeys);
-                }
-            }
 
             if (__DEV__) {
                 if (kf.percent >= 1) {
@@ -97,10 +90,20 @@ export function applyKeyframeAnimation<T extends Record<string, any>>(
                 }
             }
 
-            hasAnimation = true;
+            if (!animator) {
+                animator = el.animate(propName, animationOpts.loop);
+                animator.scope = 'keyframe';
+            }
+            for (let i = 0; i < animators.length; i++) {
+                // Stop all other animation that is not keyframe.
+                if (animators[i] !== animator && animators[i].targetName === animator.targetName) {
+                    animators[i].stopTracks(propKeys);
+                }
+            }
+
             animator.whenWithKeys(duration * kf.percent, kfValues, propKeys, kf.easing);
         });
-        if (!hasAnimation) {
+        if (!animator) {
             return;
         }
 
diff --git a/src/chart/custom/CustomView.ts b/src/chart/custom/CustomView.ts
index e98b11c..abfc4fa 100644
--- a/src/chart/custom/CustomView.ts
+++ b/src/chart/custom/CustomView.ts
@@ -86,10 +86,10 @@ import CustomSeriesModel, {
     customInnerStore,
     PrepareCustomInfo,
     CustomPathOption,
-    CustomRootElementOption
+    CustomRootElementOption,
+    CustomSeriesOption
 } from './CustomSeries';
 import { PatternObject } from 'zrender/src/graphic/Pattern';
-import { CustomSeriesOption } from '../../export/option';
 import {
     applyLeaveTransition,
     applyUpdateTransition,
diff --git a/src/component/graphic/GraphicView.ts b/src/component/graphic/GraphicView.ts
index 0507498..a308b8c 100644
--- a/src/component/graphic/GraphicView.ts
+++ b/src/component/graphic/GraphicView.ts
@@ -46,7 +46,6 @@ import {
 } from '../../animation/customGraphicTransition';
 import { updateProps } from '../../animation/basicTrasition';
 import { applyKeyframeAnimation } from '../../animation/customGraphicKeyframeAnimation';
-import { graphic } from '../../echarts.all';
 
 const nonShapeGraphicElements = {
     // Reserved but not supported in graphic component.
@@ -217,6 +216,8 @@ export class GraphicComponentView extends ComponentView {
 
             if (el) {
                 const elInner = inner(el);
+                const keyframeAnimation = elOption.keyframeAnimation;
+
                 elInner.option = elOption;
                 setEventData(el, graphicModel, elOption);
 
@@ -227,7 +228,7 @@ export class GraphicComponentView extends ComponentView {
                     itemTooltipOption: elOption.tooltip
                 });
 
-                applyKeyframeAnimation(el, elOption.keyframeAnimation, graphicModel);
+                keyframeAnimation && applyKeyframeAnimation(el, keyframeAnimation, graphicModel);
             }
         });
     }
@@ -290,8 +291,6 @@ export class GraphicComponentView extends ComponentView {
                     height: parentElInner.height
                 };
 
-
-
             // PENDING
             // Currently, when `bounding: 'all'`, the union bounding rect of the group
             // does not include the rect of [0, 0, group.width, group.height], which
diff --git a/test/graphic-animation-wave.html b/test/graphic-animation-wave.html
new file mode 100644
index 0000000..c2477a1
--- /dev/null
+++ b/test/graphic-animation-wave.html
@@ -0,0 +1,186 @@
+<!DOCTYPE html>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+
+
+<html>
+    <head>
+        <meta charset="utf-8">
+        <meta name="viewport" content="width=device-width, initial-scale=1" />
+        <script src="lib/simpleRequire.js"></script>
+        <script src="lib/config.js"></script>
+        <script src="lib/jquery.min.js"></script>
+        <script src="lib/facePrint.js"></script>
+        <script src="lib/testHelper.js"></script>
+        <script src="lib/perlin.js"></script>
+        <script src="lib/dat.gui.min.js"></script>
+        <!-- <script src="ut/lib/canteen.js"></script> -->
+        <link rel="stylesheet" href="lib/reset.css" />
+    </head>
+    <body>
+        <style>
+            body, #main {
+                margin: 0;
+                width: 100%;
+                height: 100%;
+            }
+            img {
+                position: absolute;
+                left: 0;
+                top: 0;
+            }
+        </style>
+
+
+        <div id="main"></div>
+
+        <script>
+            require(['echarts'/*, 'map/js/china' */], function (echarts) {
+                // During transition
+                var chart = echarts.init(document.getElementById('main'), null, {
+                    width: window.innerWidth,
+                    height: window.innerHeight,
+                    // renderer: 'svg',
+                    // ssr: true
+                })
+
+                const width = chart.getWidth();
+                const height = chart.getHeight();
+
+                const config = {
+                    minSize: 3,
+                    maxSize: 30,
+
+                    color0: '#ffa500',
+                    color1: '#800080',
+
+                    backgroundColor: '#8e2ed2',
+
+                    duration: 4000,
+
+                    frequency: 500,
+                    offsetX: 0,
+                    offsetY: 100
+                }
+
+                function createElements() {
+                    const elements = [];
+                    for (let x = 20; x < width; x += 40) {
+                        for (let y = 20; y < height; y += 40) {
+                            const rand = noise.perlin2(
+                                x / config.frequency + config.offsetX,
+                                y / config.frequency + config.offsetY
+                            );
+                            elements.push({
+                                type: 'circle',
+                                x, y,
+                                style: {
+                                    fill: config.color1
+                                },
+                                shape: {
+                                    r: config.maxSize
+                                },
+                                keyframeAnimation: {
+                                    duration: config.duration,
+                                    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: {
+                                            fill: config.color0
+                                        },
+                                        scaleX: config.minSize / config.maxSize,
+                                        scaleY: config.minSize / config.maxSize
+                                    }, {
+                                        percent: 1,
+                                        easing: 'sinusoidalInOut',
+                                        style: {
+                                            fill: config.color1
+                                        },
+                                        scaleX: 1,
+                                        scaleY: 1
+                                    }]
+                                }
+                            });
+                        }
+                    }
+                    return elements;
+                }
+
+                function update() {
+                    chart.setOption({
+                        // backgroundColor: {
+                        //     type: 'linear',
+                        //     x: 0,
+                        //     y: 0,
+                        //     x2: 1,
+                        //     y2: 0,
+                        //     colorStops: [{
+                        //         offset: 0,
+                        //         color: '#8e2de2'
+                        //     }, {
+                        //         offset: 1,
+                        //         color: '#4a00e0'
+                        //     }]
+                        // },
+                        backgroundColor: config.backgroundColor,
+                        graphic: {
+                            elements: createElements()
+                        }
+                    })
+                }
+
+                update();
+
+
+                var gui = new dat.GUI();
+
+                gui.add(config, 'frequency', 10, 1000).onChange(update);
+                gui.add(config, 'offsetX', 0, 1000).onChange(update);
+                gui.add(config, 'offsetY', 0, 1000).onChange(update);
+
+                gui.add(config, 'minSize', 0, 100).onChange(update);
+                gui.add(config, 'maxSize', 0, 100).onChange(update);
+                gui.add(config, 'duration', 100, 100000).onChange(update);
+
+                gui.addColor(config, 'backgroundColor').onChange(update);
+                gui.addColor(config, 'color0').onChange(update);
+                gui.addColor(config, 'color1').onChange(update);
+
+                // console.log(chart.renderToSVGString());
+                // var blob = new Blob([chart.renderToSVGString()], { type: 'image/svg+xml' });
+                // var a = document.createElement('a');
+                // a.download = 'aaa.svg';
+                // a.href = URL.createObjectURL(blob);
+                // a.style.display = "none";
+                // a.click();
+            });
+        </script>
+    </body>
+</html>
+
diff --git a/test/graphic-animation.html b/test/graphic-animation.html
index 2abc3c7..56856d6 100644
--- a/test/graphic-animation.html
+++ b/test/graphic-animation.html
@@ -90,62 +90,6 @@ under the License.
 
         });
         </script>
-
-
-        <script>
-            require(['echarts'/*, 'map/js/china' */], function (echarts) {
-                // During transition
-                var chart = testHelper.create(echarts, 'main1', {
-                    title: [
-                        'Enter / Leave transition'
-                    ]
-                });
-
-                const width = chart.getWidth();
-                const height = chart.getHeight();
-
-                const elements = [];
-                for (let x = 20; x < width; x += 40) {
-                    for (let y = 20; y < height; y += 40) {
-                        const rand = noise.perlin2(x / 200, y / 200 + 10);
-                        elements.push({
-                            type: 'circle',
-                            x: x,
-                            y: y,
-                            keyframeAnimation: {
-                                duration: 2000,
-                                loop: true,
-                                delay: (rand - 1) * 2000,
-                                keyframes: [{
-                                    percent: 0.5,
-                                    easing: 'sinusoidalInOut',
-                                    shape: {
-                                        r: 1
-                                    }
-                                }, {
-                                    percent: 1,
-                                    easing: 'sinusoidalInOut',
-                                    shape: {
-                                        r: 20
-                                    }
-                                }]
-                            },
-                            shape: {
-                                cx: 0,
-                                cy: 0,
-                                r: 20
-                            }
-                        });
-                    }
-                }
-
-                chart.setOption({
-                    graphic: {
-                        elements
-                    }
-                })
-            });
-        </script>
     </body>
 </html>
 

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org