|   | 
| /* | 
| * 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. | 
| */ | 
|   | 
|   | 
| /** | 
|  * AUTO-GENERATED FILE. DO NOT MODIFY. | 
|  */ | 
|   | 
| /* | 
| * 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 { makeInner, normalizeToArray } from '../util/model.js'; | 
| import { assert, bind, each, eqNaN, extend, hasOwn, indexOf, isArrayLike, keys, reduce } from 'zrender/lib/core/util.js'; | 
| import { cloneValue } from 'zrender/lib/animation/Animator.js'; | 
| import Displayable from 'zrender/lib/graphic/Displayable.js'; | 
| import { getAnimationConfig } from './basicTransition.js'; | 
| import { Path } from '../util/graphic.js'; | 
| import { warn } from '../util/log.js'; | 
| import { TRANSFORMABLE_PROPS } from 'zrender/lib/core/Transformable.js'; | 
| var LEGACY_TRANSFORM_PROPS_MAP = { | 
|   position: ['x', 'y'], | 
|   scale: ['scaleX', 'scaleY'], | 
|   origin: ['originX', 'originY'] | 
| }; | 
| var LEGACY_TRANSFORM_PROPS = keys(LEGACY_TRANSFORM_PROPS_MAP); | 
| var TRANSFORM_PROPS_MAP = reduce(TRANSFORMABLE_PROPS, function (obj, key) { | 
|   obj[key] = 1; | 
|   return obj; | 
| }, {}); | 
| var transformPropNamesStr = TRANSFORMABLE_PROPS.join(', '); // '' means root | 
|   | 
| export var ELEMENT_ANIMATABLE_PROPS = ['', 'style', 'shape', 'extra']; | 
| ; | 
| var transitionInnerStore = makeInner(); | 
| ; | 
|   | 
| function getElementAnimationConfig(animationType, el, elOption, parentModel, dataIndex) { | 
|   var animationProp = animationType + "Animation"; | 
|   var config = getAnimationConfig(animationType, parentModel, dataIndex) || {}; | 
|   var userDuring = transitionInnerStore(el).userDuring; // Only set when duration is > 0 and it's need to be animated. | 
|   | 
|   if (config.duration > 0) { | 
|     // For simplicity, if during not specified, the previous during will not work any more. | 
|     config.during = userDuring ? bind(duringCall, { | 
|       el: el, | 
|       userDuring: userDuring | 
|     }) : null; | 
|     config.setToFinal = true; | 
|     config.scope = animationType; | 
|   } | 
|   | 
|   extend(config, elOption[animationProp]); | 
|   return config; | 
| } | 
|   | 
| export function applyUpdateTransition(el, elOption, animatableModel, opts) { | 
|   opts = opts || {}; | 
|   var dataIndex = opts.dataIndex, | 
|       isInit = opts.isInit, | 
|       clearStyle = opts.clearStyle; | 
|   var hasAnimation = animatableModel.isAnimationEnabled(); // Save the meta info for further morphing. Like apply on the sub morphing elements. | 
|   | 
|   var store = transitionInnerStore(el); | 
|   var styleOpt = elOption.style; | 
|   store.userDuring = elOption.during; | 
|   var transFromProps = {}; | 
|   var propsToSet = {}; | 
|   prepareTransformAllPropsFinal(el, elOption, propsToSet); | 
|   prepareShapeOrExtraAllPropsFinal('shape', elOption, propsToSet); | 
|   prepareShapeOrExtraAllPropsFinal('extra', elOption, propsToSet); | 
|   | 
|   if (!isInit && hasAnimation) { | 
|     prepareTransformTransitionFrom(el, elOption, transFromProps); | 
|     prepareShapeOrExtraTransitionFrom('shape', el, elOption, transFromProps); | 
|     prepareShapeOrExtraTransitionFrom('extra', el, elOption, transFromProps); | 
|     prepareStyleTransitionFrom(el, elOption, styleOpt, transFromProps); | 
|   } | 
|   | 
|   propsToSet.style = styleOpt; | 
|   applyPropsDirectly(el, propsToSet, clearStyle); | 
|   applyMiscProps(el, elOption); | 
|   | 
|   if (hasAnimation) { | 
|     if (isInit) { | 
|       var enterFromProps_1 = {}; | 
|       each(ELEMENT_ANIMATABLE_PROPS, function (propName) { | 
|         var prop = propName ? elOption[propName] : elOption; | 
|   | 
|         if (prop && prop.enterFrom) { | 
|           if (propName) { | 
|             enterFromProps_1[propName] = enterFromProps_1[propName] || {}; | 
|           } | 
|   | 
|           extend(propName ? enterFromProps_1[propName] : enterFromProps_1, prop.enterFrom); | 
|         } | 
|       }); | 
|       var config = getElementAnimationConfig('enter', el, elOption, animatableModel, dataIndex); | 
|   | 
|       if (config.duration > 0) { | 
|         el.animateFrom(enterFromProps_1, config); | 
|       } | 
|     } else { | 
|       applyPropsTransition(el, elOption, dataIndex || 0, animatableModel, transFromProps); | 
|     } | 
|   } // Store leave to be used in leave transition. | 
|   | 
|   | 
|   updateLeaveTo(el, elOption); | 
|   styleOpt ? el.dirty() : el.markRedraw(); | 
| } | 
| export function updateLeaveTo(el, elOption) { | 
|   // Try merge to previous set leaveTo | 
|   var leaveToProps = transitionInnerStore(el).leaveToProps; | 
|   | 
|   for (var i = 0; i < ELEMENT_ANIMATABLE_PROPS.length; i++) { | 
|     var propName = ELEMENT_ANIMATABLE_PROPS[i]; | 
|     var prop = propName ? elOption[propName] : elOption; | 
|   | 
|     if (prop && prop.leaveTo) { | 
|       if (!leaveToProps) { | 
|         leaveToProps = transitionInnerStore(el).leaveToProps = {}; | 
|       } | 
|   | 
|       if (propName) { | 
|         leaveToProps[propName] = leaveToProps[propName] || {}; | 
|       } | 
|   | 
|       extend(propName ? leaveToProps[propName] : leaveToProps, prop.leaveTo); | 
|     } | 
|   } | 
| } | 
| export function applyLeaveTransition(el, elOption, animatableModel, onRemove) { | 
|   if (el) { | 
|     var parent_1 = el.parent; | 
|     var leaveToProps = transitionInnerStore(el).leaveToProps; | 
|   | 
|     if (leaveToProps) { | 
|       // TODO TODO use leave after leaveAnimation in series is introduced | 
|       // TODO Data index? | 
|       var config = getElementAnimationConfig('update', el, elOption, animatableModel, 0); | 
|   | 
|       config.done = function () { | 
|         parent_1.remove(el); | 
|         onRemove && onRemove(); | 
|       }; | 
|   | 
|       el.animateTo(leaveToProps, config); | 
|     } else { | 
|       parent_1.remove(el); | 
|       onRemove && onRemove(); | 
|     } | 
|   } | 
| } | 
| export function isTransitionAll(transition) { | 
|   return transition === 'all'; | 
| } | 
|   | 
| function applyPropsDirectly(el, // Can be null/undefined | 
| allPropsFinal, clearStyle) { | 
|   var styleOpt = allPropsFinal.style; | 
|   | 
|   if (!el.isGroup && styleOpt) { | 
|     if (clearStyle) { | 
|       el.useStyle({}); // When style object changed, how to trade the existing animation? | 
|       // It is probably complicated and not needed to cover all the cases. | 
|       // But still need consider the case: | 
|       // (1) When using init animation on `style.opacity`, and before the animation | 
|       //     ended users triggers an update by mousewhel. At that time the init | 
|       //     animation should better be continued rather than terminated. | 
|       //     So after `useStyle` called, we should change the animation target manually | 
|       //     to continue the effect of the init animation. | 
|       // (2) PENDING: If the previous animation targeted at a `val1`, and currently we need | 
|       //     to update the value to `val2` and no animation declared, should be terminate | 
|       //     the previous animation or just modify the target of the animation? | 
|       //     Therotically That will happen not only on `style` but also on `shape` and | 
|       //     `transfrom` props. But we haven't handle this case at present yet. | 
|       // (3) PENDING: Is it proper to visit `animators` and `targetName`? | 
|   | 
|       var animators = el.animators; | 
|   | 
|       for (var i = 0; i < animators.length; i++) { | 
|         var animator = animators[i]; // targetName is the "topKey". | 
|   | 
|         if (animator.targetName === 'style') { | 
|           animator.changeTarget(el.style); | 
|         } | 
|       } | 
|     } | 
|   | 
|     el.setStyle(styleOpt); | 
|   } | 
|   | 
|   if (allPropsFinal) { | 
|     // Not set style here. | 
|     allPropsFinal.style = null; // Set el to the final state firstly. | 
|   | 
|     allPropsFinal && el.attr(allPropsFinal); | 
|     allPropsFinal.style = styleOpt; | 
|   } | 
| } | 
|   | 
| function applyPropsTransition(el, elOption, dataIndex, model, // Can be null/undefined | 
| transFromProps) { | 
|   if (transFromProps) { | 
|     var config = getElementAnimationConfig('update', el, elOption, model, dataIndex); | 
|   | 
|     if (config.duration > 0) { | 
|       el.animateFrom(transFromProps, config); | 
|     } | 
|   } | 
| } | 
|   | 
| function applyMiscProps(el, elOption) { | 
|   // Merge by default. | 
|   hasOwn(elOption, 'silent') && (el.silent = elOption.silent); | 
|   hasOwn(elOption, 'ignore') && (el.ignore = elOption.ignore); | 
|   | 
|   if (el instanceof Displayable) { | 
|     hasOwn(elOption, 'invisible') && (el.invisible = elOption.invisible); | 
|   } | 
|   | 
|   if (el instanceof Path) { | 
|     hasOwn(elOption, 'autoBatch') && (el.autoBatch = elOption.autoBatch); | 
|   } | 
| } // Use it to avoid it be exposed to user. | 
|   | 
|   | 
| var tmpDuringScope = {}; | 
| var transitionDuringAPI = { | 
|   // Usually other props do not need to be changed in animation during. | 
|   setTransform: function (key, val) { | 
|     if (process.env.NODE_ENV !== 'production') { | 
|       assert(hasOwn(TRANSFORM_PROPS_MAP, key), 'Only ' + transformPropNamesStr + ' available in `setTransform`.'); | 
|     } | 
|   | 
|     tmpDuringScope.el[key] = val; | 
|     return this; | 
|   }, | 
|   getTransform: function (key) { | 
|     if (process.env.NODE_ENV !== 'production') { | 
|       assert(hasOwn(TRANSFORM_PROPS_MAP, key), 'Only ' + transformPropNamesStr + ' available in `getTransform`.'); | 
|     } | 
|   | 
|     return tmpDuringScope.el[key]; | 
|   }, | 
|   setShape: function (key, val) { | 
|     if (process.env.NODE_ENV !== 'production') { | 
|       assertNotReserved(key); | 
|     } | 
|   | 
|     var el = tmpDuringScope.el; | 
|     var shape = el.shape || (el.shape = {}); | 
|     shape[key] = val; | 
|     el.dirtyShape && el.dirtyShape(); | 
|     return this; | 
|   }, | 
|   getShape: function (key) { | 
|     if (process.env.NODE_ENV !== 'production') { | 
|       assertNotReserved(key); | 
|     } | 
|   | 
|     var shape = tmpDuringScope.el.shape; | 
|   | 
|     if (shape) { | 
|       return shape[key]; | 
|     } | 
|   }, | 
|   setStyle: function (key, val) { | 
|     if (process.env.NODE_ENV !== 'production') { | 
|       assertNotReserved(key); | 
|     } | 
|   | 
|     var el = tmpDuringScope.el; | 
|     var style = el.style; | 
|   | 
|     if (style) { | 
|       if (process.env.NODE_ENV !== 'production') { | 
|         if (eqNaN(val)) { | 
|           warn('style.' + key + ' must not be assigned with NaN.'); | 
|         } | 
|       } | 
|   | 
|       style[key] = val; | 
|       el.dirtyStyle && el.dirtyStyle(); | 
|     } | 
|   | 
|     return this; | 
|   }, | 
|   getStyle: function (key) { | 
|     if (process.env.NODE_ENV !== 'production') { | 
|       assertNotReserved(key); | 
|     } | 
|   | 
|     var style = tmpDuringScope.el.style; | 
|   | 
|     if (style) { | 
|       return style[key]; | 
|     } | 
|   }, | 
|   setExtra: function (key, val) { | 
|     if (process.env.NODE_ENV !== 'production') { | 
|       assertNotReserved(key); | 
|     } | 
|   | 
|     var extra = tmpDuringScope.el.extra || (tmpDuringScope.el.extra = {}); | 
|     extra[key] = val; | 
|     return this; | 
|   }, | 
|   getExtra: function (key) { | 
|     if (process.env.NODE_ENV !== 'production') { | 
|       assertNotReserved(key); | 
|     } | 
|   | 
|     var extra = tmpDuringScope.el.extra; | 
|   | 
|     if (extra) { | 
|       return extra[key]; | 
|     } | 
|   } | 
| }; | 
|   | 
| function assertNotReserved(key) { | 
|   if (process.env.NODE_ENV !== 'production') { | 
|     if (key === 'transition' || key === 'enterFrom' || key === 'leaveTo') { | 
|       throw new Error('key must not be "' + key + '"'); | 
|     } | 
|   } | 
| } | 
|   | 
| function duringCall() { | 
|   // Do not provide "percent" until some requirements come. | 
|   // Because consider thies case: | 
|   // enterFrom: {x: 100, y: 30}, transition: 'x'. | 
|   // And enter duration is different from update duration. | 
|   // Thus it might be confused about the meaning of "percent" in during callback. | 
|   var scope = this; | 
|   var el = scope.el; | 
|   | 
|   if (!el) { | 
|     return; | 
|   } // If el is remove from zr by reason like legend, during still need to called, | 
|   // becuase el will be added back to zr and the prop value should not be incorrect. | 
|   | 
|   | 
|   var latestUserDuring = transitionInnerStore(el).userDuring; | 
|   var scopeUserDuring = scope.userDuring; // Ensured a during is only called once in each animation frame. | 
|   // If a during is called multiple times in one frame, maybe some users' calulation logic | 
|   // might be wrong (not sure whether this usage exists). | 
|   // The case of a during might be called twice can be: by default there is a animator for | 
|   // 'x', 'y' when init. Before the init animation finished, call `setOption` to start | 
|   // another animators for 'style'/'shape'/'extra'. | 
|   | 
|   if (latestUserDuring !== scopeUserDuring) { | 
|     // release | 
|     scope.el = scope.userDuring = null; | 
|     return; | 
|   } | 
|   | 
|   tmpDuringScope.el = el; // Give no `this` to user in "during" calling. | 
|   | 
|   scopeUserDuring(transitionDuringAPI); // FIXME: if in future meet the case that some prop will be both modified in `during` and `state`, | 
|   // consider the issue that the prop might be incorrect when return to "normal" state. | 
| } | 
|   | 
| function prepareShapeOrExtraTransitionFrom(mainAttr, fromEl, elOption, transFromProps) { | 
|   var attrOpt = elOption[mainAttr]; | 
|   | 
|   if (!attrOpt) { | 
|     return; | 
|   } | 
|   | 
|   var elPropsInAttr = fromEl[mainAttr]; | 
|   var transFromPropsInAttr; | 
|   | 
|   if (elPropsInAttr) { | 
|     var transition = elOption.transition; | 
|     var attrTransition = attrOpt.transition; | 
|   | 
|     if (attrTransition) { | 
|       !transFromPropsInAttr && (transFromPropsInAttr = transFromProps[mainAttr] = {}); | 
|   | 
|       if (isTransitionAll(attrTransition)) { | 
|         extend(transFromPropsInAttr, elPropsInAttr); | 
|       } else { | 
|         var transitionKeys = normalizeToArray(attrTransition); | 
|   | 
|         for (var i = 0; i < transitionKeys.length; i++) { | 
|           var key = transitionKeys[i]; | 
|           var elVal = elPropsInAttr[key]; | 
|           transFromPropsInAttr[key] = elVal; | 
|         } | 
|       } | 
|     } else if (isTransitionAll(transition) || indexOf(transition, mainAttr) >= 0) { | 
|       !transFromPropsInAttr && (transFromPropsInAttr = transFromProps[mainAttr] = {}); | 
|       var elPropsInAttrKeys = keys(elPropsInAttr); | 
|   | 
|       for (var i = 0; i < elPropsInAttrKeys.length; i++) { | 
|         var key = elPropsInAttrKeys[i]; | 
|         var elVal = elPropsInAttr[key]; | 
|   | 
|         if (isNonStyleTransitionEnabled(attrOpt[key], elVal)) { | 
|           transFromPropsInAttr[key] = elVal; | 
|         } | 
|       } | 
|     } | 
|   } | 
| } | 
|   | 
| function prepareShapeOrExtraAllPropsFinal(mainAttr, elOption, allProps) { | 
|   var attrOpt = elOption[mainAttr]; | 
|   | 
|   if (!attrOpt) { | 
|     return; | 
|   } | 
|   | 
|   var allPropsInAttr = allProps[mainAttr] = {}; | 
|   var keysInAttr = keys(attrOpt); | 
|   | 
|   for (var i = 0; i < keysInAttr.length; i++) { | 
|     var key = keysInAttr[i]; // To avoid share one object with different element, and | 
|     // to avoid user modify the object inexpectedly, have to clone. | 
|   | 
|     allPropsInAttr[key] = cloneValue(attrOpt[key]); | 
|   } | 
| } | 
|   | 
| function prepareTransformTransitionFrom(el, elOption, transFromProps) { | 
|   var transition = elOption.transition; | 
|   var transitionKeys = isTransitionAll(transition) ? TRANSFORMABLE_PROPS : normalizeToArray(transition || []); | 
|   | 
|   for (var i = 0; i < transitionKeys.length; i++) { | 
|     var key = transitionKeys[i]; | 
|   | 
|     if (key === 'style' || key === 'shape' || key === 'extra') { | 
|       continue; | 
|     } | 
|   | 
|     var elVal = el[key]; | 
|   | 
|     if (process.env.NODE_ENV !== 'production') { | 
|       checkTransformPropRefer(key, 'el.transition'); | 
|     } // Do not clone, animator will perform that clone. | 
|   | 
|   | 
|     transFromProps[key] = elVal; | 
|   } | 
| } | 
|   | 
| function prepareTransformAllPropsFinal(el, elOption, allProps) { | 
|   for (var i = 0; i < LEGACY_TRANSFORM_PROPS.length; i++) { | 
|     var legacyName = LEGACY_TRANSFORM_PROPS[i]; | 
|     var xyName = LEGACY_TRANSFORM_PROPS_MAP[legacyName]; | 
|     var legacyArr = elOption[legacyName]; | 
|   | 
|     if (legacyArr) { | 
|       allProps[xyName[0]] = legacyArr[0]; | 
|       allProps[xyName[1]] = legacyArr[1]; | 
|     } | 
|   } | 
|   | 
|   for (var i = 0; i < TRANSFORMABLE_PROPS.length; i++) { | 
|     var key = TRANSFORMABLE_PROPS[i]; | 
|   | 
|     if (elOption[key] != null) { | 
|       allProps[key] = elOption[key]; | 
|     } | 
|   } | 
| } | 
|   | 
| function prepareStyleTransitionFrom(fromEl, elOption, styleOpt, transFromProps) { | 
|   if (!styleOpt) { | 
|     return; | 
|   } | 
|   | 
|   var fromElStyle = fromEl.style; | 
|   var transFromStyleProps; | 
|   | 
|   if (fromElStyle) { | 
|     var styleTransition = styleOpt.transition; | 
|     var elTransition = elOption.transition; | 
|   | 
|     if (styleTransition && !isTransitionAll(styleTransition)) { | 
|       var transitionKeys = normalizeToArray(styleTransition); | 
|       !transFromStyleProps && (transFromStyleProps = transFromProps.style = {}); | 
|   | 
|       for (var i = 0; i < transitionKeys.length; i++) { | 
|         var key = transitionKeys[i]; | 
|         var elVal = fromElStyle[key]; // Do not clone, see `checkNonStyleTansitionRefer`. | 
|   | 
|         transFromStyleProps[key] = elVal; | 
|       } | 
|     } else if (fromEl.getAnimationStyleProps && (isTransitionAll(elTransition) || isTransitionAll(styleTransition) || indexOf(elTransition, 'style') >= 0)) { | 
|       var animationProps = fromEl.getAnimationStyleProps(); | 
|       var animationStyleProps = animationProps ? animationProps.style : null; | 
|   | 
|       if (animationStyleProps) { | 
|         !transFromStyleProps && (transFromStyleProps = transFromProps.style = {}); | 
|         var styleKeys = keys(styleOpt); | 
|   | 
|         for (var i = 0; i < styleKeys.length; i++) { | 
|           var key = styleKeys[i]; | 
|   | 
|           if (animationStyleProps[key]) { | 
|             var elVal = fromElStyle[key]; | 
|             transFromStyleProps[key] = elVal; | 
|           } | 
|         } | 
|       } | 
|     } | 
|   } | 
| } | 
|   | 
| function isNonStyleTransitionEnabled(optVal, elVal) { | 
|   // The same as `checkNonStyleTansitionRefer`. | 
|   return !isArrayLike(optVal) ? optVal != null && isFinite(optVal) : optVal !== elVal; | 
| } | 
|   | 
| var checkTransformPropRefer; | 
|   | 
| if (process.env.NODE_ENV !== 'production') { | 
|   checkTransformPropRefer = function (key, usedIn) { | 
|     if (!hasOwn(TRANSFORM_PROPS_MAP, key)) { | 
|       warn('Prop `' + key + '` is not a permitted in `' + usedIn + '`. ' + 'Only `' + keys(TRANSFORM_PROPS_MAP).join('`, `') + '` are permitted.'); | 
|     } | 
|   }; | 
| } |