|  | /* | 
|  | * 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. | 
|  | */ | 
|  |  | 
|  |  | 
|  | import Element, { ElementProps } from 'zrender/src/Element'; | 
|  | import { ZREasing } from './types'; | 
|  | import { AnimationEasing } from 'zrender/src/animation/easing'; | 
|  |  | 
|  | interface AnimationWrapStorage { | 
|  | el: Element; | 
|  | target: ElementProps; | 
|  | duration: number; | 
|  | delay: number; | 
|  | easing: AnimationEasing | 
|  | } | 
|  | type AnimationWrapDoneCallback = () => void; | 
|  |  | 
|  | /** | 
|  | * Animate multiple elements with a single done-callback. | 
|  | * | 
|  | * @example | 
|  | *  animation | 
|  | *      .createWrap() | 
|  | *      .add(el1, {x: 10, y: 10}) | 
|  | *      .add(el2, {shape: {width: 500}, style: {fill: 'red'}}, 400) | 
|  | *      .done(function () { // done }) | 
|  | *      .start('cubicOut'); | 
|  | */ | 
|  | class AnimationWrap { | 
|  |  | 
|  | private _storage = [] as AnimationWrapStorage[]; | 
|  | private _elExistsMap: { [elId: string]: boolean } = {}; | 
|  | private _finishedCallback: AnimationWrapDoneCallback; | 
|  |  | 
|  | /** | 
|  | * Caution: a el can only be added once, otherwise 'done' | 
|  | * might not be called. This method checks this (by el.id), | 
|  | * suppresses adding and returns false when existing el found. | 
|  | * | 
|  | * @return Whether adding succeeded. | 
|  | */ | 
|  | add( | 
|  | el: Element, | 
|  | target: ElementProps, | 
|  | duration?: number, | 
|  | delay?: number, | 
|  | easing?: ZREasing | 
|  | ): boolean { | 
|  | if (this._elExistsMap[el.id]) { | 
|  | return false; | 
|  | } | 
|  | this._elExistsMap[el.id] = true; | 
|  |  | 
|  | this._storage.push({ | 
|  | el: el, | 
|  | target: target, | 
|  | duration: duration, | 
|  | delay: delay, | 
|  | easing: easing | 
|  | }); | 
|  |  | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Only execute when animation done/aborted. | 
|  | */ | 
|  | finished(callback: AnimationWrapDoneCallback): AnimationWrap { | 
|  | this._finishedCallback = callback; | 
|  | return this; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Will stop exist animation firstly. | 
|  | */ | 
|  | start(): AnimationWrap { | 
|  | let count = this._storage.length; | 
|  |  | 
|  | const checkTerminate = () => { | 
|  | count--; | 
|  | if (count <= 0) { // Guard. | 
|  | this._storage.length = 0; | 
|  | this._elExistsMap = {}; | 
|  | this._finishedCallback && this._finishedCallback(); | 
|  | } | 
|  | }; | 
|  |  | 
|  | for (let i = 0, len = this._storage.length; i < len; i++) { | 
|  | const item = this._storage[i]; | 
|  | item.el.animateTo(item.target, { | 
|  | duration: item.duration, | 
|  | delay: item.delay, | 
|  | easing: item.easing, | 
|  | setToFinal: true, | 
|  | done: checkTerminate, | 
|  | aborted: checkTerminate | 
|  | }); | 
|  | } | 
|  |  | 
|  | return this; | 
|  | } | 
|  | } | 
|  |  | 
|  | export function createWrap(): AnimationWrap { | 
|  | return new AnimationWrap(); | 
|  | } |