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/19 03:34:40 UTC
[echarts] 02/02: fix(transition): not do strict checking. some code cleanup
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
commit cca220611466bc265add8481540f9cfd29675c61
Author: pissang <bm...@gmail.com>
AuthorDate: Fri Nov 19 11:33:24 2021 +0800
fix(transition): not do strict checking. some code cleanup
---
src/animation/customGraphicTransition.ts | 123 +++++++++++--------------------
src/chart/custom/CustomView.ts | 8 +-
src/component/graphic/GraphicModel.ts | 1 +
src/component/graphic/GraphicView.ts | 42 ++++++++---
test/graphic-transition.html | 39 ++++++++++
5 files changed, 118 insertions(+), 95 deletions(-)
diff --git a/src/animation/customGraphicTransition.ts b/src/animation/customGraphicTransition.ts
index 6ae2106..7459f53 100644
--- a/src/animation/customGraphicTransition.ts
+++ b/src/animation/customGraphicTransition.ts
@@ -34,12 +34,26 @@ import { AnimationOptionMixin, ZRStyleProps } from '../util/types';
import { Dictionary } from 'zrender/lib/core/types';
import { PathStyleProps } from 'zrender';
-const LEGACY_TRANSFORM_PROPS = {
+const LEGACY_TRANSFORM_PROPS_MAP = {
position: ['x', 'y'],
scale: ['scaleX', 'scaleY'],
origin: ['originX', 'originY']
} as const;
-type LegacyTransformProp = keyof typeof LEGACY_TRANSFORM_PROPS;
+const LEGACY_TRANSFORM_PROPS = keys(LEGACY_TRANSFORM_PROPS_MAP);
+type LegacyTransformProp = keyof typeof LEGACY_TRANSFORM_PROPS_MAP;
+
+const TRANSFORM_PROPS_MAP = {
+ x: 1,
+ y: 1,
+ scaleX: 1,
+ scaleY: 1,
+ originX: 1,
+ originY: 1,
+ rotation: 1
+} as const;
+type TransformProp = keyof typeof TRANSFORM_PROPS_MAP;
+const TRANSFORM_PROPS = keys(TRANSFORM_PROPS_MAP);
+const transformPropNamesStr = TRANSFORM_PROPS.join(', ');
export type CustomTransitionProps = string | string[];
export interface TransitionOptionMixin {
@@ -55,17 +69,6 @@ export type ElementTransitionOptionMixin = {
};
type ElementRootTransitionProp = TransformProp | 'shape' | 'extra' | 'style';
-export const TRANSFORM_PROPS = {
- x: 1,
- y: 1,
- scaleX: 1,
- scaleY: 1,
- originX: 1,
- originY: 1,
- rotation: 1
-} as const;
-export type TransformProp = keyof typeof TRANSFORM_PROPS;
-
interface LooseElementProps extends ElementProps {
style?: ZRStyleProps;
shape?: Dictionary<unknown>;
@@ -88,30 +91,6 @@ const transitionInnerStore = makeInner<{
userDuring: (params: TransitionDuringAPI) => void;
}, Element>();
-const transformPropNamesStr = keys(TRANSFORM_PROPS).join(', ');
-
-function setLegacyTransformProp(
- elOption: TransitionElementOption,
- targetProps: Partial<Pick<Transformable, TransformProp>>,
- legacyName: LegacyTransformProp
-): void {
- const legacyArr = (elOption as any)[legacyName];
- const xyName = LEGACY_TRANSFORM_PROPS[legacyName];
- if (legacyArr) {
- targetProps[xyName[0]] = legacyArr[0];
- targetProps[xyName[1]] = legacyArr[1];
- }
-}
-
-function setTransformProp(
- elOption: TransitionElementOption,
- allProps: Partial<Pick<Transformable, TransformProp>>,
- name: TransformProp
-): void {
- if (elOption[name] != null) {
- allProps[name] = elOption[name];
- }
-}
function setTransformPropToTransitionFrom(
transitionFrom: Partial<Pick<Transformable, TransformProp>>,
@@ -158,10 +137,13 @@ export function applyUpdateTransition(
prepareShapeOrExtraTransitionFrom('shape', el, elOption, transFromProps, isInit);
prepareShapeOrExtraAllPropsFinal('shape', elOption, propsToSet);
+
prepareTransformTransitionFrom(el, elOption, transFromProps, isInit);
prepareTransformAllPropsFinal(el, elOption, propsToSet);
+
prepareShapeOrExtraTransitionFrom('extra', el, elOption, transFromProps, isInit);
prepareShapeOrExtraAllPropsFinal('extra', elOption, propsToSet);
+
prepareStyleTransitionFrom(el, elOption, styleOpt, transFromProps, isInit);
(propsToSet as DisplayableProps).style = styleOpt;
applyPropsDirectly(el, propsToSet);
@@ -291,14 +273,14 @@ const transitionDuringAPI: TransitionDuringAPI = {
// Usually other props do not need to be changed in animation during.
setTransform(key: TransformProp, val: unknown) {
if (__DEV__) {
- assert(hasOwn(TRANSFORM_PROPS, key), 'Only ' + transformPropNamesStr + ' available in `setTransform`.');
+ assert(hasOwn(TRANSFORM_PROPS_MAP, key), 'Only ' + transformPropNamesStr + ' available in `setTransform`.');
}
tmpDuringScope.el[key] = val as number;
return this;
},
getTransform(key: TransformProp): number {
if (__DEV__) {
- assert(hasOwn(TRANSFORM_PROPS, key), 'Only ' + transformPropNamesStr + ' available in `getTransform`.');
+ assert(hasOwn(TRANSFORM_PROPS_MAP, key), 'Only ' + transformPropNamesStr + ' available in `getTransform`.');
}
return tmpDuringScope.el[key];
},
@@ -463,10 +445,6 @@ function prepareShapeOrExtraTransitionFrom(
for (let i = 0; i < transitionKeys.length; i++) {
const key = transitionKeys[i];
const elVal = elPropsInAttr[key];
- if (__DEV__) {
- checkNonStyleTansitionRefer(key, (attrOpt as any)[key], elVal);
- }
- // Do not clone, see `checkNonStyleTansitionRefer`.
transFromPropsInAttr[key] = elVal;
}
}
@@ -544,9 +522,8 @@ function prepareTransformTransitionFrom(
const elVal = el[key];
if (__DEV__) {
checkTransformPropRefer(key, 'el.transition');
- checkNonStyleTansitionRefer(key, elOption[key], elVal);
}
- // Do not clone, see `checkNonStyleTansitionRefer`.
+ // Do not clone, animator will perform that clone.
transFromProps[key] = elVal;
}
}
@@ -576,17 +553,22 @@ function prepareTransformAllPropsFinal(
elOption: TransitionElementOption,
allProps: ElementProps
): void {
- setLegacyTransformProp(elOption, allProps, 'position');
- setLegacyTransformProp(elOption, allProps, 'scale');
- setLegacyTransformProp(elOption, allProps, 'origin');
-
- setTransformProp(elOption, allProps, 'x');
- setTransformProp(elOption, allProps, 'y');
- setTransformProp(elOption, allProps, 'scaleX');
- setTransformProp(elOption, allProps, 'scaleY');
- setTransformProp(elOption, allProps, 'originX');
- setTransformProp(elOption, allProps, 'originY');
- setTransformProp(elOption, allProps, 'rotation');
+ for (let i = 0; i < LEGACY_TRANSFORM_PROPS.length; i++) {
+ const legacyName = LEGACY_TRANSFORM_PROPS[i];
+ const xyName = LEGACY_TRANSFORM_PROPS_MAP[legacyName];
+ const legacyArr = (elOption as any)[legacyName];
+ if (legacyArr) {
+ allProps[xyName[0]] = legacyArr[0];
+ allProps[xyName[1]] = legacyArr[1];
+ }
+ }
+
+ for (let i = 0; i < TRANSFORM_PROPS.length; i++) {
+ const key = TRANSFORM_PROPS[i];
+ if (elOption[key] != null) {
+ allProps[key] = elOption[key];
+ }
+ }
}
function prepareStyleTransitionFrom(
@@ -657,26 +639,6 @@ function prepareStyleTransitionFrom(
}
}
-let checkNonStyleTansitionRefer: (propName: string, optVal: unknown, elVal: unknown) => void;
-if (__DEV__) {
- checkNonStyleTansitionRefer = function (propName: string, optVal: unknown, elVal: unknown): void {
- if (!isArrayLike(optVal)) {
- assert(
- optVal != null && isFinite(optVal as number),
- 'Prop `' + propName + '` must refer to a finite number or ArrayLike for transition.'
- );
- }
- else {
- // Try not to copy array for performance, but if user use the same object in different
- // call of `renderItem`, it will casue animation transition fail.
- assert(
- optVal !== elVal,
- 'Prop `' + propName + '` must use different Array object each time for transition.'
- );
- }
- };
-}
-
function isNonStyleTransitionEnabled(optVal: unknown, elVal: unknown): boolean {
// The same as `checkNonStyleTansitionRefer`.
return !isArrayLike(optVal)
@@ -687,11 +649,10 @@ function isNonStyleTransitionEnabled(optVal: unknown, elVal: unknown): boolean {
let checkTransformPropRefer: (key: string, usedIn: string) => void;
if (__DEV__) {
checkTransformPropRefer = function (key: string, usedIn: string): void {
- assert(
- hasOwn(TRANSFORM_PROPS, key),
- 'Prop `' + key + '` is not a permitted in `' + usedIn + '`. '
- + 'Only `' + keys(TRANSFORM_PROPS).join('`, `') + '` are permitted.'
- );
+ if (!hasOwn(TRANSFORM_PROPS_MAP, key)) {
+ warn('Prop `' + key + '` is not a permitted in `' + usedIn + '`. '
+ + 'Only `' + keys(TRANSFORM_PROPS_MAP).join('`, `') + '` are permitted.');
+ }
};
}
diff --git a/src/chart/custom/CustomView.ts b/src/chart/custom/CustomView.ts
index 2d80864..47f90f1 100644
--- a/src/chart/custom/CustomView.ts
+++ b/src/chart/custom/CustomView.ts
@@ -491,9 +491,7 @@ function updateElOnState(
el: Element,
elStateOpt: CustomElementOptionOnState,
styleOpt: CustomElementOptionOnState['style'],
- attachedTxInfo: AttachedTxInfo,
- isRoot: boolean,
- isTextContent: boolean
+ attachedTxInfo: AttachedTxInfo
): void {
const elDisplayable = el.isGroup ? null : el as Displayable;
const txCfgOpt = attachedTxInfo && attachedTxInfo[state].cfg;
@@ -1009,7 +1007,7 @@ function doCreateOrUpdateEl(
if (stateName !== NORMAL) {
const otherStateOpt = retrieveStateOption(elOption, stateName);
const otherStyleOpt = retrieveStyleOptionOnState(elOption, otherStateOpt, stateName);
- updateElOnState(stateName, el, otherStateOpt, otherStyleOpt, attachedTxInfoTmp, isRoot, false);
+ updateElOnState(stateName, el, otherStateOpt, otherStyleOpt, attachedTxInfoTmp);
}
}
@@ -1161,7 +1159,7 @@ function doCreateOrUpdateAttachedTx(
textContent,
txConOptOtherState,
retrieveStyleOptionOnState(txConOptNormal, txConOptOtherState, stateName),
- null, false, true
+ null
);
}
}
diff --git a/src/component/graphic/GraphicModel.ts b/src/component/graphic/GraphicModel.ts
index 8b14ea9..8c49869 100644
--- a/src/component/graphic/GraphicModel.ts
+++ b/src/component/graphic/GraphicModel.ts
@@ -123,6 +123,7 @@ export interface GraphicComponentDisplayableOption extends
Partial<Pick<Displayable, 'zlevel' | 'z' | 'z2' | 'invisible' | 'cursor'>> {
style?: ZRStyleProps & TransitionOptionMixin
+ z2?: number
}
// TODO: states?
// interface GraphicComponentDisplayableOptionOnState extends Partial<Pick<
diff --git a/src/component/graphic/GraphicView.ts b/src/component/graphic/GraphicView.ts
index 6225923..9158cc0 100644
--- a/src/component/graphic/GraphicView.ts
+++ b/src/component/graphic/GraphicView.ts
@@ -18,16 +18,17 @@
*/
import * as zrUtil from 'zrender/src/core/util';
+import { TextStyleProps } from 'zrender/src/graphic/Text';
+import Displayable from 'zrender/src/graphic/Displayable';
+import Element from 'zrender/src/Element';
import * as modelUtil from '../../util/model';
import * as graphicUtil from '../../util/graphic';
import * as layoutUtil from '../../util/layout';
import { parsePercent } from '../../util/number';
-import Element from 'zrender/src/Element';
import GlobalModel from '../../model/Global';
import ComponentView from '../../view/Component';
import ExtensionAPI from '../../core/ExtensionAPI';
import { getECData } from '../../util/innerStore';
-import { TextStyleProps } from 'zrender/src/graphic/Text';
import { isEC4CompatibleStyle, convertFromEC4CompatibleStyle } from '../../util/styleCompat';
import {
ElementMap,
@@ -106,6 +107,9 @@ export class GraphicComponentView extends ComponentView {
const elMap = this._elMap;
const rootGroup = this.group;
+ const globalZ = graphicModel.get('z');
+ const globalZLevel = graphicModel.get('zlevel');
+
// Top-down tranverse to assign graphic settings to each elements.
zrUtil.each(elOptionsToUpdate, function (elOption) {
const id = modelUtil.convertOptionIdName(elOption.id, null);
@@ -158,13 +162,16 @@ export class GraphicComponentView extends ComponentView {
if (isInit) {
el = createEl(id, targetElParent, elOption.type, elMap);
}
- el && applyUpdateTransition(
- el,
- elOptionCleaned,
- graphicModel,
- 0, // TODO Fixed dataIndex to be 0
- isInit
- );
+ if (el) {
+ applyUpdateTransition(
+ el,
+ elOptionCleaned,
+ graphicModel,
+ 0, // TODO Fixed dataIndex to be 0
+ isInit
+ );
+ updateZ(el, elOption, globalZ, globalZLevel);
+ }
}
else if ($action === 'replace') {
removeEl(elExisting, elMap, graphicModel);
@@ -177,6 +184,7 @@ export class GraphicComponentView extends ComponentView {
0, // TODO Fixed dataIndex to be 0
true
);
+ updateZ(el, elOption, globalZ, globalZLevel);
}
}
else if ($action === 'remove') {
@@ -335,6 +343,22 @@ function removeEl(elExisting: Element, elMap: ElementMap, graphicModel: GraphicC
elMap.removeKey(inner(elExisting).id);
}
}
+
+function updateZ(el: Element, elOption: GraphicComponentElementOption, defaultZ: number, defaultZlevel: number) {
+ if (el.isGroup) {
+ return;
+ }
+
+ const elDisplayable = el as Displayable;
+ // We should not support configure z and zlevel in the element level.
+ // But seems we didn't limit it previously. So here still use it to avoid breaking.
+ elDisplayable.z = zrUtil.retrieve2((elOption as any).z, defaultZ);
+ elDisplayable.zlevel = zrUtil.retrieve2((elOption as any).zlevel, defaultZlevel);
+ // z2 must not be null/undefined, otherwise sort error may occur.
+ const optZ2 = (elOption as GraphicComponentDisplayableOption).z2;
+ optZ2 != null && (elDisplayable.z2 = optZ2 || 0);
+
+}
// Remove unnecessary props to avoid potential problems.
function getCleanedElOption(
elOption: GraphicComponentElementOption
diff --git a/test/graphic-transition.html b/test/graphic-transition.html
index 20bd92c..b4c8de9 100644
--- a/test/graphic-transition.html
+++ b/test/graphic-transition.html
@@ -99,6 +99,22 @@ under the License.
})
}
},
+
+ {
+ text: 'Move to x: 100, y: 50',
+ onclick() {
+ chart.setOption({
+ graphic: {
+ elements: [{
+ type: 'circle',
+ transition: ['x', 'y'],
+ x: 100,
+ y: 50
+ }]
+ }
+ })
+ }
+ }
]
});
@@ -114,11 +130,34 @@ under the License.
<script>
require(['echarts'/*, 'map/js/china' */], function (echarts) {
var option;
+ // Enter transition
+ });
+ </script>
+ <script>
+ require(['echarts'/*, 'map/js/china' */], function (echarts) {
+ var option;
+
+ // Leave transition
+ });
+ </script>
+
+ <script>
+ require(['echarts'/*, 'map/js/china' */], function (echarts) {
+ var option;
+
+ // Replace transition
});
</script>
+ <script>
+ require(['echarts'/*, 'map/js/china' */], function (echarts) {
+ var option;
+
+ // During transition
+ });
+ </script>
</body>
</html>
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org