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/02/02 14:14:00 UTC
[echarts] branch enhance-morph updated: fix(morph): handle path
number don't match between morph groups
This is an automated email from the ASF dual-hosted git repository.
shenyi pushed a commit to branch enhance-morph
in repository https://gitbox.apache.org/repos/asf/echarts.git
The following commit(s) were added to refs/heads/enhance-morph by this push:
new 4c43b64 fix(morph): handle path number don't match between morph groups
4c43b64 is described below
commit 4c43b64f2d6726a075522b66931e100e09d3854a
Author: pissang <bm...@gmail.com>
AuthorDate: Tue Feb 2 21:56:57 2021 +0800
fix(morph): handle path number don't match between morph groups
---
src/chart/custom/CustomView.ts | 8 ++
src/chart/custom/transitionHelper.ts | 156 ++++++++++++++++++++++-------------
2 files changed, 106 insertions(+), 58 deletions(-)
diff --git a/src/chart/custom/CustomView.ts b/src/chart/custom/CustomView.ts
index a9daaf1..249d20e 100644
--- a/src/chart/custom/CustomView.ts
+++ b/src/chart/custom/CustomView.ts
@@ -603,9 +603,17 @@ function updateElNormal(
}
else {
// Needs shape and transform info in morphing.
+ // Will set all properties in prepare
prepareTransformAllPropsFinal(el, elOption, propsToSet);
prepareShapeOrExtraAllPropsFinal('shape', elOption, propsToSet);
+
+ // Other properties also needs to be set.
+ prepareShapeOrExtraAllPropsFinal('extra', elOption, propsToSet);
+ prepareStyleTransitionFrom(el, elOption, styleOpt, transFromProps, isInit);
+ (propsToSet as DisplayableProps).style = styleOpt;
+
applyPropsDirectly(el, propsToSet);
+ applyMiscProps(el, elOption, isTextContent);
store.option = elOption;
}
diff --git a/src/chart/custom/transitionHelper.ts b/src/chart/custom/transitionHelper.ts
index 361feb3..a6cd8c0 100644
--- a/src/chart/custom/transitionHelper.ts
+++ b/src/chart/custom/transitionHelper.ts
@@ -23,8 +23,6 @@ import {
combineMorph,
morphPath,
isCombineMorphing,
- SeparateConfig,
- CombineConfig,
SplitPathParams
} from 'zrender/src/tool/morphPath';
import { Path } from '../../util/graphic';
@@ -32,7 +30,7 @@ import { SeriesModel } from '../../export/api';
import Element, { ElementAnimateConfig } from 'zrender/src/Element';
import { AnimationEasing } from 'zrender/src/animation/easing';
import { PayloadAnimationPart } from '../../util/types';
-import { defaults, extend, isArray, isFunction } from 'zrender/src/core/util';
+import { defaults, isArray, isFunction } from 'zrender/src/core/util';
import Displayable from 'zrender/src/graphic/Displayable';
import { clonePath } from 'zrender/src/tool/path';
@@ -87,6 +85,55 @@ function clonePaths({ path, count }: SplitPathParams) {
return paths;
}
+interface MorphingBatch {
+ one: Path;
+ many: Path[];
+}
+
+function prepareMorphBatches(one: DescendentPaths, many: DescendentPaths[]) {
+ const batches: MorphingBatch[] = [];
+ const batchCount = one.length;
+ for (let i = 0; i < batchCount; i++) {
+ batches.push({
+ one: one[i],
+ many: []
+ });
+ }
+
+ for (let i = 0; i < many.length; i++) {
+ const len = many[i].length;
+ let k;
+ for (k = 0; k < len; k++) {
+ batches[k % batchCount].many.push(many[i][k]);
+ }
+ }
+
+ let off = 0;
+ // If one has more paths than each one of many. average them.
+ for (let i = batchCount - 1; i >= 0; i--) {
+ if (!batches[i].many.length) {
+ const moveFrom = batches[off].many;
+ if (moveFrom.length <= 1) { // Not enough
+ // Start from the first one.
+ if (off) {
+ off = 0;
+ }
+ else {
+ return batches;
+ }
+ }
+ const len = moveFrom.length;
+ const mid = Math.ceil(len / 2);
+ batches[i].many = moveFrom.slice(mid, len);
+ batches[off].many = moveFrom.slice(0, mid);
+
+ off++;
+ }
+ }
+
+ return batches;
+}
+
export function applyMorphAnimation(
from: DescendentPaths | DescendentPaths[],
to: DescendentPaths | DescendentPaths[],
@@ -111,74 +158,67 @@ export function applyMorphAnimation(
one = from as DescendentPaths;
}
- if (many) {
- const animationCfgWithSplitPath = defaults({
- splitPath: clonePaths
- }, animationCfg);
- // TODO mergeByName
- for (let i = 0; i < one.length; i++) {
- const manyPaths: Path[] = [];
- for (let k = 0; k < many.length; k++) {
- if (many[k][i]) {
- manyPaths.push(many[k][i]);
- }
- }
- let fromIndividuals;
- let toIndividuals;
+ const animationCfgWithSplitPath = defaults({
+ splitPath: clonePaths
+ }, animationCfg);
- if (many === from) { // manyToOne
- const res = combineMorph(
- manyPaths, one[i], animationCfgWithSplitPath
- );
- fromIndividuals = res.fromIndividuals;
- toIndividuals = res.toIndividuals;
+ function morphOneBatch(batch: MorphingBatch, fromIsMany: boolean, forceManyOne?: boolean) {
+ const batchMany = batch.many;
+ const batchOne = batch.one;
+ if (batchMany.length === 1 && !forceManyOne) {
+ // Is one to one
+ const batchFrom: Path = fromIsMany ? batchMany[0] : batchOne;
+ const batchTo: Path = fromIsMany ? batchOne : batchMany[0];
+ // Path is reused.
+ if (batchFrom === batchTo) {
+ return;
}
- else { // oneToMany
- const res = separateMorph(
- one[i], manyPaths, animationCfgWithSplitPath
- );
- fromIndividuals = res.fromIndividuals;
- toIndividuals = res.toIndividuals;
+ if (isCombineMorphing(batchFrom as Path)) {
+ // Keep doing combine animation.
+ morphOneBatch({
+ many: [batchFrom as Path],
+ one: batchTo as Path
+ }, true, true);
+ }
+ else {
+ morphPath(batchFrom, batchTo, animationCfg);
+ updateOtherProps(batchFrom, batchTo, batchFrom, batchTo);
}
+ }
+ else {
+ const {
+ fromIndividuals,
+ toIndividuals
+ } = fromIsMany
+ ? combineMorph(batchMany, batchOne, animationCfgWithSplitPath)
+ : separateMorph(batchOne, batchMany, animationCfgWithSplitPath);
for (let k = 0; k < fromIndividuals.length; k++) {
updateOtherProps(
fromIndividuals[k],
toIndividuals[k],
- many === from ? manyPaths[k] : one[i],
- many === from ? one[i] : manyPaths[k]
+ fromIsMany ? batchMany[k] : batch.one,
+ fromIsMany ? batch.one : batchMany[k]
);
}
}
}
- else { // oneToOne
- for (let i = 0; i < to.length; i++) {
- if (from[i]) {
- // Reuse the path.
- if (from[i] === to[i]) {
- continue;
- }
- if (isCombineMorphing(from[i] as Path)) {
- // Keep doing combine animation.
- const {fromIndividuals, toIndividuals} = combineMorph(
- [from[i] as Path], to[i] as Path, animationCfg as CombineConfig
- );
- for (let k = 0; k < fromIndividuals.length; k++) {
- updateOtherProps(
- fromIndividuals[k],
- toIndividuals[k],
- fromIndividuals[k],
- toIndividuals[k]
- );
- }
- }
- else {
- morphPath(from[i] as Path, to[i] as Path, animationCfg);
- updateOtherProps(from[i] as Path, to[i] as Path, from[i] as Path, to[i] as Path);
- }
- }
- }
+
+ const fromIsMany = many
+ ? many === from
+ // Is one to one. If the path number not match. also needs do merge and separate morphing.
+ : from.length > to.length;
+
+ // TODO mergeByName
+ const morphBatches = many
+ ? prepareMorphBatches(one, many)
+ : prepareMorphBatches(
+ (fromIsMany ? to : from) as DescendentPaths,
+ [(fromIsMany ? from : to) as DescendentPaths]
+ );
+ for (let i = 0; i < morphBatches.length; i++) {
+ morphOneBatch(morphBatches[i], fromIsMany);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org