From 1123c226a249f0fb128009c085d5be27e04c58df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=A5=E6=98=95?= Date: Thu, 7 Nov 2019 22:22:05 +0800 Subject: [PATCH] fix(g-base): animation for gradient color should be correct --- packages/g-base/src/abstract/element.ts | 6 +---- packages/g-base/src/animate/timeline.ts | 3 +++ packages/g-base/src/util/color.ts | 3 +++ packages/g-base/tests/unit/animate-spec.js | 27 ++++++++++++++++++++++ 4 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 packages/g-base/src/util/color.ts diff --git a/packages/g-base/src/abstract/element.ts b/packages/g-base/src/abstract/element.ts index 56840cb5c..ddd82564d 100644 --- a/packages/g-base/src/abstract/element.ts +++ b/packages/g-base/src/abstract/element.ts @@ -17,8 +17,6 @@ const CLONE_CFGS = ['zIndex', 'capture', 'visible']; const RESERVED_PORPS = ['delay']; -const COLOR_RELATED_PROPS = ['fill', 'fillStyle', 'stroke', 'strokeStyle']; - // 需要考虑数组嵌套数组的场景 // 数组嵌套对象的场景不考虑 function _cloneArrayAttr(arr) { @@ -46,9 +44,7 @@ function getFormatToAttrs(props, shape) { const toAttrs = {}; const attrs = shape.attr(); each(props, (v, k) => { - if (COLOR_RELATED_PROPS.indexOf(k) !== -1 && /^[r,R,L,l]{1}[\s]*\(/.test(v)) { - // Do nothing, 渐变色不支持动画 - } else if (RESERVED_PORPS.indexOf(k) === -1 && !isEqual(attrs[k], v)) { + if (RESERVED_PORPS.indexOf(k) === -1 && !isEqual(attrs[k], v)) { toAttrs[k] = v; } }); diff --git a/packages/g-base/src/animate/timeline.ts b/packages/g-base/src/animate/timeline.ts index 4e59e5dff..cb2f0aa6a 100644 --- a/packages/g-base/src/animate/timeline.ts +++ b/packages/g-base/src/animate/timeline.ts @@ -3,6 +3,7 @@ import * as d3Timer from 'd3-timer'; import * as d3Ease from 'd3-ease'; import { interpolate, interpolateArray } from 'd3-interpolate'; // 目前整体动画只需要数值和数组的差值计算 import * as PathUtil from '../util/path'; +import { isColorProp, isGradientColor } from '../util/color'; import { ICanvas, IElement } from '../interfaces'; import { Animation } from '../types'; @@ -59,6 +60,8 @@ function _update(shape: IElement, animation: Animation, ratio: number) { const matrixFn = interpolateArray(fromAttrs[k], toAttrs[k]); const currentMatrix = matrixFn(ratio); shape.setMatrix(currentMatrix); + } else if (isColorProp(k) && isGradientColor(toAttrs[k])) { + cProps[k] = toAttrs[k]; } else { interf = interpolate(fromAttrs[k], toAttrs[k]); cProps[k] = interf(ratio); diff --git a/packages/g-base/src/util/color.ts b/packages/g-base/src/util/color.ts new file mode 100644 index 000000000..cd81d9bc1 --- /dev/null +++ b/packages/g-base/src/util/color.ts @@ -0,0 +1,3 @@ +export const isColorProp = (prop) => ['fill', 'stroke', 'fillStyle', 'strokeStyle'].includes(prop); + +export const isGradientColor = (val) => /^[r,R,L,l]{1}[\s]*\(/.test(val); diff --git a/packages/g-base/tests/unit/animate-spec.js b/packages/g-base/tests/unit/animate-spec.js index 39d88e34d..1019dceaf 100644 --- a/packages/g-base/tests/unit/animate-spec.js +++ b/packages/g-base/tests/unit/animate-spec.js @@ -615,4 +615,31 @@ describe('animate', () => { done(); }, 1800); }); + + it('animate for gradient color should be correct', (done) => { + const gradientColor = 'l (90) 0:RGBA(39, 117, 255, 0.8) 1:rgba(255,255,255, 0)'; + const shape = new Shape({ + attrs: { + x: 50, + y: 50, + fill: 'red', + }, + }); + canvas.add(shape); + shape.animate( + { + fill: gradientColor, + }, + { + duration: 500, + } + ); + setTimeout(() => { + expect(shape.attr('fill')).eqls(gradientColor); + }, 200); + setTimeout(() => { + expect(shape.attr('fill')).eqls(gradientColor); + done(); + }, 600); + }); });