From 0e67fd7300d03725994f81c444dfdd6e3372fed2 Mon Sep 17 00:00:00 2001 From: zhouxinyu Date: Sun, 29 Sep 2024 16:29:29 +0800 Subject: [PATCH 01/24] fix: fix issue with dirtyBounds incorrectly while set visible --- .../fix-visible-bounds_2024-09-29-08-30.json | 10 ++++++++++ .../src/graphic/graphic-service/graphic-service.ts | 10 +++++----- packages/vrender/__tests__/browser/src/pages/text.ts | 2 ++ 3 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 common/changes/@visactor/vrender-core/fix-visible-bounds_2024-09-29-08-30.json diff --git a/common/changes/@visactor/vrender-core/fix-visible-bounds_2024-09-29-08-30.json b/common/changes/@visactor/vrender-core/fix-visible-bounds_2024-09-29-08-30.json new file mode 100644 index 000000000..e590b282f --- /dev/null +++ b/common/changes/@visactor/vrender-core/fix-visible-bounds_2024-09-29-08-30.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vrender-core", + "comment": "fix: fix issue with dirtyBounds incorrectly while set visible", + "type": "none" + } + ], + "packageName": "@visactor/vrender-core" +} \ No newline at end of file diff --git a/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts b/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts index 186d5535e..f345b256c 100644 --- a/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts +++ b/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts @@ -23,6 +23,7 @@ import { BoundsContext } from '../../common/bounds-context'; import { renderCommandList } from '../../common/render-command-list'; import { GraphicCreator } from '../constants'; import { identityMat4, multiplyMat4Mat4, rotateX, rotateY, rotateZ, scaleMat4, translate } from '../../common/matrix'; +import { application } from '../../application'; export function getExtraModelMatrix(dx: number, dy: number, graphic: IGraphic): mat4 | null { const { alpha, beta } = graphic.attribute; @@ -366,13 +367,12 @@ export class DefaultGraphicService implements IGraphicService { return true; } - if (!graphic.valid) { - aabbBounds.clear(); - return false; - } const { visible = theme.visible } = attribute; - if (!visible) { + + if (!(graphic.valid && visible)) { + application.graphicService.beforeUpdateAABBBounds(graphic, graphic.stage, true, aabbBounds); aabbBounds.clear(); + application.graphicService.afterUpdateAABBBounds(graphic, graphic.stage, aabbBounds, graphic, true); return false; } return true; diff --git a/packages/vrender/__tests__/browser/src/pages/text.ts b/packages/vrender/__tests__/browser/src/pages/text.ts index 14c410ad3..b182b9298 100644 --- a/packages/vrender/__tests__/browser/src/pages/text.ts +++ b/packages/vrender/__tests__/browser/src/pages/text.ts @@ -190,6 +190,8 @@ export const page = () => { // scaleY: 2 }); graphics.push(text); + text.setAttributes({ visible: false }); + console.log(text.AABBBounds); const b = text.OBBBounds; const circle = createCircle({ x: (b.x1 + b.x2) / 2, From 7b8372c9a717b68f80941fe6693badf0167c2059 Mon Sep 17 00:00:00 2001 From: zhouxinyu Date: Sun, 29 Sep 2024 16:47:30 +0800 Subject: [PATCH 02/24] fix: add clearAABBBounds interface --- .../graphic/graphic-service/graphic-service.ts | 17 +++++++++++++---- .../src/interface/graphic-service.ts | 2 ++ .../builtin-plugin/dirty-bounds-plugin.ts | 15 +++++++++++++++ .../vrender/__tests__/browser/src/pages/text.ts | 8 ++++++-- 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts b/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts index f345b256c..5ad5802a3 100644 --- a/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts +++ b/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts @@ -176,6 +176,7 @@ export class DefaultGraphicService implements IGraphicService { onClearIncremental: ISyncHook<[IGroup, IStage]>; beforeUpdateAABBBounds: ISyncHook<[IGraphic, IStage, boolean, IAABBBounds]>; afterUpdateAABBBounds: ISyncHook<[IGraphic, IStage, IAABBBounds, { globalAABBBounds: IAABBBounds }, boolean]>; + clearAABBBounds: ISyncHook<[IGraphic, IStage, IAABBBounds]>; }; // 临时bounds,用作缓存 @@ -201,7 +202,8 @@ export class DefaultGraphicService implements IGraphicService { 'aabbBounds', 'globalAABBBounds', 'selfChange' - ]) + ]), + clearAABBBounds: new SyncHook<[IGraphic, IStage, IAABBBounds]>(['graphic', 'stage', 'aabbBounds']) }; this.tempAABBBounds1 = new AABBBounds(); this.tempAABBBounds2 = new AABBBounds(); @@ -252,6 +254,11 @@ export class DefaultGraphicService implements IGraphicService { this.hooks.afterUpdateAABBBounds.call(graphic, stage, bounds, params, selfChange); } } + clearAABBBounds(graphic: IGraphic, stage: IStage, b: IAABBBounds) { + if (this.hooks.clearAABBBounds.taps.length) { + this.hooks.clearAABBBounds.call(graphic, stage, b); + } + } // TODO delete updatePathProxyAABBBounds(aabbBounds: IAABBBounds, graphic?: IGraphic): boolean { const path = typeof graphic.pathProxy === 'function' ? graphic.pathProxy(graphic.attribute) : graphic.pathProxy; @@ -370,9 +377,11 @@ export class DefaultGraphicService implements IGraphicService { const { visible = theme.visible } = attribute; if (!(graphic.valid && visible)) { - application.graphicService.beforeUpdateAABBBounds(graphic, graphic.stage, true, aabbBounds); - aabbBounds.clear(); - application.graphicService.afterUpdateAABBBounds(graphic, graphic.stage, aabbBounds, graphic, true); + // application.graphicService.beforeUpdateAABBBounds(graphic, graphic.stage, true, aabbBounds); + if (!aabbBounds.empty()) { + application.graphicService.clearAABBBounds(graphic, graphic.stage, aabbBounds); + aabbBounds.clear(); + } return false; } return true; diff --git a/packages/vrender-core/src/interface/graphic-service.ts b/packages/vrender-core/src/interface/graphic-service.ts index 19e0464f6..c5ba53f5e 100644 --- a/packages/vrender-core/src/interface/graphic-service.ts +++ b/packages/vrender-core/src/interface/graphic-service.ts @@ -51,6 +51,7 @@ export interface IGraphicService { onClearIncremental: ISyncHook<[IGroup, IStage]>; beforeUpdateAABBBounds: ISyncHook<[IGraphic, IStage, boolean, IAABBBounds]>; afterUpdateAABBBounds: ISyncHook<[IGraphic, IStage, IAABBBounds, { globalAABBBounds: IAABBBounds }, boolean]>; + clearAABBBounds: ISyncHook<[IGraphic, IStage, IAABBBounds]>; }; beforeUpdateAABBBounds: (graphic: IGraphic, stage: IStage, willUpdate: boolean, bounds: IAABBBounds) => void; afterUpdateAABBBounds: ( @@ -60,6 +61,7 @@ export interface IGraphicService { params: { globalAABBBounds: IAABBBounds }, selfChange: boolean ) => void; + clearAABBBounds: (graphic: IGraphic, stage: IStage, b: IAABBBounds) => void; creator: IGraphicCreator; validCheck: ( diff --git a/packages/vrender-core/src/plugins/builtin-plugin/dirty-bounds-plugin.ts b/packages/vrender-core/src/plugins/builtin-plugin/dirty-bounds-plugin.ts index 4b9115062..9e4557724 100644 --- a/packages/vrender-core/src/plugins/builtin-plugin/dirty-bounds-plugin.ts +++ b/packages/vrender-core/src/plugins/builtin-plugin/dirty-bounds-plugin.ts @@ -59,6 +59,17 @@ export class DirtyBoundsPlugin implements IPlugin { stage.dirty(params.globalAABBBounds); } ); + application.graphicService.hooks.clearAABBBounds.tap( + this.key, + (graphic: IGraphic, stage: IStage, bounds: IAABBBounds) => { + if (!(stage && stage === this.pluginService.stage && stage.renderCount)) { + return; + } + if (stage) { + stage.dirty(bounds); + } + } + ); application.graphicService.hooks.onRemove.tap(this.key, (graphic: IGraphic) => { const stage = graphic.stage; if (!(stage && stage === this.pluginService.stage && stage.renderCount)) { @@ -78,6 +89,10 @@ export class DirtyBoundsPlugin implements IPlugin { application.graphicService.hooks.afterUpdateAABBBounds.taps.filter(item => { return item.name !== this.key; }); + application.graphicService.hooks.clearAABBBounds.taps = + application.graphicService.hooks.clearAABBBounds.taps.filter(item => { + return item.name !== this.key; + }); context.stage.hooks.afterRender.taps = context.stage.hooks.afterRender.taps.filter(item => { return item.name !== this.key; }); diff --git a/packages/vrender/__tests__/browser/src/pages/text.ts b/packages/vrender/__tests__/browser/src/pages/text.ts index b182b9298..ed9685436 100644 --- a/packages/vrender/__tests__/browser/src/pages/text.ts +++ b/packages/vrender/__tests__/browser/src/pages/text.ts @@ -190,8 +190,11 @@ export const page = () => { // scaleY: 2 }); graphics.push(text); - text.setAttributes({ visible: false }); - console.log(text.AABBBounds); + setTimeout(() => { + debugger; + text.setAttributes({ visible: false }); + console.log(text.AABBBounds); + }, 1000); const b = text.OBBBounds; const circle = createCircle({ x: (b.x1 + b.x2) / 2, @@ -235,6 +238,7 @@ export const page = () => { const stage = createStage({ canvas: 'main', autoRender: true, + disableDirtyBounds: false, pluginList: ['poptipForText'] }); From 9b12fa5131747968d64576a259bac0d03082a350 Mon Sep 17 00:00:00 2001 From: zhouxinyu Date: Mon, 30 Sep 2024 11:16:54 +0800 Subject: [PATCH 03/24] fix: fix issue with dirtyBounds by calc globalAABBBounds --- .../vrender-core/src/graphic/graphic-service/graphic-service.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts b/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts index 5ad5802a3..cc5276501 100644 --- a/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts +++ b/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts @@ -379,6 +379,7 @@ export class DefaultGraphicService implements IGraphicService { if (!(graphic.valid && visible)) { // application.graphicService.beforeUpdateAABBBounds(graphic, graphic.stage, true, aabbBounds); if (!aabbBounds.empty()) { + aabbBounds.transformWithMatrix((graphic.parent as IGroup).globalTransMatrix); application.graphicService.clearAABBBounds(graphic, graphic.stage, aabbBounds); aabbBounds.clear(); } From 241e539c07897d0a68065de24d9d899ac09ae88a Mon Sep 17 00:00:00 2001 From: zhouxinyu Date: Mon, 30 Sep 2024 14:44:11 +0800 Subject: [PATCH 04/24] fix: fix bug where clearAABBSounds is called when graphic.parent is null --- .../vrender-core/src/graphic/graphic-service/graphic-service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts b/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts index cc5276501..115c94ba6 100644 --- a/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts +++ b/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts @@ -379,7 +379,7 @@ export class DefaultGraphicService implements IGraphicService { if (!(graphic.valid && visible)) { // application.graphicService.beforeUpdateAABBBounds(graphic, graphic.stage, true, aabbBounds); if (!aabbBounds.empty()) { - aabbBounds.transformWithMatrix((graphic.parent as IGroup).globalTransMatrix); + graphic.parent && aabbBounds.transformWithMatrix((graphic.parent as IGroup).globalTransMatrix); application.graphicService.clearAABBBounds(graphic, graphic.stage, aabbBounds); aabbBounds.clear(); } From b293c4c30ef6688cc6b00cedbc97aba3f302a57a Mon Sep 17 00:00:00 2001 From: zhouxinyu Date: Sat, 12 Oct 2024 15:58:25 +0800 Subject: [PATCH 05/24] fix: group bounds valid check ignore visible --- .../src/graphic/graphic-service/graphic-service.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts b/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts index 115c94ba6..a184ff5bf 100644 --- a/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts +++ b/packages/vrender-core/src/graphic/graphic-service/graphic-service.ts @@ -370,7 +370,8 @@ export class DefaultGraphicService implements IGraphicService { return true; } - if (graphic.shadowRoot) { + // 是Group或者有影子节点的话,就直接认为是合法的 + if (graphic.shadowRoot || graphic.isContainer) { return true; } From db0155eee6037c41cd8f65c6f2bfac83a2a097bc Mon Sep 17 00:00:00 2001 From: neuqzxy Date: Wed, 16 Oct 2024 03:15:54 +0000 Subject: [PATCH 06/24] build: prelease version 0.21.0-alpha.2 --- common/config/rush/pnpm-lock.yaml | 26 +++++++++++------------ common/config/rush/version-policies.json | 2 +- docs/package.json | 2 +- packages/react-vrender-utils/package.json | 6 +++--- packages/react-vrender/package.json | 4 ++-- packages/vrender-components/package.json | 6 +++--- packages/vrender-core/package.json | 2 +- packages/vrender-kits/package.json | 4 ++-- packages/vrender/package.json | 6 +++--- tools/bugserver-trigger/package.json | 8 +++---- 10 files changed, 33 insertions(+), 33 deletions(-) diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 817588127..e96208e3f 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -14,7 +14,7 @@ importers: '@types/react-dom': ^18.0.0 '@visactor/vchart': 1.3.0 '@visactor/vgrammar': ~0.5.7 - '@visactor/vrender': workspace:0.20.9 + '@visactor/vrender': workspace:0.21.0-alpha.2 '@visactor/vutils': ~0.18.17 '@vitejs/plugin-react': 3.1.0 axios: ^1.4.0 @@ -71,7 +71,7 @@ importers: '@types/react': ^18.0.0 '@types/react-dom': ^18.0.0 '@types/react-reconciler': ^0.28.2 - '@visactor/vrender': workspace:0.20.9 + '@visactor/vrender': workspace:0.21.0-alpha.2 '@visactor/vutils': ~0.18.17 '@vitejs/plugin-react': 3.1.0 cross-env: ^7.0.3 @@ -111,8 +111,8 @@ importers: '@rushstack/eslint-patch': ~1.1.4 '@types/react': ^18.0.0 '@types/react-dom': ^18.0.0 - '@visactor/react-vrender': workspace:0.20.9 - '@visactor/vrender': workspace:0.20.9 + '@visactor/react-vrender': workspace:0.21.0-alpha.2 + '@visactor/vrender': workspace:0.21.0-alpha.2 '@visactor/vutils': ~0.18.17 '@vitejs/plugin-react': 3.1.0 cross-env: ^7.0.3 @@ -153,8 +153,8 @@ importers: '@types/jest': ^26.0.0 '@types/react': ^18.0.0 '@types/react-dom': ^18.0.0 - '@visactor/vrender-core': workspace:0.20.9 - '@visactor/vrender-kits': workspace:0.20.9 + '@visactor/vrender-core': workspace:0.21.0-alpha.2 + '@visactor/vrender-kits': workspace:0.21.0-alpha.2 '@visactor/vutils': ~0.18.17 '@vitejs/plugin-react': 3.1.0 canvas: 2.11.2 @@ -200,8 +200,8 @@ importers: '@internal/ts-config': workspace:* '@rushstack/eslint-patch': ~1.1.4 '@types/jest': ^26.0.0 - '@visactor/vrender-core': workspace:0.20.9 - '@visactor/vrender-kits': workspace:0.20.9 + '@visactor/vrender-core': workspace:0.21.0-alpha.2 + '@visactor/vrender-kits': workspace:0.21.0-alpha.2 '@visactor/vscale': ~0.18.17 '@visactor/vutils': ~0.18.17 cross-env: ^7.0.3 @@ -287,7 +287,7 @@ importers: '@types/node-fetch': 2.6.4 '@types/react': ^18.0.0 '@types/react-dom': ^18.0.0 - '@visactor/vrender-core': workspace:0.20.9 + '@visactor/vrender-core': workspace:0.21.0-alpha.2 '@visactor/vutils': ~0.18.17 '@vitejs/plugin-react': 3.1.0 canvas: 2.11.2 @@ -369,10 +369,10 @@ importers: '@rushstack/eslint-patch': ~1.1.4 '@types/node': '*' '@types/node-fetch': 2.6.4 - '@visactor/vrender': workspace:0.20.9 - '@visactor/vrender-components': workspace:0.20.9 - '@visactor/vrender-core': workspace:0.20.9 - '@visactor/vrender-kits': workspace:0.20.9 + '@visactor/vrender': workspace:0.21.0-alpha.2 + '@visactor/vrender-components': workspace:0.21.0-alpha.2 + '@visactor/vrender-core': workspace:0.21.0-alpha.2 + '@visactor/vrender-kits': workspace:0.21.0-alpha.2 cross-env: ^7.0.3 eslint: ~8.18.0 form-data: ~4.0.0 diff --git a/common/config/rush/version-policies.json b/common/config/rush/version-policies.json index b14988c71..abe6bf99f 100644 --- a/common/config/rush/version-policies.json +++ b/common/config/rush/version-policies.json @@ -1 +1 @@ -[{"definitionName":"lockStepVersion","policyName":"vrenderMain","version":"0.20.9","nextBump":"patch"}] +[{"definitionName":"lockStepVersion","policyName":"vrenderMain","version":"0.20.9","nextBump":"minor"}] diff --git a/docs/package.json b/docs/package.json index c73efafa9..048d719a9 100644 --- a/docs/package.json +++ b/docs/package.json @@ -13,7 +13,7 @@ "@visactor/vchart": "1.3.0", "@visactor/vutils": "~0.18.17", "@visactor/vgrammar": "~0.5.7", - "@visactor/vrender": "workspace:0.20.9", + "@visactor/vrender": "workspace:0.21.0-alpha.2", "markdown-it": "^13.0.0", "highlight.js": "^11.8.0", "axios": "^1.4.0", diff --git a/packages/react-vrender-utils/package.json b/packages/react-vrender-utils/package.json index 8bbdb1f6c..973a303d2 100644 --- a/packages/react-vrender-utils/package.json +++ b/packages/react-vrender-utils/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/react-vrender-utils", - "version": "0.20.9", + "version": "0.21.0-alpha.2", "description": "", "sideEffects": false, "main": "cjs/index.js", @@ -24,8 +24,8 @@ "react-dom": "^18.2.0" }, "dependencies": { - "@visactor/vrender": "workspace:0.20.9", - "@visactor/react-vrender": "workspace:0.20.9", + "@visactor/vrender": "workspace:0.21.0-alpha.2", + "@visactor/react-vrender": "workspace:0.21.0-alpha.2", "@visactor/vutils": "~0.18.17", "react-reconciler": "^0.29.0", "tslib": "^2.3.1" diff --git a/packages/react-vrender/package.json b/packages/react-vrender/package.json index e466816fe..46620f0f4 100644 --- a/packages/react-vrender/package.json +++ b/packages/react-vrender/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/react-vrender", - "version": "0.20.9", + "version": "0.21.0-alpha.2", "description": "", "sideEffects": false, "main": "cjs/index.js", @@ -23,7 +23,7 @@ "react": "^18.2.0" }, "dependencies": { - "@visactor/vrender": "workspace:0.20.9", + "@visactor/vrender": "workspace:0.21.0-alpha.2", "@visactor/vutils": "~0.18.17", "react-reconciler": "^0.29.0", "tslib": "^2.3.1" diff --git a/packages/vrender-components/package.json b/packages/vrender-components/package.json index b3f7b5994..d6240b0f6 100644 --- a/packages/vrender-components/package.json +++ b/packages/vrender-components/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/vrender-components", - "version": "0.20.9", + "version": "0.21.0-alpha.2", "description": "components library for dp visualization", "sideEffects": false, "main": "cjs/index.js", @@ -26,8 +26,8 @@ "dependencies": { "@visactor/vutils": "~0.18.17", "@visactor/vscale": "~0.18.17", - "@visactor/vrender-core": "workspace:0.20.9", - "@visactor/vrender-kits": "workspace:0.20.9" + "@visactor/vrender-core": "workspace:0.21.0-alpha.2", + "@visactor/vrender-kits": "workspace:0.21.0-alpha.2" }, "devDependencies": { "@internal/bundler": "workspace:*", diff --git a/packages/vrender-core/package.json b/packages/vrender-core/package.json index bc1fc2927..66d4e394c 100644 --- a/packages/vrender-core/package.json +++ b/packages/vrender-core/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/vrender-core", - "version": "0.20.9", + "version": "0.21.0-alpha.2", "description": "", "sideEffects": [ "./src/modules.ts", diff --git a/packages/vrender-kits/package.json b/packages/vrender-kits/package.json index f31c24184..d305fc310 100644 --- a/packages/vrender-kits/package.json +++ b/packages/vrender-kits/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/vrender-kits", - "version": "0.20.9", + "version": "0.21.0-alpha.2", "description": "", "sideEffects": false, "main": "cjs/index.js", @@ -21,7 +21,7 @@ }, "dependencies": { "@visactor/vutils": "~0.18.17", - "@visactor/vrender-core": "workspace:0.20.9", + "@visactor/vrender-core": "workspace:0.21.0-alpha.2", "@resvg/resvg-js": "2.4.1", "roughjs": "4.5.2" }, diff --git a/packages/vrender/package.json b/packages/vrender/package.json index fc16f3f3e..619b1d3f7 100644 --- a/packages/vrender/package.json +++ b/packages/vrender/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/vrender", - "version": "0.20.9", + "version": "0.21.0-alpha.2", "description": "", "sideEffects": true, "main": "cjs/index.js", @@ -24,8 +24,8 @@ "test-watch": "cross-env DEBUG_MODE=1 jest --watch" }, "dependencies": { - "@visactor/vrender-core": "workspace:0.20.9", - "@visactor/vrender-kits": "workspace:0.20.9" + "@visactor/vrender-core": "workspace:0.21.0-alpha.2", + "@visactor/vrender-kits": "workspace:0.21.0-alpha.2" }, "devDependencies": { "@internal/bundler": "workspace:*", diff --git a/tools/bugserver-trigger/package.json b/tools/bugserver-trigger/package.json index 84cee3fbe..9890f8277 100644 --- a/tools/bugserver-trigger/package.json +++ b/tools/bugserver-trigger/package.json @@ -8,10 +8,10 @@ "ci": "ts-node --transpileOnly --skipProject ./scripts/trigger-test.ts" }, "dependencies": { - "@visactor/vrender": "workspace:0.20.9", - "@visactor/vrender-core": "workspace:0.20.9", - "@visactor/vrender-kits": "workspace:0.20.9", - "@visactor/vrender-components": "workspace:0.20.9" + "@visactor/vrender": "workspace:0.21.0-alpha.2", + "@visactor/vrender-core": "workspace:0.21.0-alpha.2", + "@visactor/vrender-kits": "workspace:0.21.0-alpha.2", + "@visactor/vrender-components": "workspace:0.21.0-alpha.2" }, "devDependencies": { "@rushstack/eslint-patch": "~1.1.4", From 1ca4b7098b94febd7f380d30f95e6f9f76188fcf Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Wed, 13 Nov 2024 15:41:54 +0800 Subject: [PATCH 07/24] feat: add gifImage in vrender-components --- common/config/rush/pnpm-lock.yaml | 12 ++ .../__tests__/browser/examples/gif.ts | 49 +++++++ .../__tests__/browser/main.ts | 4 + .../__tests__/browser/sources/loading-1.gif | Bin 0 -> 11698 bytes .../__tests__/browser/sources/loading.gif | Bin 0 -> 10402 bytes packages/vrender-components/package.json | 3 +- packages/vrender-components/src/gif/gif.ts | 134 ++++++++++++++++++ packages/vrender-components/src/gif/index.ts | 1 + packages/vrender-components/src/index.ts | 1 + .../image-contribution-render.ts | 34 +++-- .../contributions/render/image-render.ts | 27 ++-- .../src/resource-loader/loader.ts | 4 +- 12 files changed, 239 insertions(+), 30 deletions(-) create mode 100644 packages/vrender-components/__tests__/browser/examples/gif.ts create mode 100644 packages/vrender-components/__tests__/browser/sources/loading-1.gif create mode 100644 packages/vrender-components/__tests__/browser/sources/loading.gif create mode 100644 packages/vrender-components/src/gif/gif.ts create mode 100644 packages/vrender-components/src/gif/index.ts diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index aa7b8c1cf..940b7ccec 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -206,6 +206,7 @@ importers: '@visactor/vutils': ~0.18.18 cross-env: ^7.0.3 eslint: ~8.18.0 + gifuct-js: 2.1.2 jest: ^26.0.0 jest-electron: ^0.1.12 lil-gui: ^0.17.0 @@ -217,6 +218,7 @@ importers: '@visactor/vrender-kits': link:../vrender-kits '@visactor/vscale': 0.18.18 '@visactor/vutils': 0.18.18 + gifuct-js: 2.1.2 devDependencies: '@internal/bundler': link:../../tools/bundler '@internal/eslint-config': link:../../share/eslint-config @@ -6348,6 +6350,12 @@ packages: assert-plus: 1.0.0 dev: true + /gifuct-js/2.1.2: + resolution: {integrity: sha512-rI2asw77u0mGgwhV3qA+OEgYqaDn5UNqgs+Bx0FGwSpuqfYn+Ir6RQY5ENNQ8SbIiG/m5gVa7CD5RriO4f4Lsg==} + dependencies: + js-binary-schema-parser: 2.0.3 + dev: false + /glob-parent/3.1.0: resolution: {integrity: sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==} dependencies: @@ -8261,6 +8269,10 @@ packages: - ts-node - utf-8-validate + /js-binary-schema-parser/2.0.3: + resolution: {integrity: sha512-xezGJmOb4lk/M1ZZLTR/jaBHQ4gG/lqQnJqdIv4721DMggsa1bDVlHXNeHYogaIEHD9vCRv0fcL4hMA+Coarkg==} + dev: false + /js-string-escape/1.0.1: resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==} engines: {node: '>= 0.8'} diff --git a/packages/vrender-components/__tests__/browser/examples/gif.ts b/packages/vrender-components/__tests__/browser/examples/gif.ts new file mode 100644 index 000000000..1169a0f37 --- /dev/null +++ b/packages/vrender-components/__tests__/browser/examples/gif.ts @@ -0,0 +1,49 @@ +import '@visactor/vrender'; +import render from '../../util/render'; +import { GifImage, IGifImageGraphicAttribute } from '../../../src'; + +export function run() { + const radios: GifImage[] = []; + + radios.push( + new GifImage({ + x: 100, + y: 100, + width: 50, + height: 50, + gifImage: './sources/loading.gif' + } as IGifImageGraphicAttribute) + ); + + radios.push( + new GifImage({ + x: 200, + y: 100, + width: 50, + height: 50, + gifImage: './sources/loading.gif' + } as IGifImageGraphicAttribute) + ); + + radios.push( + new GifImage({ + x: 100, + y: 200, + width: 50, + height: 50, + gifImage: './sources/loading-1.gif' + } as IGifImageGraphicAttribute) + ); + + radios.push( + new GifImage({ + x: 200, + y: 200, + width: 50, + height: 50, + gifImage: './sources/loading-1.gif' + } as IGifImageGraphicAttribute) + ); + + const stage = render(radios, 'main'); +} diff --git a/packages/vrender-components/__tests__/browser/main.ts b/packages/vrender-components/__tests__/browser/main.ts index 595d01510..d7a43b928 100644 --- a/packages/vrender-components/__tests__/browser/main.ts +++ b/packages/vrender-components/__tests__/browser/main.ts @@ -285,6 +285,10 @@ const specs = [ { path: 'timeline', name: 'timeline' + }, + { + path: 'gif', + name: 'gif' } ]; diff --git a/packages/vrender-components/__tests__/browser/sources/loading-1.gif b/packages/vrender-components/__tests__/browser/sources/loading-1.gif new file mode 100644 index 0000000000000000000000000000000000000000..20ac5cb44a0e62e1e8839c309f50f3204ce7e0b3 GIT binary patch literal 11698 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 literal 0 HcmV?d00001 diff --git a/packages/vrender-components/package.json b/packages/vrender-components/package.json index d6c23e0a1..ce8bbaba8 100644 --- a/packages/vrender-components/package.json +++ b/packages/vrender-components/package.json @@ -27,7 +27,8 @@ "@visactor/vutils": "~0.18.18", "@visactor/vscale": "~0.18.18", "@visactor/vrender-core": "workspace:0.20.12", - "@visactor/vrender-kits": "workspace:0.20.12" + "@visactor/vrender-kits": "workspace:0.20.12", + "gifuct-js": "2.1.2" }, "devDependencies": { "@internal/bundler": "workspace:*", diff --git a/packages/vrender-components/src/gif/gif.ts b/packages/vrender-components/src/gif/gif.ts new file mode 100644 index 000000000..e46b3fadc --- /dev/null +++ b/packages/vrender-components/src/gif/gif.ts @@ -0,0 +1,134 @@ +import type { IImageGraphicAttribute } from '@visactor/vrender-core'; +import { application, Image, ResourceLoader } from '@visactor/vrender-core'; +import type { ITimeline } from '@visactor/vrender-core'; +import { isString } from '@visactor/vutils'; +import type { ParsedFrame } from 'gifuct-js'; +import { decompressFrames, parseGIF } from 'gifuct-js'; + +export interface IGifImageGraphicAttribute extends IImageGraphicAttribute { + timeline?: ITimeline; + gifImage?: string | ArrayBuffer; +} + +export class GifImage extends Image { + declare attribute: IGifImageGraphicAttribute; + + frameImageData?: ImageData; + tempCanvas?: HTMLCanvasElement; + tempCtx?: CanvasRenderingContext2D; + gifCanvas?: HTMLCanvasElement; + gifCtx?: CanvasRenderingContext2D; + loadedFrames?: ParsedFrame[]; + frameIndex?: number; + playing?: boolean; + lastTime?: number; + + isGifImage = true; + + constructor(params: IGifImageGraphicAttribute) { + super(params); + + if (isString(this.attribute.gifImage)) { + ResourceLoader.GetFile(this.attribute.gifImage, 'arrayBuffer') + .then((res: ArrayBuffer) => { + const gif = parseGIF(res); + const frames = decompressFrames(gif, true); + this.renderGIF(frames); + }) + .catch(e => { + console.error('Gif load error: ', e); + }); + } else if (this.attribute.gifImage instanceof ArrayBuffer) { + const gif = parseGIF(this.attribute.gifImage); + const frames = decompressFrames(gif, true); + this.renderGIF(frames); + } + } + + renderGIF(frames: ParsedFrame[]) { + this.loadedFrames = frames; + this.frameIndex = 0; + + if (!this.tempCanvas) { + this.tempCanvas = application.global.createCanvas({}); + this.tempCtx = this.tempCanvas.getContext('2d'); + } + + if (!this.gifCanvas) { + this.gifCanvas = application.global.createCanvas({}); + this.gifCtx = this.gifCanvas.getContext('2d'); + } + + this.gifCanvas.width = frames[0].dims.width; + this.gifCanvas.height = frames[0].dims.height; + + this.playing = true; + this.lastTime = new Date().getTime(); + const animation = this.animate(); + if (this.attribute.timeline) { + animation.setTimeline(this.attribute.timeline); + } + animation.to({}, 1000, 'linear').loop(Infinity); + } + + renderFrame(context: CanvasRenderingContext2D, x: number, y: number) { + // get the frame + const frame = this.loadedFrames[this.frameIndex || 0]; + + if (frame.disposalType === 2) { + this.gifCtx.clearRect(0, 0, this.attribute.width, this.attribute.height); + } + + // draw image into gifCanvas + this.drawPatch(frame); + + // draw gifCanvas into stage + this.manipulate(context, x, y); + + // update the frame index + const diff = new Date().getTime() - this.lastTime; + if (frame.delay < diff) { + this.frameIndex++; + this.lastTime = new Date().getTime(); + } + if (this.frameIndex >= this.loadedFrames.length) { + this.frameIndex = 0; + } + } + + drawPatch(frame: ParsedFrame) { + const dims = frame.dims; + + if ( + !this.frameImageData || + dims.width !== this.frameImageData.width || + dims.height !== this.frameImageData.height + ) { + this.tempCanvas.width = dims.width; + this.tempCanvas.height = dims.height; + this.frameImageData = this.tempCtx.createImageData(dims.width, dims.height); + } + + // set the patch data as an override + this.frameImageData.data.set(frame.patch); + + // draw the patch back over the canvas + this.tempCtx.putImageData(this.frameImageData, 0, 0); + + this.gifCtx.drawImage(this.tempCanvas, dims.left, dims.top); + } + + manipulate(context: CanvasRenderingContext2D, x: number, y: number) { + context.drawImage( + this.gifCanvas, + 0, + 0, + this.gifCanvas.width, + this.gifCanvas.height, + x, + y, + this.attribute.width, + this.attribute.height + ); + } +} diff --git a/packages/vrender-components/src/gif/index.ts b/packages/vrender-components/src/gif/index.ts new file mode 100644 index 000000000..e595f706d --- /dev/null +++ b/packages/vrender-components/src/gif/index.ts @@ -0,0 +1 @@ +export * from './gif'; diff --git a/packages/vrender-components/src/index.ts b/packages/vrender-components/src/index.ts index 7e3f5da76..681a77ab0 100644 --- a/packages/vrender-components/src/index.ts +++ b/packages/vrender-components/src/index.ts @@ -29,3 +29,4 @@ export * from './checkbox'; export * from './radio'; export * from './empty-tip'; export * from './util'; +export * from './gif'; diff --git a/packages/vrender-core/src/render/contributions/render/contributions/image-contribution-render.ts b/packages/vrender-core/src/render/contributions/render/contributions/image-contribution-render.ts index 9fecb04a2..804645506 100644 --- a/packages/vrender-core/src/render/contributions/render/contributions/image-contribution-render.ts +++ b/packages/vrender-core/src/render/contributions/render/contributions/image-contribution-render.ts @@ -144,7 +144,7 @@ export class DefaultImageRenderContribution extends DefaultRectRenderContributio useStyle: boolean = true; order: number = 0; drawShape( - rect: any, + image: any, context: IContext2d, x: number, y: number, @@ -165,20 +165,24 @@ export class DefaultImageRenderContribution extends DefaultRectRenderContributio themeAttribute: IThemeAttribute ) => boolean ) { - return super.drawShape( - rect, - context, - x, - y, - doFill, - doStroke, - fVisible, - sVisible, - rectAttribute, - drawContext, - fillCb, - strokeCb - ); + if (image.isGifImage && image.renderFrame && image.playing) { + image.renderFrame(context, x, y); + } else { + return super.drawShape( + image, + context, + x, + y, + doFill, + doStroke, + fVisible, + sVisible, + rectAttribute, + drawContext, + fillCb, + strokeCb + ); + } } } diff --git a/packages/vrender-core/src/render/contributions/render/image-render.ts b/packages/vrender-core/src/render/contributions/render/image-render.ts index 71aaa4b17..8267d6911 100644 --- a/packages/vrender-core/src/render/contributions/render/image-render.ts +++ b/packages/vrender-core/src/render/contributions/render/image-render.ts @@ -162,18 +162,21 @@ export class DefaultCanvasImageRender extends BaseRender implements IGra draw(image: IImage, renderService: IRenderService, drawContext: IDrawContext) { const { image: url } = image.attribute; - if (!url || !image.resources) { - return; - } - const res = image.resources.get(url); - // if (res.state !== 'success') { - // return; - // } - if (res.state === 'loading' && isString(url)) { - ResourceLoader.improveImageLoading(url); - return; - } else if (res.state !== 'success') { - return; + + if (!image.isGifImage) { + if (!url || !image.resources) { + return; + } + const res = image.resources.get(url); + // if (res.state !== 'success') { + // return; + // } + if (res.state === 'loading' && isString(url)) { + ResourceLoader.improveImageLoading(url); + return; + } else if (res.state !== 'success') { + return; + } } const { context } = renderService.drawParams; diff --git a/packages/vrender-core/src/resource-loader/loader.ts b/packages/vrender-core/src/resource-loader/loader.ts index 55c779829..f40326744 100644 --- a/packages/vrender-core/src/resource-loader/loader.ts +++ b/packages/vrender-core/src/resource-loader/loader.ts @@ -108,9 +108,9 @@ export class ResourceLoader { let data = ResourceLoader.cache.get(url); if (data) { // 存在缓存 - if (data.loadState === 'init' || data.loadState === 'fail') { + if (data.loadState === 'fail') { return Promise.reject(); - } else if (data.loadState === 'loading') { + } else if (data.loadState === 'init' || data.loadState === 'loading') { return data.dataPromise.then(data => data.data); } return Promise.resolve(data.data); From 45b6b26727798c3ca6dac88436ee47549186451f Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Wed, 13 Nov 2024 17:10:07 +0800 Subject: [PATCH 08/24] docs: add disableAutoClipedPoptip in text documentation --- docs/assets/api/en/common/text.md | 4 ++++ docs/assets/api/zh/common/text.md | 4 ++++ docs/assets/option/en/common/text.md | 4 ++++ docs/assets/option/zh/common/text.md | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/docs/assets/api/en/common/text.md b/docs/assets/api/en/common/text.md index d28e2e8df..c21774b92 100644 --- a/docs/assets/api/en/common/text.md +++ b/docs/assets/api/en/common/text.md @@ -36,3 +36,7 @@ Roboto,Helvetica,Arial,sans-serif, apple color emoji,segoe ui emoji,segoe ui sym #${prefix} lineThrough(number) = 0 中划线线粗 + +#${prefix} disableAutoClipedPoptip(boolean) = false + +禁用省略hover展示poptip \ No newline at end of file diff --git a/docs/assets/api/zh/common/text.md b/docs/assets/api/zh/common/text.md index d28e2e8df..c21774b92 100644 --- a/docs/assets/api/zh/common/text.md +++ b/docs/assets/api/zh/common/text.md @@ -36,3 +36,7 @@ Roboto,Helvetica,Arial,sans-serif, apple color emoji,segoe ui emoji,segoe ui sym #${prefix} lineThrough(number) = 0 中划线线粗 + +#${prefix} disableAutoClipedPoptip(boolean) = false + +禁用省略hover展示poptip \ No newline at end of file diff --git a/docs/assets/option/en/common/text.md b/docs/assets/option/en/common/text.md index d28e2e8df..c21774b92 100644 --- a/docs/assets/option/en/common/text.md +++ b/docs/assets/option/en/common/text.md @@ -36,3 +36,7 @@ Roboto,Helvetica,Arial,sans-serif, apple color emoji,segoe ui emoji,segoe ui sym #${prefix} lineThrough(number) = 0 中划线线粗 + +#${prefix} disableAutoClipedPoptip(boolean) = false + +禁用省略hover展示poptip \ No newline at end of file diff --git a/docs/assets/option/zh/common/text.md b/docs/assets/option/zh/common/text.md index d28e2e8df..c21774b92 100644 --- a/docs/assets/option/zh/common/text.md +++ b/docs/assets/option/zh/common/text.md @@ -36,3 +36,7 @@ Roboto,Helvetica,Arial,sans-serif, apple color emoji,segoe ui emoji,segoe ui sym #${prefix} lineThrough(number) = 0 中划线线粗 + +#${prefix} disableAutoClipedPoptip(boolean) = false + +禁用省略hover展示poptip \ No newline at end of file From 2c6759e49c84e39b20b0b4346aaa89d78330d5b5 Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Wed, 13 Nov 2024 19:28:11 +0800 Subject: [PATCH 09/24] feat: add update in gif-image component --- packages/vrender-components/src/gif/gif.ts | 24 +++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/vrender-components/src/gif/gif.ts b/packages/vrender-components/src/gif/gif.ts index e46b3fadc..eac331cd1 100644 --- a/packages/vrender-components/src/gif/gif.ts +++ b/packages/vrender-components/src/gif/gif.ts @@ -1,4 +1,4 @@ -import type { IImageGraphicAttribute } from '@visactor/vrender-core'; +import type { IImageGraphicAttribute, ISetAttributeContext } from '@visactor/vrender-core'; import { application, Image, ResourceLoader } from '@visactor/vrender-core'; import type { ITimeline } from '@visactor/vrender-core'; import { isString } from '@visactor/vutils'; @@ -28,6 +28,10 @@ export class GifImage extends Image { constructor(params: IGifImageGraphicAttribute) { super(params); + this.loadGif(); + } + + loadGif() { if (isString(this.attribute.gifImage)) { ResourceLoader.GetFile(this.attribute.gifImage, 'arrayBuffer') .then((res: ArrayBuffer) => { @@ -131,4 +135,22 @@ export class GifImage extends Image { this.attribute.height ); } + + setAttribute(key: string, value: any, forceUpdateTag?: boolean, context?: ISetAttributeContext): void { + super.setAttribute(key, value, forceUpdateTag, context); + if (key === 'gifImage') { + this.loadGif(); + } + } + + setAttributes( + params: Partial, + forceUpdateTag?: boolean, + context?: ISetAttributeContext + ): void { + super.setAttributes(params, forceUpdateTag, context); + if (params.gifImage) { + this.loadGif(); + } + } } From 3a7e86df814da2450926a731b6c96fe55924e344 Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Wed, 13 Nov 2024 20:34:36 +0800 Subject: [PATCH 10/24] fix: fix gif-canvas clear in GifImage --- packages/vrender-components/src/gif/gif.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vrender-components/src/gif/gif.ts b/packages/vrender-components/src/gif/gif.ts index eac331cd1..0b10bddcc 100644 --- a/packages/vrender-components/src/gif/gif.ts +++ b/packages/vrender-components/src/gif/gif.ts @@ -80,7 +80,7 @@ export class GifImage extends Image { const frame = this.loadedFrames[this.frameIndex || 0]; if (frame.disposalType === 2) { - this.gifCtx.clearRect(0, 0, this.attribute.width, this.attribute.height); + this.gifCtx.clearRect(0, 0, this.gifCanvas.width, this.gifCanvas.height); } // draw image into gifCanvas From 9f1f39c2ffac5c1b1f1dfaf36d19fac382d01e09 Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Thu, 14 Nov 2024 15:44:14 +0800 Subject: [PATCH 11/24] feat: add animation & name in JSX --- packages/vrender-kits/src/jsx/jsx-classic.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/vrender-kits/src/jsx/jsx-classic.ts b/packages/vrender-kits/src/jsx/jsx-classic.ts index ad56ff823..f6ea0fdb2 100644 --- a/packages/vrender-kits/src/jsx/jsx-classic.ts +++ b/packages/vrender-kits/src/jsx/jsx-classic.ts @@ -10,7 +10,7 @@ function flatten(list: any, out: any[]): void { } export function jsx(type: string | any, config: Record, ...children: any) { - const { key, name, id, attribute, stateProxy, ...props } = config || {}; + const { key, name, id, attribute, stateProxy, animation, timeline, ...props } = config || {}; let c = type; if (isString(type)) { @@ -29,6 +29,22 @@ export function jsx(type: string | any, config: Record, ...children g.stateProxy = stateProxy; } + if (name) { + g.name = name; + } + + if (isArray(animation)) { + // animation={[ + // ['to', { angle: 2 * Math.PI }, 1000, 'linear'], + // ['loop', Infinity] + // ]} + const animate = g.animate(); + timeline && animate.setTimeline(timeline); + animation.forEach((item: any[]) => { + animate[item[0]](...item.slice(1)); + }); + } + return g; } From 7e6f13386404b038fb320403c22b283777911d14 Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Thu, 14 Nov 2024 16:34:01 +0800 Subject: [PATCH 12/24] chore: add rush change --- .../feat-gif-image_2024-11-14-08-33.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 common/changes/@visactor/vrender-components/feat-gif-image_2024-11-14-08-33.json diff --git a/common/changes/@visactor/vrender-components/feat-gif-image_2024-11-14-08-33.json b/common/changes/@visactor/vrender-components/feat-gif-image_2024-11-14-08-33.json new file mode 100644 index 000000000..beccac877 --- /dev/null +++ b/common/changes/@visactor/vrender-components/feat-gif-image_2024-11-14-08-33.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vrender-components", + "comment": "feat: add GifImage component", + "type": "none" + } + ], + "packageName": "@visactor/vrender-components" +} \ No newline at end of file From 6148c392efc22dccbb89fa6b07eaecf5cec3b3af Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Mon, 18 Nov 2024 14:47:11 +0800 Subject: [PATCH 13/24] feat: move GifImage from vrender-components to vrender-kits --- common/config/rush/pnpm-lock.yaml | 4 +- .../__tests__/browser/examples/gif.ts | 49 ---------- .../__tests__/browser/main.ts | 4 - packages/vrender-components/package.json | 3 +- packages/vrender-components/src/gif/index.ts | 1 - packages/vrender-components/src/index.ts | 1 - .../vrender-core/src/interface/graphic.ts | 3 +- .../image-contribution-render.ts | 32 +++---- .../contributions/render/image-render.ts | 26 +++--- packages/vrender-kits/package.json | 3 +- .../vrender-kits/src/graphic/constants.ts | 3 + .../src/graphic/gif-image.ts} | 18 ++-- packages/vrender-kits/src/index.ts | 4 + .../vrender-kits/src/interface/gif-image.ts | 19 ++++ .../canvas-picker/gif-image-module.ts | 14 +++ .../canvas-picker/gif-image-picker.ts | 31 +++++++ .../src/picker/contributions/constants.ts | 1 + .../contributions/canvas/gif-image-module.ts | 13 +++ .../contributions/canvas/gif-image-render.ts | 87 ++++++++++++++++++ .../__tests__/browser/sources/loading-1.gif | Bin 0 -> 11698 bytes .../__tests__/browser/sources/loading.gif | Bin 0 -> 10402 bytes .../__tests__/browser/src/pages/gif-image.ts | 64 +++++++++++++ .../__tests__/browser/src/pages/index.ts | 4 + 23 files changed, 282 insertions(+), 102 deletions(-) delete mode 100644 packages/vrender-components/__tests__/browser/examples/gif.ts delete mode 100644 packages/vrender-components/src/gif/index.ts create mode 100644 packages/vrender-kits/src/graphic/constants.ts rename packages/{vrender-components/src/gif/gif.ts => vrender-kits/src/graphic/gif-image.ts} (91%) create mode 100644 packages/vrender-kits/src/interface/gif-image.ts create mode 100644 packages/vrender-kits/src/picker/contributions/canvas-picker/gif-image-module.ts create mode 100644 packages/vrender-kits/src/picker/contributions/canvas-picker/gif-image-picker.ts create mode 100644 packages/vrender-kits/src/render/contributions/canvas/gif-image-module.ts create mode 100644 packages/vrender-kits/src/render/contributions/canvas/gif-image-render.ts create mode 100644 packages/vrender/__tests__/browser/sources/loading-1.gif create mode 100644 packages/vrender/__tests__/browser/sources/loading.gif create mode 100644 packages/vrender/__tests__/browser/src/pages/gif-image.ts diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 5dfdceee1..d8b047d61 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -206,7 +206,6 @@ importers: '@visactor/vutils': ~0.18.17 cross-env: ^7.0.3 eslint: ~8.18.0 - gifuct-js: 2.1.2 jest: ^26.0.0 jest-electron: ^0.1.12 lil-gui: ^0.17.0 @@ -218,7 +217,6 @@ importers: '@visactor/vrender-kits': link:../vrender-kits '@visactor/vscale': 0.18.18 '@visactor/vutils': 0.18.18 - gifuct-js: 2.1.2 devDependencies: '@internal/bundler': link:../../tools/bundler '@internal/eslint-config': link:../../share/eslint-config @@ -295,6 +293,7 @@ importers: canvas: 2.11.2 cross-env: ^7.0.3 eslint: ~8.18.0 + gifuct-js: 2.1.2 node-fetch: 2.6.6 react: ^18.0.0 react-dom: ^18.0.0 @@ -305,6 +304,7 @@ importers: '@resvg/resvg-js': 2.4.1 '@visactor/vrender-core': link:../vrender-core '@visactor/vutils': 0.18.18 + gifuct-js: 2.1.2 roughjs: 4.5.2 devDependencies: '@internal/bundler': link:../../tools/bundler diff --git a/packages/vrender-components/__tests__/browser/examples/gif.ts b/packages/vrender-components/__tests__/browser/examples/gif.ts deleted file mode 100644 index 1169a0f37..000000000 --- a/packages/vrender-components/__tests__/browser/examples/gif.ts +++ /dev/null @@ -1,49 +0,0 @@ -import '@visactor/vrender'; -import render from '../../util/render'; -import { GifImage, IGifImageGraphicAttribute } from '../../../src'; - -export function run() { - const radios: GifImage[] = []; - - radios.push( - new GifImage({ - x: 100, - y: 100, - width: 50, - height: 50, - gifImage: './sources/loading.gif' - } as IGifImageGraphicAttribute) - ); - - radios.push( - new GifImage({ - x: 200, - y: 100, - width: 50, - height: 50, - gifImage: './sources/loading.gif' - } as IGifImageGraphicAttribute) - ); - - radios.push( - new GifImage({ - x: 100, - y: 200, - width: 50, - height: 50, - gifImage: './sources/loading-1.gif' - } as IGifImageGraphicAttribute) - ); - - radios.push( - new GifImage({ - x: 200, - y: 200, - width: 50, - height: 50, - gifImage: './sources/loading-1.gif' - } as IGifImageGraphicAttribute) - ); - - const stage = render(radios, 'main'); -} diff --git a/packages/vrender-components/__tests__/browser/main.ts b/packages/vrender-components/__tests__/browser/main.ts index d7a43b928..595d01510 100644 --- a/packages/vrender-components/__tests__/browser/main.ts +++ b/packages/vrender-components/__tests__/browser/main.ts @@ -285,10 +285,6 @@ const specs = [ { path: 'timeline', name: 'timeline' - }, - { - path: 'gif', - name: 'gif' } ]; diff --git a/packages/vrender-components/package.json b/packages/vrender-components/package.json index 8a42021ba..d6240b0f6 100644 --- a/packages/vrender-components/package.json +++ b/packages/vrender-components/package.json @@ -27,8 +27,7 @@ "@visactor/vutils": "~0.18.17", "@visactor/vscale": "~0.18.17", "@visactor/vrender-core": "workspace:0.21.0-alpha.2", - "@visactor/vrender-kits": "workspace:0.21.0-alpha.2", - "gifuct-js": "2.1.2" + "@visactor/vrender-kits": "workspace:0.21.0-alpha.2" }, "devDependencies": { "@internal/bundler": "workspace:*", diff --git a/packages/vrender-components/src/gif/index.ts b/packages/vrender-components/src/gif/index.ts deleted file mode 100644 index e595f706d..000000000 --- a/packages/vrender-components/src/gif/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './gif'; diff --git a/packages/vrender-components/src/index.ts b/packages/vrender-components/src/index.ts index 681a77ab0..7e3f5da76 100644 --- a/packages/vrender-components/src/index.ts +++ b/packages/vrender-components/src/index.ts @@ -29,4 +29,3 @@ export * from './checkbox'; export * from './radio'; export * from './empty-tip'; export * from './util'; -export * from './gif'; diff --git a/packages/vrender-core/src/interface/graphic.ts b/packages/vrender-core/src/interface/graphic.ts index 63279cd60..10c59a413 100644 --- a/packages/vrender-core/src/interface/graphic.ts +++ b/packages/vrender-core/src/interface/graphic.ts @@ -38,7 +38,8 @@ export type GraphicType = | 'shadowroot' | 'polygon' | 'pyramid3d' - | 'glyph'; + | 'glyph' + | string; // Cursor style // See: https://developer.mozilla.org/en-US/docs/Web/CSS/cursor diff --git a/packages/vrender-core/src/render/contributions/render/contributions/image-contribution-render.ts b/packages/vrender-core/src/render/contributions/render/contributions/image-contribution-render.ts index 804645506..84158e633 100644 --- a/packages/vrender-core/src/render/contributions/render/contributions/image-contribution-render.ts +++ b/packages/vrender-core/src/render/contributions/render/contributions/image-contribution-render.ts @@ -165,24 +165,20 @@ export class DefaultImageRenderContribution extends DefaultRectRenderContributio themeAttribute: IThemeAttribute ) => boolean ) { - if (image.isGifImage && image.renderFrame && image.playing) { - image.renderFrame(context, x, y); - } else { - return super.drawShape( - image, - context, - x, - y, - doFill, - doStroke, - fVisible, - sVisible, - rectAttribute, - drawContext, - fillCb, - strokeCb - ); - } + return super.drawShape( + image, + context, + x, + y, + doFill, + doStroke, + fVisible, + sVisible, + rectAttribute, + drawContext, + fillCb, + strokeCb + ); } } diff --git a/packages/vrender-core/src/render/contributions/render/image-render.ts b/packages/vrender-core/src/render/contributions/render/image-render.ts index 8267d6911..6c0316b9f 100644 --- a/packages/vrender-core/src/render/contributions/render/image-render.ts +++ b/packages/vrender-core/src/render/contributions/render/image-render.ts @@ -163,20 +163,18 @@ export class DefaultCanvasImageRender extends BaseRender implements IGra draw(image: IImage, renderService: IRenderService, drawContext: IDrawContext) { const { image: url } = image.attribute; - if (!image.isGifImage) { - if (!url || !image.resources) { - return; - } - const res = image.resources.get(url); - // if (res.state !== 'success') { - // return; - // } - if (res.state === 'loading' && isString(url)) { - ResourceLoader.improveImageLoading(url); - return; - } else if (res.state !== 'success') { - return; - } + if (!url || !image.resources) { + return; + } + const res = image.resources.get(url); + // if (res.state !== 'success') { + // return; + // } + if (res.state === 'loading' && isString(url)) { + ResourceLoader.improveImageLoading(url); + return; + } else if (res.state !== 'success') { + return; } const { context } = renderService.drawParams; diff --git a/packages/vrender-kits/package.json b/packages/vrender-kits/package.json index d305fc310..e825118fd 100644 --- a/packages/vrender-kits/package.json +++ b/packages/vrender-kits/package.json @@ -23,7 +23,8 @@ "@visactor/vutils": "~0.18.17", "@visactor/vrender-core": "workspace:0.21.0-alpha.2", "@resvg/resvg-js": "2.4.1", - "roughjs": "4.5.2" + "roughjs": "4.5.2", + "gifuct-js": "2.1.2" }, "devDependencies": { "@internal/bundler": "workspace:*", diff --git a/packages/vrender-kits/src/graphic/constants.ts b/packages/vrender-kits/src/graphic/constants.ts new file mode 100644 index 000000000..c234ac0eb --- /dev/null +++ b/packages/vrender-kits/src/graphic/constants.ts @@ -0,0 +1,3 @@ +import { Generator } from '@visactor/vrender-core'; + +export const GIFIMAGE_NUMBER_TYPE = Generator.GenAutoIncrementId(); diff --git a/packages/vrender-components/src/gif/gif.ts b/packages/vrender-kits/src/graphic/gif-image.ts similarity index 91% rename from packages/vrender-components/src/gif/gif.ts rename to packages/vrender-kits/src/graphic/gif-image.ts index 0b10bddcc..2e930233d 100644 --- a/packages/vrender-components/src/gif/gif.ts +++ b/packages/vrender-kits/src/graphic/gif-image.ts @@ -4,13 +4,11 @@ import type { ITimeline } from '@visactor/vrender-core'; import { isString } from '@visactor/vutils'; import type { ParsedFrame } from 'gifuct-js'; import { decompressFrames, parseGIF } from 'gifuct-js'; +import type { IGifImage, IGifImageGraphicAttribute } from '../interface/gif-image'; +import { GIFIMAGE_NUMBER_TYPE } from './constants'; -export interface IGifImageGraphicAttribute extends IImageGraphicAttribute { - timeline?: ITimeline; - gifImage?: string | ArrayBuffer; -} - -export class GifImage extends Image { +export class GifImage extends Image implements IGifImage { + type: any = 'gif-image'; declare attribute: IGifImageGraphicAttribute; frameImageData?: ImageData; @@ -23,11 +21,9 @@ export class GifImage extends Image { playing?: boolean; lastTime?: number; - isGifImage = true; - constructor(params: IGifImageGraphicAttribute) { super(params); - + this.numberType = GIFIMAGE_NUMBER_TYPE; this.loadGif(); } @@ -154,3 +150,7 @@ export class GifImage extends Image { } } } + +export function createGifImage(attributes: IGifImageGraphicAttribute): IGifImage { + return new GifImage(attributes); +} diff --git a/packages/vrender-kits/src/index.ts b/packages/vrender-kits/src/index.ts index 9a24112ec..6b68fef67 100644 --- a/packages/vrender-kits/src/index.ts +++ b/packages/vrender-kits/src/index.ts @@ -51,6 +51,10 @@ export * from './picker/contributions/canvas-picker/arc3d-module'; export * from './picker/contributions/canvas-picker/pyramid3d-module'; +export * from './graphic/gif-image'; +export * from './picker/contributions/canvas-picker/gif-image-module'; +export * from './render/contributions/canvas/gif-image-module'; + export * from './register/register-arc'; export * from './register/register-arc3d'; export * from './register/register-area'; diff --git a/packages/vrender-kits/src/interface/gif-image.ts b/packages/vrender-kits/src/interface/gif-image.ts new file mode 100644 index 000000000..891c3dbde --- /dev/null +++ b/packages/vrender-kits/src/interface/gif-image.ts @@ -0,0 +1,19 @@ +import type { IGraphic, IImageGraphicAttribute, ITimeline } from '@visactor/vrender-core'; +import type { ParsedFrame } from 'gifuct-js'; + +export interface IGifImageGraphicAttribute extends IImageGraphicAttribute { + timeline?: ITimeline; + gifImage?: string | ArrayBuffer; +} + +export interface IGifImage extends IGraphic { + frameImageData?: ImageData; + tempCanvas?: HTMLCanvasElement; + tempCtx?: CanvasRenderingContext2D; + gifCanvas?: HTMLCanvasElement; + gifCtx?: CanvasRenderingContext2D; + loadedFrames?: ParsedFrame[]; + frameIndex?: number; + playing?: boolean; + lastTime?: number; +} diff --git a/packages/vrender-kits/src/picker/contributions/canvas-picker/gif-image-module.ts b/packages/vrender-kits/src/picker/contributions/canvas-picker/gif-image-module.ts new file mode 100644 index 000000000..755c5eec0 --- /dev/null +++ b/packages/vrender-kits/src/picker/contributions/canvas-picker/gif-image-module.ts @@ -0,0 +1,14 @@ +import { ContainerModule } from '@visactor/vrender-core'; +import { CanvasGifImagePicker, CanvasPickerContribution } from '../constants'; +import { DefaultCanvasGifImagePicker } from './gif-image-picker'; + +let loadGifImagePick = false; +export const gifImageCanvasPickModule = new ContainerModule((bind, unbind, isBound, rebind) => { + if (loadGifImagePick) { + return; + } + loadGifImagePick = true; + // gifGifImage picker + bind(CanvasGifImagePicker).to(DefaultCanvasGifImagePicker).inSingletonScope(); + bind(CanvasPickerContribution).toService(CanvasGifImagePicker); +}); diff --git a/packages/vrender-kits/src/picker/contributions/canvas-picker/gif-image-picker.ts b/packages/vrender-kits/src/picker/contributions/canvas-picker/gif-image-picker.ts new file mode 100644 index 000000000..4a7634db5 --- /dev/null +++ b/packages/vrender-kits/src/picker/contributions/canvas-picker/gif-image-picker.ts @@ -0,0 +1,31 @@ +import type { IPoint } from '@visactor/vutils'; +import { injectable } from '@visactor/vrender-core'; +import type { IGraphicPicker, IPickParams } from '@visactor/vrender-core'; +import type { IGifImage } from '../../../interface/gif-image'; +import { GIFIMAGE_NUMBER_TYPE } from '../../../graphic/constants'; + +@injectable() +export class DefaultCanvasGifImagePicker implements IGraphicPicker { + type: string = 'gif-image'; + numberType: number = GIFIMAGE_NUMBER_TYPE; + + contains(gifImage: IGifImage, point: IPoint, params?: IPickParams): boolean { + // const { gifImageAttribute } = graphicService.themeService.getCurrentTheme(); + // const { + // x = gifImageAttribute.x, + // y = gifImageAttribute.y, + // } = gifImage.attribute; + + const { pickContext } = params ?? {}; + if (!pickContext) { + return false; + } + + if (!gifImage.AABBBounds.containsPoint(point)) { + return false; + } + + // TODO: 详细形状判断 + return true; + } +} diff --git a/packages/vrender-kits/src/picker/contributions/constants.ts b/packages/vrender-kits/src/picker/contributions/constants.ts index 4ce53d35b..f2c09d01f 100644 --- a/packages/vrender-kits/src/picker/contributions/constants.ts +++ b/packages/vrender-kits/src/picker/contributions/constants.ts @@ -19,6 +19,7 @@ export const CanvasArc3dPicker = Symbol.for('CanvasArc3dPicker'); export const CanvasAreaPicker = Symbol.for('CanvasAreaPicker'); export const CanvasCirclePicker = Symbol.for('CanvasCirclePicker'); export const CanvasImagePicker = Symbol.for('CanvasImagePicker'); +export const CanvasGifImagePicker = Symbol.for('CanvasGifImagePicker'); export const CanvasLinePicker = Symbol.for('CanvasLinePicker'); export const CanvasPathPicker = Symbol.for('CanvasPathPicker'); export const CanvasRectPicker = Symbol.for('CanvasRectPicker'); diff --git a/packages/vrender-kits/src/render/contributions/canvas/gif-image-module.ts b/packages/vrender-kits/src/render/contributions/canvas/gif-image-module.ts new file mode 100644 index 000000000..be568f750 --- /dev/null +++ b/packages/vrender-kits/src/render/contributions/canvas/gif-image-module.ts @@ -0,0 +1,13 @@ +import { ContainerModule, GraphicRender } from '@visactor/vrender-core'; +import { DefaultCanvasGifImageRender } from './gif-image-render'; + +let loadGifImageModule = false; +export const gifImageModule = new ContainerModule(bind => { + if (loadGifImageModule) { + return; + } + loadGifImageModule = true; + // gifImage渲染器 + bind(DefaultCanvasGifImageRender).toSelf().inSingletonScope(); + bind(GraphicRender).toService(DefaultCanvasGifImageRender); +}); diff --git a/packages/vrender-kits/src/render/contributions/canvas/gif-image-render.ts b/packages/vrender-kits/src/render/contributions/canvas/gif-image-render.ts new file mode 100644 index 000000000..d65f4976f --- /dev/null +++ b/packages/vrender-kits/src/render/contributions/canvas/gif-image-render.ts @@ -0,0 +1,87 @@ +import type { + IContext2d, + IContributionProvider, + IDrawContext, + IGraphicAttribute, + IGraphicRender, + IImageRenderContribution, + IMarkAttribute, + IRenderService, + IThemeAttribute +} from '@visactor/vrender-core'; +import { + BaseRenderContributionTime, + ContributionProvider, + DefaultCanvasImageRender, + DefaultRectRenderContribution, + getTheme, + ImageRenderContribution, + inject, + injectable, + named +} from '@visactor/vrender-core'; +import { GIFIMAGE_NUMBER_TYPE } from '../../../graphic/constants'; +import type { IGifImage } from '../../../interface/gif-image'; + +@injectable() +export class DefaultCanvasGifImageRender extends DefaultCanvasImageRender implements IGraphicRender { + type: 'image'; + numberType: number = GIFIMAGE_NUMBER_TYPE; + + constructor( + @inject(ContributionProvider) + @named(ImageRenderContribution) + protected readonly imageRenderContribitions: IContributionProvider + ) { + super(imageRenderContribitions); + this._renderContribitions = undefined; + this.builtinContributions = [defaultGifImageRenderContribution]; + this.init(imageRenderContribitions); + } + + draw(image: IGifImage, renderService: IRenderService, drawContext: IDrawContext) { + const { context } = renderService.drawParams; + if (!context) { + return; + } + const imageAttribute = getTheme(image).image; + this._draw(image, imageAttribute, false, drawContext); + } +} + +export class DefaultGifImageRenderContribution + extends DefaultRectRenderContribution + implements IImageRenderContribution +{ + time: BaseRenderContributionTime = BaseRenderContributionTime.afterFillStroke; + useStyle: boolean = true; + order: number = 0; + drawShape( + image: any, + context: IContext2d, + x: number, + y: number, + doFill: boolean, + doStroke: boolean, + fVisible: boolean, + sVisible: boolean, + rectAttribute: any, + drawContext: IDrawContext, + fillCb?: ( + ctx: IContext2d, + markAttribute: Partial, + themeAttribute: IThemeAttribute + ) => boolean, + strokeCb?: ( + ctx: IContext2d, + markAttribute: Partial, + themeAttribute: IThemeAttribute + ) => boolean + ) { + if (image.renderFrame && image.playing) { + image.renderFrame(context, x, y); + } + } +} + +export const defaultGifImageRenderContribution = new DefaultGifImageRenderContribution(); diff --git a/packages/vrender/__tests__/browser/sources/loading-1.gif b/packages/vrender/__tests__/browser/sources/loading-1.gif new file mode 100644 index 0000000000000000000000000000000000000000..20ac5cb44a0e62e1e8839c309f50f3204ce7e0b3 GIT binary patch literal 11698 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 literal 0 HcmV?d00001 diff --git a/packages/vrender/__tests__/browser/src/pages/gif-image.ts b/packages/vrender/__tests__/browser/src/pages/gif-image.ts new file mode 100644 index 000000000..8900d5098 --- /dev/null +++ b/packages/vrender/__tests__/browser/src/pages/gif-image.ts @@ -0,0 +1,64 @@ +import { createStage, container } from '@visactor/vrender-core'; +import { GifImage, IGifImageGraphicAttribute, gifImageModule, gifImageCanvasPickModule } from '@visactor/vrender-kits'; +import { addShapesToStage, colorPools } from '../utils'; + +container.load(gifImageModule); +container.load(gifImageCanvasPickModule); + +export const page = () => { + const shapes = []; + shapes.push( + new GifImage({ + x: 100, + y: 100, + width: 50, + height: 50, + gifImage: './sources/loading.gif' + } as IGifImageGraphicAttribute) + ); + + shapes.push( + new GifImage({ + x: 200, + y: 100, + width: 50, + height: 50, + gifImage: './sources/loading.gif' + } as IGifImageGraphicAttribute) + ); + + shapes.push( + new GifImage({ + x: 100, + y: 200, + width: 50, + height: 50, + gifImage: './sources/loading-1.gif' + } as IGifImageGraphicAttribute) + ); + + shapes.push( + new GifImage({ + x: 200, + y: 200, + width: 50, + height: 50, + gifImage: './sources/loading-1.gif' + } as IGifImageGraphicAttribute) + ); + + const stage = createStage({ + canvas: 'main', + width: 1200, + height: 600, + viewWidth: 1200, + viewHeight: 600 + }); + + addShapesToStage(stage, shapes as any, true); + stage.render(); + + stage.addEventListener('click', e => { + console.log('target', e.target); + }); +}; diff --git a/packages/vrender/__tests__/browser/src/pages/index.ts b/packages/vrender/__tests__/browser/src/pages/index.ts index 8eff30472..2fed4b3de 100644 --- a/packages/vrender/__tests__/browser/src/pages/index.ts +++ b/packages/vrender/__tests__/browser/src/pages/index.ts @@ -190,6 +190,10 @@ export const pages = [ { name: 'react', path: 'react' + }, + { + name: 'gif-image', + path: 'gif-image' } ] }, From cb98cd9be4c6e46598d9087cedc8b1f255ddf96c Mon Sep 17 00:00:00 2001 From: zhouxinyu Date: Mon, 30 Dec 2024 17:40:41 +0800 Subject: [PATCH 14/24] fix: fix issue with animate error when graphic.stage is null --- .../fix-animate-with-noStage_2024-12-30-09-41.json | 10 ++++++++++ packages/vrender-core/src/animate/animate.ts | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 common/changes/@visactor/vrender-core/fix-animate-with-noStage_2024-12-30-09-41.json diff --git a/common/changes/@visactor/vrender-core/fix-animate-with-noStage_2024-12-30-09-41.json b/common/changes/@visactor/vrender-core/fix-animate-with-noStage_2024-12-30-09-41.json new file mode 100644 index 000000000..1e808ce1b --- /dev/null +++ b/common/changes/@visactor/vrender-core/fix-animate-with-noStage_2024-12-30-09-41.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vrender-core", + "comment": "fix: fix issue with animate error when graphic.stage is null", + "type": "none" + } + ], + "packageName": "@visactor/vrender-core" +} \ No newline at end of file diff --git a/packages/vrender-core/src/animate/animate.ts b/packages/vrender-core/src/animate/animate.ts index 84d42484c..7edd14f34 100644 --- a/packages/vrender-core/src/animate/animate.ts +++ b/packages/vrender-core/src/animate/animate.ts @@ -200,7 +200,7 @@ export class Animate implements IAnimate { slience?: boolean ) { this.id = id; - this.timeline = timeline; + this.timeline = timeline || defaultTimeline; this.status = AnimateStatus.INITIAL; this.tailAnimate = new SubAnimate(this); this.subAnimates = [this.tailAnimate]; From a766717fa9a0b49e809ccc6f28862d1e5802a686 Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Mon, 6 Jan 2025 17:15:37 +0800 Subject: [PATCH 15/24] chore: update merge request --- .../fix-visible-bounds_2024-09-29-08-30.json | 10 ---------- common/config/rush/pnpm-lock.yaml | 1 + .../__tests__/browser/sources/loading-1.gif | Bin 11698 -> 0 bytes .../__tests__/browser/sources/loading.gif | Bin 10402 -> 0 bytes 4 files changed, 1 insertion(+), 10 deletions(-) delete mode 100644 common/changes/@visactor/vrender-core/fix-visible-bounds_2024-09-29-08-30.json delete mode 100644 packages/vrender-components/__tests__/browser/sources/loading-1.gif delete mode 100644 packages/vrender-components/__tests__/browser/sources/loading.gif diff --git a/common/changes/@visactor/vrender-core/fix-visible-bounds_2024-09-29-08-30.json b/common/changes/@visactor/vrender-core/fix-visible-bounds_2024-09-29-08-30.json deleted file mode 100644 index e590b282f..000000000 --- a/common/changes/@visactor/vrender-core/fix-visible-bounds_2024-09-29-08-30.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "changes": [ - { - "packageName": "@visactor/vrender-core", - "comment": "fix: fix issue with dirtyBounds incorrectly while set visible", - "type": "none" - } - ], - "packageName": "@visactor/vrender-core" -} \ No newline at end of file diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 81634baa3..d2f963e62 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -304,6 +304,7 @@ importers: '@resvg/resvg-js': 2.4.1 '@visactor/vrender-core': link:../vrender-core '@visactor/vutils': 0.19.3 + gifuct-js: 2.1.2 roughjs: 4.5.2 devDependencies: '@internal/bundler': link:../../tools/bundler diff --git a/packages/vrender-components/__tests__/browser/sources/loading-1.gif b/packages/vrender-components/__tests__/browser/sources/loading-1.gif deleted file mode 100644 index 20ac5cb44a0e62e1e8839c309f50f3204ce7e0b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11698 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 From 783f76dd8e6e11d750886155d7f6c507538f7d09 Mon Sep 17 00:00:00 2001 From: xile611 Date: Mon, 6 Jan 2025 18:34:30 +0800 Subject: [PATCH 16/24] docs: add comments for graphic --- .../src/legend/discrete/type.ts | 24 ++- packages/vrender-core/src/interface/color.ts | 13 ++ .../vrender-core/src/interface/graphic.ts | 152 +++++++++++++++--- 3 files changed, 168 insertions(+), 21 deletions(-) diff --git a/packages/vrender-components/src/legend/discrete/type.ts b/packages/vrender-components/src/legend/discrete/type.ts index d31475a3d..ebe5df2d8 100644 --- a/packages/vrender-components/src/legend/discrete/type.ts +++ b/packages/vrender-components/src/legend/discrete/type.ts @@ -34,6 +34,9 @@ export interface LegendSwitchComponentAttributes { animationEasing?: EasingType; } +/** + * 离散类型的图例组件,当图例项较多的时候,默认使用分页器组件 + */ export type LegendPagerAttributes = Omit & LegendSwitchComponentAttributes & { /** @@ -43,8 +46,14 @@ export type LegendPagerAttributes = Omit & position?: 'start' | 'middle' | 'end'; }; +/** + * 离散类型的图例组件使用滚动条组件的时候对应的配置 + */ export type LegendScrollbarAttributes = Omit & LegendSwitchComponentAttributes & { + /** + * 申明图例组件使用滚动条进行翻页展示更多的图例项 + */ type: 'scrollbar'; /** * @deprecated since 0.20.13 @@ -222,7 +231,10 @@ export type DiscreteLegendAttrs = { select?: | boolean | { - /** @since 0.20.13 */ + /** + * 触发选中交互的事件类型 + * @since 0.20.13 + **/ trigger?: GraphicEventType; }; @@ -232,9 +244,15 @@ export type DiscreteLegendAttrs = { hover?: | boolean | { - /** @since 0.20.13 */ + /** + * 触发hover交互的事件类型 + * @since 0.20.13 + **/ trigger?: GraphicEventType; - /** @since 0.20.13 */ + /** + * 触发取消hover交互的事件类型 + * @since 0.20.13 + **/ triggerOff?: GraphicEventType; }; /** diff --git a/packages/vrender-core/src/interface/color.ts b/packages/vrender-core/src/interface/color.ts index e824440d8..7c9635d71 100644 --- a/packages/vrender-core/src/interface/color.ts +++ b/packages/vrender-core/src/interface/color.ts @@ -5,6 +5,9 @@ interface IGradientStop { export type IGradientColor = ILinearGradient | IRadialGradient | IConicalGradient; +/** + * 线性渐变色 + */ export interface ILinearGradient { gradient: 'linear'; x0?: number; @@ -14,6 +17,9 @@ export interface ILinearGradient { stops: IGradientStop[]; } +/** + * 径向渐变色 + */ export interface IRadialGradient { gradient: 'radial'; x0?: number; @@ -25,6 +31,9 @@ export interface IRadialGradient { stops: IGradientStop[]; } +/** + * 环形渐变色/锥形渐变色 + */ export interface IConicalGradient { gradient: 'conical'; startAngle?: number; @@ -39,4 +48,8 @@ export interface IColorStop { color: string; } +/** + * 颜色类型, + * 支持字符串、线性渐变、径向渐变、锥形渐变 + */ export type IColor = string | ILinearGradient | IRadialGradient | IConicalGradient; diff --git a/packages/vrender-core/src/interface/graphic.ts b/packages/vrender-core/src/interface/graphic.ts index 6781ff69a..0eaf540b8 100644 --- a/packages/vrender-core/src/interface/graphic.ts +++ b/packages/vrender-core/src/interface/graphic.ts @@ -13,10 +13,19 @@ import type { IFace3d } from './graphic/face3d'; import type { IPickerService } from './picker'; type IStrokeSeg = { - start: number; // 百分比 - // end和length二选一 - end: number; // 百分比 - length: number; // 像素长度 + /** + * 百分比 + */ + start: number; + /** + * 百分比 + * end和length二选一 + */ + end: number; + /** + * 像素长度 + */ + length: number; }; // TODO 最后加一个any @@ -103,11 +112,29 @@ export type ITransform = { export type IFillType = boolean | string | IColor; export type IFillStyle = { + /** + * 图形的填充透明度 + */ fillOpacity: number; + /** + * 图形模糊效果程度 + */ shadowBlur: number; + /** + * 图形的阴影颜色 + */ shadowColor: string; + /** + * 阴影水平偏移距离 + */ shadowOffsetX: number; + /** + * 阴影垂直偏移距离 + */ shadowOffsetY: number; + /** + * 图形的填充颜色 + */ fill: IFillType; }; @@ -122,8 +149,17 @@ export type IBorderStyle = Omit & { export type IStrokeType = boolean | string | IColor | null; export type IStrokeStyle = { + /** + * 外部边框的样式配置,默认不展示外部边框 + */ outerBorder: Partial; + /** + * 内部边框的样式配置 + */ innerBorder: Partial; + /** + * 描边的透明度 + */ strokeOpacity: number; lineDash: number[]; lineDashOffset: number; @@ -131,7 +167,9 @@ export type IStrokeStyle = { lineCap: CanvasLineCap; lineJoin: CanvasLineJoin; miterLimit: number; - // 描边的boundsBuffer,用于控制bounds的buffer + /** + * 描边的boundsBuffer,用于控制bounds的buffer + */ strokeBoundsBuffer: number; /** * stroke - true 全描边 @@ -156,8 +194,13 @@ export type IStrokeStyle = { type TextureType = 'circle' | 'diamond' | 'rect' | 'vertical-line' | 'horizontal-line' | 'bias-lr' | 'bias-rl' | 'grid'; export type IConnectedStyle = { - // 连接,取零或者断开 + /** + * 连接,取零或者断开 + */ connectedType: 'connect' | 'zero' | 'none'; + /** + * 连接线的样式配置 + */ connectedStyle: { stroke: IStrokeStyle['stroke']; strokeOpacity: IStrokeStyle['strokeOpacity']; @@ -212,40 +255,94 @@ export type IGraphicStyle = ILayout & IFillStyle & IStrokeStyle & IPickStyle & { + /** + * 强制设置的bounds宽度,主要用于使用html或者react展示图形的时候,设置一个固定的宽度 + */ forceBoundsWidth: number | (() => number) | undefined; + /** + * 强制设置的bounds高度,主要用于使用html或者react展示图形的时候,设置一个固定的高度 + */ forceBoundsHeight: number | (() => number) | undefined; + /** + * 透明度,会同时影响填充和描边 + */ opacity: number; shadowGraphic?: IGraphic | undefined; backgroundMode: 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat'; // 填充模式(与具体图元有关) backgroundFit: boolean; // 是否正好填充,只在repeat-x或者repeat-y以及no-repeat的时候生效 backgroundCornerRadius: number | number[]; backgroundOpacity: number; + /** + * 背景,支持颜色字符串、html image元素、html canvas元素 + */ background: | IBackgroundType | { + /** + * 背景,支持颜色字符串、html image元素、html canvas元素 + */ background: IBackgroundType; + /** + * 背景的x方向偏移量 + */ dx?: number; + /** + * 背景的y方向偏移量 + */ dy?: number; + /** + * 背景宽度 + */ width?: number; + /** + * 背景高度 + */ height?: number; + /** + * 背景的x坐标 + */ x?: number; + /** + * 背景的y坐标 + */ y?: number; } | null; // 背景,可以与fill同时存在 - texture: TextureType | string; // 纹理 - textureColor: string; // 纹理颜色 - textureSize: number; // 纹理大小 - texturePadding: number; // 纹理间隙 + /** + * 纹理的类型 + */ + texture: TextureType | string; + /** + * 纹理的颜色 + */ + textureColor: string; + /** + * 纹理的大小 + */ + textureSize: number; + /** + * 纹理的间隙 + */ + texturePadding: number; + blur: number; - cursor: Cursor | null; // 鼠标样式 + /** + * 设置图形对应的鼠标样式 + */ + cursor: Cursor | null; renderStyle?: 'default' | 'rough' | any; - // HTML的dom或者string + /** + * HTML的dom或者string + */ html: | ({ dom: string | HTMLElement; // dom字符串或者dom } & SimpleDomStyleOptions & CommonDomOptions) | null; + /** + * 使用react元素渲染内容 + */ react: | ({ element: any; // react场景节点 @@ -255,7 +352,9 @@ export type IGraphicStyle = ILayout & }; export type IPickStyle = { - // 给stroke模式的pick额外加的buffer,用于外界控制stroke区域的pick范围 + /** + * 给stroke模式的pick额外加的buffer,用于外界控制stroke区域的pick范围 + */ pickStrokeBuffer: number; }; @@ -269,7 +368,9 @@ export type IGraphicAttribute = IDebugType & * stroke百分比 */ strokeSeg: IStrokeSeg | null; - // 包围盒的padding + /** + * 包围盒的padding + */ boundsPadding: number | number[]; /** * 选择模式,精确模式,粗糙模式(包围盒模式),自定义模式 @@ -305,6 +406,9 @@ export type IGraphicAttribute = IDebugType & * @default true */ visible: boolean; + /** + * 分组下的层级,层级越小越先绘制 + */ zIndex: number; layout: any; /** @@ -319,14 +423,26 @@ export type IGraphicAttribute = IDebugType & keepDirIn3d?: boolean; shadowRootIdx: number; shadowPickMode?: 'full' | 'graphic'; + /** + * 全局范围的层级,设置了这个属性的图形,会提取到交互层进行渲染 + */ globalZIndex: number; + /** + * canvas 的合成方式 + */ globalCompositeOperation: CanvasRenderingContext2D['globalCompositeOperation'] | ''; - // 完全支持滚动 | 完全不支持滚动 | 支持x方向的滚动 | 支持y方向的滚动 + /** + * 完全支持滚动 | 完全不支持滚动 | 支持x方向的滚动 | 支持y方向的滚动 + */ overflow: 'scroll' | 'hidden' | 'scroll-x' | 'scroll-y'; - // 绘制fill和stroke的顺序,为0表示fill先绘制,1表示stroke先绘制 + /** + * 绘制fill和stroke的顺序,为0表示fill先绘制,1表示stroke先绘制 + */ fillStrokeOrder: number; - // @since 0.20.15 - // 保持stroke的scale,默认为false,为true的话stroke显示的宽度会随着scale变化 + /** + * @since 0.20.15 + * 保持stroke的scale,默认为false,为true的话stroke显示的宽度会随着scale变化 + */ keepStrokeScale: boolean; }; From 871cb466e7c18e9517add9fa48be12b735d3cb55 Mon Sep 17 00:00:00 2001 From: xiaoluoHe Date: Tue, 7 Jan 2025 14:46:31 +0800 Subject: [PATCH 17/24] fix: fix duplicate label issue after custom filtering with label datafilter --- packages/vrender-components/src/label/base.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/vrender-components/src/label/base.ts b/packages/vrender-components/src/label/base.ts index 918a90e5e..8e1c79c94 100644 --- a/packages/vrender-components/src/label/base.ts +++ b/packages/vrender-components/src/label/base.ts @@ -182,6 +182,12 @@ export class LabelBase extends AbstractComponent { data = dataFilter(data); } + if (data && data.length) { + // 数据保护,防止重复 id 造成不可预知的问题 + const seenIds = new Set(); + data = data.filter(d => !seenIds.has(d.id) && seenIds.add(d.id)); + } + let labels: (IText | IRichText)[] = this._initText(data); if (isFunction(customLayoutFunc)) { From 67f3537db2be1801fabbba6c7fac160d60bc5b09 Mon Sep 17 00:00:00 2001 From: xiaoluoHe Date: Tue, 7 Jan 2025 14:47:31 +0800 Subject: [PATCH 18/24] docs: add changelog --- .../fix-duplicated-label-id_2025-01-07-06-46.json | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 common/changes/@visactor/vrender-components/fix-duplicated-label-id_2025-01-07-06-46.json diff --git a/common/changes/@visactor/vrender-components/fix-duplicated-label-id_2025-01-07-06-46.json b/common/changes/@visactor/vrender-components/fix-duplicated-label-id_2025-01-07-06-46.json new file mode 100644 index 000000000..592dab035 --- /dev/null +++ b/common/changes/@visactor/vrender-components/fix-duplicated-label-id_2025-01-07-06-46.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vrender-components", + "comment": "fix: fix duplicate label issue after custom filtering with label dataFilter", + "type": "none" + } + ], + "packageName": "@visactor/vrender-components" +} \ No newline at end of file From 9a73ed516d439bbc25d2221645aa2611f5658add Mon Sep 17 00:00:00 2001 From: Rui-Sun Date: Wed, 8 Jan 2025 18:10:33 +0800 Subject: [PATCH 19/24] fix: fix drawShape function in gif-image render --- ...fix-gif-image-render_2025-01-08-10-09.json | 10 +++ .../contributions/canvas/gif-image-render.ts | 83 +++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 common/changes/@visactor/vrender-kits/fix-gif-image-render_2025-01-08-10-09.json diff --git a/common/changes/@visactor/vrender-kits/fix-gif-image-render_2025-01-08-10-09.json b/common/changes/@visactor/vrender-kits/fix-gif-image-render_2025-01-08-10-09.json new file mode 100644 index 000000000..5c31e0437 --- /dev/null +++ b/common/changes/@visactor/vrender-kits/fix-gif-image-render_2025-01-08-10-09.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vrender-kits", + "comment": "fix: fix drawShape function in gif-image render ", + "type": "none" + } + ], + "packageName": "@visactor/vrender-kits" +} \ No newline at end of file diff --git a/packages/vrender-kits/src/render/contributions/canvas/gif-image-render.ts b/packages/vrender-kits/src/render/contributions/canvas/gif-image-render.ts index d65f4976f..47b6cda79 100644 --- a/packages/vrender-kits/src/render/contributions/canvas/gif-image-render.ts +++ b/packages/vrender-kits/src/render/contributions/canvas/gif-image-render.ts @@ -4,6 +4,7 @@ import type { IDrawContext, IGraphicAttribute, IGraphicRender, + IGraphicRenderDrawParams, IImageRenderContribution, IMarkAttribute, IRenderService, @@ -39,6 +40,88 @@ export class DefaultCanvasGifImageRender extends DefaultCanvasImageRender implem this.init(imageRenderContribitions); } + drawShape( + image: IGifImage, + context: IContext2d, + x: number, + y: number, + drawContext: IDrawContext, + params?: IGraphicRenderDrawParams, + fillCb?: ( + ctx: IContext2d, + markAttribute: Partial, + themeAttribute: IThemeAttribute + ) => boolean, + strokeCb?: ( + ctx: IContext2d, + markAttribute: Partial, + themeAttribute: IThemeAttribute + ) => boolean + ) { + // const imageAttribute = graphicService.themeService.getCurrentTheme().imageAttribute; + const imageAttribute = getTheme(image).image; + const { + x: originX = imageAttribute.x, + y: originY = imageAttribute.y, + fillStrokeOrder = imageAttribute.fillStrokeOrder + } = image.attribute; + + const data = this.valid(image, imageAttribute, fillCb); + if (!data) { + return; + } + const { fVisible, sVisible, doFill, doStroke } = data; + + // deal with cornerRadius + const needRestore = true; + + const _runFill = () => { + if (doFill) { + if (fillCb) { + fillCb(context, image.attribute, imageAttribute); + } else if (fVisible) { + } + } + }; + + const _runStroke = () => { + if (doStroke) { + if (strokeCb) { + strokeCb(context, image.attribute, imageAttribute); + } else if (sVisible) { + context.setStrokeStyle(image, image.attribute, originX - x, originY - y, imageAttribute); + context.stroke(); + } + } + }; + + if (!fillStrokeOrder) { + if (needRestore) { + context.save(); + context.clip(); + } + this.beforeRenderStep(image, context, x, y, doFill, false, fVisible, false, imageAttribute, drawContext, fillCb); + _runFill(); + if (needRestore) { + context.restore(); + } + _runStroke(); + } else { + _runStroke(); + if (needRestore) { + context.save(); + context.clip(); + } + this.beforeRenderStep(image, context, x, y, doFill, false, fVisible, false, imageAttribute, drawContext, fillCb); + _runFill(); + if (needRestore) { + context.restore(); + } + } + + this.afterRenderStep(image, context, x, y, doFill, false, fVisible, false, imageAttribute, drawContext, fillCb); + } + draw(image: IGifImage, renderService: IRenderService, drawContext: IDrawContext) { const { context } = renderService.drawParams; if (!context) { From 0462d374d00a30c1e53d46e595d6e3441eb0a4ad Mon Sep 17 00:00:00 2001 From: xile611 Date: Thu, 9 Jan 2025 15:53:52 +0800 Subject: [PATCH 20/24] docs: update comments --- packages/vrender-components/src/axis/type.ts | 6 + packages/vrender-components/src/core/type.ts | 18 ++ packages/vrender-components/src/label/type.ts | 71 +++++- .../src/legend/discrete/type.ts | 3 +- .../vrender-components/src/marker/type.ts | 146 ++++++++++- .../vrender-components/src/poptip/type.ts | 29 ++- packages/vrender-core/src/interface/color.ts | 72 ++++++ .../vrender-core/src/interface/graphic.ts | 166 ++++++++++++- .../src/interface/graphic/richText.ts | 230 ++++++++++++++++-- 9 files changed, 694 insertions(+), 47 deletions(-) diff --git a/packages/vrender-components/src/axis/type.ts b/packages/vrender-components/src/axis/type.ts index 52b816f19..c61919450 100644 --- a/packages/vrender-components/src/axis/type.ts +++ b/packages/vrender-components/src/axis/type.ts @@ -448,7 +448,13 @@ export interface AxisLabelOverlap { overflowLimitLength?: | number | { + /** + * 左侧扩充空间的大小 + */ left?: number; + /** + * 右侧扩充空间的大小 + */ right?: number; // top?: number; // bottom?: number; diff --git a/packages/vrender-components/src/core/type.ts b/packages/vrender-components/src/core/type.ts index d6cc9a13a..7f1c3a1bc 100644 --- a/packages/vrender-components/src/core/type.ts +++ b/packages/vrender-components/src/core/type.ts @@ -52,9 +52,21 @@ export type Padding = | number | number[] | { + /** + * 上边距 + */ top?: number; + /** + * 下边距 + */ bottom?: number; + /** + * 左边距 + */ left?: number; + /** + * 右边距 + */ right?: number; }; @@ -65,7 +77,13 @@ type CommonTextContent = { | number | number[] | { + /** + * 指定文本节点类型为'text' + */ type?: 'text'; + /** + * 设置文本的内容 + */ text: string | string[] | number | number[]; }; }; diff --git a/packages/vrender-components/src/label/type.ts b/packages/vrender-components/src/label/type.ts index 3c30021ff..fcef620ce 100644 --- a/packages/vrender-components/src/label/type.ts +++ b/packages/vrender-components/src/label/type.ts @@ -162,7 +162,16 @@ export interface OverlapAttrs { /** * 防重叠的区域大小 */ - size?: { width: number; height: number }; + size?: { + /** + * 防重叠区域的宽度 + */ + width: number; + /** + * 防重叠区域的高度 + */ + height: number; + }; /** * 发生重叠后,是否隐藏标签 @@ -274,6 +283,9 @@ export interface SmartInvertAttrs { } export type ShiftYStrategy = { + /** + * 将防重叠策略设置为 'shiftY' + */ type: 'shiftY'; /** * 布局迭代次数 @@ -294,10 +306,13 @@ export type ShiftYStrategy = { export type PositionStrategy = { /** - * 可选位置策略。 + * 将防重叠的策略设置为'position',即可选位置策略。 * 若默认位置没有足够的空间放置标签,则考虑 position 内的备选位置。 */ type: 'position'; + /** + * 所有的备选位置 + */ position?: Functional; /** * 当 position 内的备选位置依然无法放下标签时,标签是否放回原位。 @@ -310,10 +325,13 @@ export type PositionStrategy = { export type BoundStrategy = { /** - * 标签配置在图形内部时使用。 + * 将防重叠策略设置为'bound',当标签配置在图形内部时使用。 * 当图形大小不足以放下标签,则考虑 position 内的备选位置。 */ type: 'bound'; + /** + * 所有的备选位置 + */ position?: Functional; /** * 当 position 内的备选位置依然无法放下标签时,标签是否放回原位。 @@ -326,7 +344,7 @@ export type BoundStrategy = { export type MoveYStrategy = { /** - * 可选位置策略。 + * 将防重叠策略设置为'moveY' * 若默认位置没有足够的空间放置标签,则根据 offset 在Y方向上寻找位置。 */ type: 'moveY'; @@ -338,7 +356,7 @@ export type MoveYStrategy = { export type MoveXStrategy = { /** - * 可选位置策略。 + * 将防重叠策略设置为'moveX' * 若默认位置没有足够的空间放置标签,则根据 offset 在X方向上寻找位置。 */ type: 'moveX'; @@ -555,26 +573,65 @@ export interface DataLabelAttrs extends IGroupGraphicAttribute { export type Functional = T | ((data: any) => T); +/** + * 标签的离场动画配置 + */ export interface ILabelExitAnimation { + /** + * 动画执行的时长 + */ duration?: number; + /** + * 动画延迟的时长 + */ delay?: number; + /** + * 动画的缓动函数 + */ easing?: EasingType; } +/** + * 标签的入场动画配置 + */ export interface ILabelEnterAnimation extends ILabelExitAnimation { + /** + * 标签动画的模式,支持三种类型 + * - same-time:标签出现动画和关联图形的动画同时进行 + * - after:当关联动图的出场动画结束后,执行标签的出场动画 + * - after-all:当所有关联图元的出场动画结束后,执行标签的出场动画 + */ mode?: 'same-time' | 'after' | 'after-all'; } +/** + * 标签的更新动画配置 + */ export interface ILabelUpdateAnimation extends ILabelExitAnimation { - /** 是否开启 increaseCount 动画 + /** + * 是否开启 increaseCount 动画 * @default true */ increaseEffect?: boolean; } +/** + * 标签更新的时候,动画的通道配置 + */ export interface ILabelUpdateChannelAnimation extends ILabelUpdateAnimation { + /** + * 进行插值动画的视觉通道 + */ channel?: string[]; - options?: { excludeChannels?: string[] }; + /** + * 动画的配置 + */ + options?: { + /** + * 忽略的视觉通道 + */ + excludeChannels?: string[]; + }; } export interface ILabelAnimation extends ILabelEnterAnimation, ILabelExitAnimation, ILabelUpdateAnimation {} diff --git a/packages/vrender-components/src/legend/discrete/type.ts b/packages/vrender-components/src/legend/discrete/type.ts index ebe5df2d8..4ca0def55 100644 --- a/packages/vrender-components/src/legend/discrete/type.ts +++ b/packages/vrender-components/src/legend/discrete/type.ts @@ -52,6 +52,7 @@ export type LegendPagerAttributes = Omit & export type LegendScrollbarAttributes = Omit & LegendSwitchComponentAttributes & { /** + * 将翻页器的类型设置为 'scrollbar' * 申明图例组件使用滚动条进行翻页展示更多的图例项 */ type: 'scrollbar'; @@ -218,8 +219,8 @@ export type LegendItem = { */ align?: 'left' | 'right'; /** - * @since 0.21.3 * 水平方向时,一行中多个图例的垂直对齐方式 + * @since 0.21.3 */ verticalAlign?: 'top' | 'middle' | 'bottom'; }; diff --git a/packages/vrender-components/src/marker/type.ts b/packages/vrender-components/src/marker/type.ts index 45b09818e..55605d936 100644 --- a/packages/vrender-components/src/marker/type.ts +++ b/packages/vrender-components/src/marker/type.ts @@ -124,6 +124,9 @@ export type IMarkRef = { }; export type MarkerAttrs = IGroupGraphicAttribute & { + /** + * 设置标注的类型 + */ type?: 'line' | 'arc-line' | 'area' | 'arc-area' | 'point'; /** * 是否支持交互 @@ -154,23 +157,50 @@ export type MarkerAttrs = IGroupGraphicAttribute & { * 组件绘制范围配置 */ limitRect?: { + /** + * 绘制范围的起点x坐标 + */ x: number; + /** + * 绘制范围的起点y坐标 + */ y: number; + /** + * 绘制范围的宽度 + */ width: number; + /** + * 绘制范围的高度 + */ height: number; }; } & BaseMarkerAnimation; /** animation type */ export type BaseMarkerAnimation = { + /** + * 动画公共配置 + */ animation?: MarkerAnimation | boolean; + /** + * 入场动画配置 + */ animationEnter?: MarkerUpdateAnimation; + /** + * 更新动画配置 + */ animationUpdate?: MarkerUpdateAnimation; + /** + * 离场动画配置 + */ animationExit?: MarkerExitAnimation; }; export type MarkerAnimation = MarkerUpdateAnimation | MarkerUpdateAnimation; export type MarkerUpdateAnimation = { + /** + * 设置动画的类型 + */ type: T; } & MarkerExitAnimation; @@ -181,9 +211,21 @@ export type CommonMarkAreaAnimationType = 'fadeIn'; export type MarkPointAnimationType = 'callIn' | 'fadeIn'; export type MarkerExitAnimation = { + /** + * 设置离场动画的类型为fadeOut,即淡出 + */ type: 'fadeOut'; + /** + * 动画的时长 + */ duration?: number; + /** + * 动画延迟的时长 + */ delay?: number; + /** + * 动画的缓动函数 + */ easing?: EasingType; }; @@ -191,29 +233,83 @@ export type MarkerAnimationState = 'enter' | 'update' | 'exit'; /** state type */ export type MarkCommonLineState = { + /** + * 设置线图形的在特定状态下的样式 + */ line?: State; + /** + * 设置线的起点在特定状态下的样式 + */ lineStartSymbol?: State>; + /** + * 设置线的终点在特定状态下的样式 + */ lineEndSymbol?: State>; + /** + * 设置标签在特定状态下的样式 + */ label?: State>; + /** + * 设置标签背景区块在特定状态下的样式 + */ labelBackground?: State>; }; export type CommonMarkAreaState = { + /** + * 设置标注区域在特定状态下的样式 + */ area?: State>; + /** + * 设置标注区域标签在特定状态下的样式 + */ label?: State>; + /** + * 设置标签背景区块在特定状态下的样式 + */ labelBackground?: State>; }; export type MarkPointState = { + /** + * 设置标注点连线在特定状态下的样式 + */ line?: State[]>; + /** + * 设置线起点图形在特定状态下的样式 + */ lineStartSymbol?: State>; + /** + * 设置线终点图形在特定状态下的样式 + */ lineEndSymbol?: State>; + /** + * 设置标注图形在特定状态下的样式 + */ symbol?: State>; + /** + * 设置标注图形在特定状态下的样式 + */ image?: State>; + /** + * 设置标签在特定状态下的样式 + */ text?: State>; + /** + * 设置标签背景区块在特定状态下的样式 + */ textBackground?: State>; + /** + * 设置富文本在特定状态下的样式 + */ richText?: State>; + /** + * 设置自定义标注图形在特定状态下的样式 + */ customMark?: State>; + /** + * 设置目标元素在特定状态下的样式 + */ targetItem?: State>; }; @@ -235,6 +331,9 @@ export type MarkCommonLineAttrs; }; @@ -243,6 +342,9 @@ export type MarkLineAttrs = MarkCommonLineAttrs< keyof typeof IMarkLineLabelPosition, MarkCommonLineAnimationType > & { + /** + * 将辅助线的类型设置为 'line' + */ type?: 'line'; /** * 是否对 points 进行多段处理,默认为 false,即直接将所有的点连接成线。 @@ -255,9 +357,12 @@ export type MarkLineAttrs = MarkCommonLineAttrs< */ mainSegmentIndex?: number; /** - * 构成line的点: 如果是两个点,则为直线;多个点则为曲线 + * 构成line的点: 如果是两个点,则为直线;多个点则为折线 */ points: Point[] | Point[][]; + /** + * 线的样式设置 + */ lineStyle?: ILineGraphicAttribute; }; @@ -266,6 +371,9 @@ export type MarkArcLineAttrs = MarkCommonLineAttrs< keyof typeof IMarkCommonArcLabelPosition, MarkCommonLineAnimationType > & { + /** + * 将辅助线的类型设置为 'arc-line',即弧线 + */ type?: 'arc-line'; /** * 弧线中心位置 @@ -286,6 +394,9 @@ export type MarkArcLineAttrs = MarkCommonLineAttrs< * 弧线终点角度(弧度) */ endAngle: number; + /** + * 设置弧线的样式 + */ lineStyle?: IArcGraphicAttribute; }; @@ -299,6 +410,9 @@ export type MarkAreaAttrs = MarkerAttrs & { * 标签 */ label?: { + /** + * 设置标签的位置 + */ position?: keyof typeof IMarkAreaLabelPosition; /** * 当 mark 配置了 limitRect 之后,label 是否自动调整位置 @@ -310,7 +424,9 @@ export type MarkAreaAttrs = MarkerAttrs & { * area的样式 */ areaStyle?: IPolygonAttribute; - + /** + * 设置标注区域在各种状态下的样式 + */ state?: CommonMarkAreaState; }; @@ -343,6 +459,9 @@ export type MarkArcAreaAttrs = MarkerAttrs & { * 标签 */ label?: { + /** + * 标签的位置 + */ position?: keyof typeof IMarkCommonArcLabelPosition; /** * 当 mark 配置了 limitRect 之后,label 是否自动调整位置 @@ -355,7 +474,9 @@ export type MarkArcAreaAttrs = MarkerAttrs & { * area的样式 */ areaStyle?: IArcGraphicAttribute; - + /** + * 辅助区域这种状态下各个图元的样式设置 + */ state?: CommonMarkAreaState; }; @@ -365,6 +486,9 @@ export type IItemContent = IMarkRef & { * Tips: 保留'richText'与之前的定义做兼容 */ type?: 'symbol' | 'text' | 'image' | 'richText' | 'custom'; + /** + * 设置标注的位置 + */ position?: keyof typeof IMarkPointItemPosition; /** * x 方向偏移量 @@ -405,6 +529,9 @@ export type IItemContent = IMarkRef & { export type IItemLine = { /** TODO:'type-opo' */ type?: 'type-s' | 'type-do' | 'type-po' | 'type-op' | 'type-arc'; + /** + * 是否展示该标注 + */ visible?: boolean; /** * 当type为type-arc时生效, 数值决定曲率, 符号决定法向, 不能等于0 @@ -415,7 +542,13 @@ export type IItemLine = { * 垂直于引导线的装饰线,参考案例: https://observablehq.com/@mikelotis/edmonton-population-history-line-chart */ decorativeLine?: { + /** + * 是否显示引导线的装饰线 + */ visible?: boolean; + /** + * 装饰线的长度 + */ length?: number; }; } & Omit; @@ -454,8 +587,13 @@ export type MarkPointAttrs = Omit, 'labelSty * @default 20 */ size?: number; + /** + * 被标注内容的样式设置 + */ style?: ISymbol; }; - + /** + * 标注点各个状态下的样式 + */ state?: MarkPointState; } & BaseMarkerAnimation; diff --git a/packages/vrender-components/src/poptip/type.ts b/packages/vrender-components/src/poptip/type.ts index e897fd8da..dc580011e 100644 --- a/packages/vrender-components/src/poptip/type.ts +++ b/packages/vrender-components/src/poptip/type.ts @@ -24,21 +24,33 @@ type StateStyle = { }; export type PopTipAttributes = { - /** 位置,参考arco design */ + /** + * 弹出框的方位,有 12 个方位可供选择 + */ position?: 'auto' | 'top' | 'tl' | 'tr' | 'bottom' | 'bl' | 'br' | 'left' | 'lt' | 'lb' | 'right' | 'rt' | 'rb'; /** * 标题内容,如果需要进行换行,则使用数组形式,如 ['abc', '123'] */ title?: string | string[] | number | number[]; - /** 标题样式 */ + /** + * 标题样式 + */ titleStyle?: Partial; + /** + * 标题的格式化方法 + */ titleFormatMethod?: (t: string | string[] | number | number[]) => string | string[] | number | number[]; /** * 内容文本,如果需要进行换行,则使用数组形式,如 ['abc', '123'] */ content?: string | string[] | number | number[]; - /** 内容文本样式 */ + /** + * 内容文本样式 + */ contentStyle?: Partial; + /** + * 内容的格式化方法 + */ contentFormatMethod?: (t: string | string[] | number | number[]) => string | string[] | number | number[]; /** * 标题与内容的间距 @@ -63,10 +75,17 @@ export type PopTipAttributes = { */ maxWidth?: number; - // 最大宽度比例 + /** + * 最大宽度比例 + */ maxWidthPercent?: number; - + /** + * 是否展示 + */ visible?: boolean; + /** + * 自定义的展示逻辑 + */ visibleFunc?: (graphic: IGraphic) => boolean; state?: StateStyle; dx?: number; diff --git a/packages/vrender-core/src/interface/color.ts b/packages/vrender-core/src/interface/color.ts index 7c9635d71..960186de9 100644 --- a/packages/vrender-core/src/interface/color.ts +++ b/packages/vrender-core/src/interface/color.ts @@ -1,5 +1,11 @@ interface IGradientStop { + /** + * 颜色偏移量, 0-1的值 + */ offset: number; + /** + * 颜色值 + */ color: string; } @@ -9,11 +15,29 @@ export type IGradientColor = ILinearGradient | IRadialGradient | IConicalGradien * 线性渐变色 */ export interface ILinearGradient { + /** + * 渐变色的类型设置为 'linear',即线形渐变 + */ gradient: 'linear'; + /** + * 渐变色的起点x坐标,0-1的值,相对于图形包围盒x方向取值的比例值 + */ x0?: number; + /** + * 渐变色的起点y坐标,0-1的值,相对于图形包围盒y方向取值的比例值 + */ y0?: number; + /** + * 渐变色的终点x坐标,0-1的值,相对于图形包围盒x方向取值的比例值 + */ x1?: number; + /** + * 渐变色的终点y坐标,0-1的值,相对于图形包围盒y方向取值的比例值 + */ y1?: number; + /** + * 渐变色的颜色数组,每个颜色对象包含一个偏移量(0-1)和一个颜色值 + */ stops: IGradientStop[]; } @@ -21,13 +45,37 @@ export interface ILinearGradient { * 径向渐变色 */ export interface IRadialGradient { + /** + * 渐变色的类型设置为 'radial',即环形渐变 + */ gradient: 'radial'; + /** + * 径向渐变的起点的x坐标 + */ x0?: number; + /** + * 径向渐变的起点的y坐标 + */ y0?: number; + /** + * 径向渐变的终点的x坐标 + */ x1?: number; + /** + * 径向渐变的终点的x坐标 + */ y1?: number; + /** + * 径向渐变的起点的半径 + */ r0?: number; + /** + * 径向渐变的终点的半径 + */ r1?: number; + /** + * 径向渐变的颜色数组,每个颜色对象包含一个偏移量(0-1)和一个颜色值 + */ stops: IGradientStop[]; } @@ -35,16 +83,40 @@ export interface IRadialGradient { * 环形渐变色/锥形渐变色 */ export interface IConicalGradient { + /** + * 渐变色的类型设置为 'conical',即环形渐变 + */ gradient: 'conical'; + /** + * 锥形渐变的开始角度 + */ startAngle?: number; + /** + * 锥形渐变的开始角度 + */ endAngle?: number; + /** + * 锥形渐变的中心点x坐标 + */ x?: number; + /** + * 锥形渐变的中心点y坐标 + */ y?: number; + /** + * 锥形渐变的颜色 + */ stops: IGradientStop[]; } export interface IColorStop { + /** + * 颜色偏移量, 0-1的值 + */ offset: number; + /** + * 颜色值 + */ color: string; } diff --git a/packages/vrender-core/src/interface/graphic.ts b/packages/vrender-core/src/interface/graphic.ts index cda04af76..ff05f1766 100644 --- a/packages/vrender-core/src/interface/graphic.ts +++ b/packages/vrender-core/src/interface/graphic.ts @@ -91,23 +91,77 @@ export type Cursor = | 'zoom-out'; export type ITransform = { + /** + * x坐标 + */ x: number; + /** + * y坐标 + */ y: number; + /** + * z坐标 + */ z: number; + /** + * x方向偏移量 + */ dx: number; + /** + * y方向偏移量 + */ dy: number; + /** + * z方向偏移量 + */ dz: number; + /** + * x方向的滚动值 + */ scrollX: number; + /** + * y方向的滚动值 + */ scrollY: number; + /** + * x方向的缩放值 + */ scaleX: number; + /** + * y方向的缩放值 + */ scaleY: number; + /** + * z方向的缩放值 + */ scaleZ: number; + /** + * 绕z轴的转角,即xy平面上的旋转角度 + */ angle: number; + /** + * 绕x轴的转角 + */ alpha: number; + /** + * 绕y轴的转角 + */ beta: number; + /** + * 应用缩放的中心 + */ scaleCenter: [number | string, number | string]; - anchor: [number | string, number | string]; // 基于AABB的锚点位置,用于简单的定位某些path - anchor3d: [number | string, number | string, number] | [number | string, number | string]; // 3d的锚点位置 + /** + * 基于AABB的锚点位置,用于简单的定位某些path + */ + anchor: [number | string, number | string]; + /** + * 3d的锚点位置 + */ + anchor3d: [number | string, number | string, number] | [number | string, number | string]; + /** + * 处理矩阵,在正常计算完变换矩阵之后,会将该矩阵乘到变换矩阵上得到最终的变换矩阵 + */ postMatrix: IMatrix; }; @@ -140,11 +194,20 @@ export type IFillStyle = { }; export type ILayout = { + /** + * 设置对齐方式 + */ alignSelf: 'auto' | 'flex-start' | 'flex-end' | 'center'; }; export type IBorderStyle = Omit & { + /** + * 边距离边缘的距离 + */ distance: number | string; + /** + * 是否显示边框,默认是不显示的 + */ visible?: boolean; }; @@ -162,11 +225,34 @@ export type IStrokeStyle = { * 描边的透明度 */ strokeOpacity: number; + /** + * 设置线条虚线样式的属性,它通过定义实线和空白的交替长度来创建虚线效果 + */ lineDash: number[]; + + /** + * 设置虚线样式的起始偏移量 + */ lineDashOffset: number; + + /** + * 设置线条的宽度 + */ lineWidth: number; + + /** + * 设置线条末端的样式 + */ lineCap: CanvasLineCap; + + /** + * 设置线条拐角的样式 + */ lineJoin: CanvasLineJoin; + + /** + * 设置线条拐角处的斜接限制 + */ miterLimit: number; /** * 描边的boundsBuffer,用于控制bounds的buffer @@ -229,8 +315,17 @@ export type IBackgroundConfig = { type IBackgroundType = string | HTMLImageElement | HTMLCanvasElement | IBackgroundConfig; export interface SimpleDomStyleOptions { - width: number; // 容器的宽度 - height: number; // 容器的高度 + /** + * 容器的宽度 + */ + width: number; + /** + * 容器的高度 + */ + height: number; + /** + * 容器的样式设置 + */ style?: | string | Record @@ -242,13 +337,41 @@ export interface SimpleDomStyleOptions { } export interface CommonDomOptions { + /** + * 全局唯一的id + */ id?: string; - container: string | HTMLElement | null; // id或者dom + /** + * 容器元素的id或者dom元素 + */ + container: string | HTMLElement | null; + /** + * 是否显示 + */ visible?: boolean; + /** + * 是否支持事件冒泡 + */ pointerEvents?: boolean | string; - // 可穿透的事件列表 - // @since 0.21.2 + /** + * 可穿透的事件列表 + * @since 0.21.2 + */ penetrateEventList?: string[]; + /** + * 定位类型 + * 'position' - 根据挂载图形节点的坐标也就是x,y进行定位 + * 'boundsLeftTop' - 定位到挂载图形节点bounds的左上角 + * 'left' - 定位到挂载图形节点bounds 的左侧 + * 'right' - 定位到挂载图形节点bounds 的右侧 + * 'bottom' - 定位到挂载图形节点bounds 的底部 + * 'top' - 定位到挂载图形节点bounds 的顶部 + * 'center' - 定位到挂载图形节点bounds 的中心 + * 'top-left' - 定位到挂载图形节点bounds 的左上角 + * 'top-right' - 定位到挂载图形节点bounds 的右上角 + * 'bottom-left' - 定位到挂载图形节点bounds 的左下角 + * 'bottom-right' - 定位到挂载图形节点bounds 的右下角 + */ anchorType?: 'position' | 'boundsLeftTop' | BoundsAnchorType; } @@ -268,10 +391,25 @@ export type IGraphicStyle = ILayout & * 透明度,会同时影响填充和描边 */ opacity: number; + /** + * 影子节点 + */ shadowGraphic?: IGraphic | undefined; - backgroundMode: 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat'; // 填充模式(与具体图元有关) - backgroundFit: boolean; // 是否正好填充,只在repeat-x或者repeat-y以及no-repeat的时候生效 + /** + * 背景填充模式(与具体图元有关) + */ + backgroundMode: 'repeat' | 'repeat-x' | 'repeat-y' | 'no-repeat'; + /** + * 是否正好填充,只在repeat-x或者repeat-y以及no-repeat的时候生效 + */ + backgroundFit: boolean; + /** + * 背景圆角半径 + */ backgroundCornerRadius: number | number[]; + /** + * 背景透明度 + */ backgroundOpacity: number; /** * 背景,支持颜色字符串、html image元素、html canvas元素 @@ -337,7 +475,10 @@ export type IGraphicStyle = ILayout & */ html: | ({ - dom: string | HTMLElement; // dom字符串或者dom + /** + * dom字符串或者dom + */ + dom: string | HTMLElement; } & SimpleDomStyleOptions & CommonDomOptions) | null; @@ -346,7 +487,10 @@ export type IGraphicStyle = ILayout & */ react: | ({ - element: any; // react场景节点 + /** + * react场景节点 + */ + element: any; } & SimpleDomStyleOptions & CommonDomOptions) | null; diff --git a/packages/vrender-core/src/interface/graphic/richText.ts b/packages/vrender-core/src/interface/graphic/richText.ts index 01d788a52..8568e00f9 100644 --- a/packages/vrender-core/src/interface/graphic/richText.ts +++ b/packages/vrender-core/src/interface/graphic/richText.ts @@ -5,20 +5,63 @@ import type { IImage, IImageGraphicAttribute } from './image'; import type { ITextGraphicAttribute } from './text'; export type IRichTextAttribute = { + /** + * 富文本的总宽度 + */ width: number; + /** + * 富文本的总高度 + */ height: number; + /** + * 是否可编辑 + */ editable: boolean; + /** + * 文本超长的时候是否显示省略字符串 + * 1. boolean类型,true 表示将截断后的省略字符串设置为..., false 表示不显示省略字符串 + * 2. string类型,表示显示省略字符串,并将省略字符串设置为指定的值 + */ ellipsis: boolean | string; + /** + * 文字换行类型 + */ wordBreak: RichTextWordBreak; + /** + * 文字垂直方向 + */ verticalDirection: RichTextVerticalDirection; + /** + * 富文本的最大高度,超过这个高度根据ellipsis的配置展示省略字符串或者直接截断 + */ maxHeight: number; + /** + * 富文本的最大宽度,超过这个宽度根据ellipsis的配置展示省略字符串或者直接截断 + */ maxWidth: number; + /** + * 文字对齐方式 + */ textAlign: RichTextGlobalAlignType; + /** + * 文字基线 + */ textBaseline: RichTextGlobalBaselineType; + /** + * 富文本的布局方向 + */ layoutDirection: RichTextLayoutDirectionType; + /** + * 富文本的内容配置 + */ textConfig: IRichTextCharacter[]; - // 是否不自动每行截断 + /** + * 不自动换行,仅当用户设置了换行符的时候才换行 + */ disableAutoWrapLine: boolean; + /** + * 是否强制单行显示 + */ singleLine: boolean; }; @@ -36,81 +79,230 @@ export type RichTextTextDecoration = 'none' | 'underline' | 'line-through'; export type RichTextScript = 'normal' | 'sub' | 'super'; export type IRichTextBasicCharacter = { + /** + * 行高 + */ lineHeight?: number | string; - textAlign?: CanvasTextAlign; // left, right, center + /** + * 文字对齐方式 + * left, right, center + */ + textAlign?: CanvasTextAlign; + /** + * 文字基线 + */ textBaseline?: CanvasTextBaseline; + /** + * 文字方向 + */ direction?: RichTextLayoutDirectionType; }; +/** + * 富文本段落为文本类型时候的配置 + */ export type IRichTextParagraphCharacter = IRichTextBasicCharacter & { + /** + * 文本内容 + */ text: string | number; + /** + * 富文本片段的字体大小 + */ fontSize?: number; + /** + * 富文本片段的字体类型 + */ fontFamily?: string; + /** + * 富文本片段的文字颜色 + */ fill?: IColor | boolean; + /** + * 富文本片段的文字描边颜色 + */ stroke?: IColor | boolean; + /** + * 富文本片段的文字字重 + */ fontWeight?: string; + /** + * 富文本片段的文字描边宽度 + */ lineWidth?: number; // lineHeight?: number; - fontStyle?: RichTextFontStyle; // normal, italic, oblique - textDecoration?: RichTextTextDecoration; // none, underline, line-through + /** + * 富文本片段的文字斜体设置,支持以下属性 + * normal, italic, oblique + */ + fontStyle?: RichTextFontStyle; + /** + * 富文本片段的文字中划线设置,支持以下属性 + * none, underline, line-through + */ + textDecoration?: RichTextTextDecoration; // textAlign?: RichTextTextAlign; // left, right, center script?: RichTextScript; // normal, sub, super + /** + * 富文本片段的文字下划线设置,是否显示下划线 + */ underline?: boolean; + /** + * 富文本片段的文字中划线设置,是否显示中划线 + */ lineThrough?: boolean; + /** + * 富文本片段的透明度 + */ opacity?: number; + /** + * 富文本片段的文字填充透明度 + */ fillOpacity?: number; + /** + * 富文本片段的文字描边透明度 + */ strokeOpacity?: number; // direction?: RichTextLayoutDirectionType; }; export type IRichTextImageCharacter = IRichTextBasicCharacter & { - // 图片基础属性 + /** + * 设置图片的内容, + * 支持三种格式: + * 1. 图片的url + * 2. 图片的Image对象 + * 3. 图片的Canvas对象 + */ image: string | HTMLImageElement | HTMLCanvasElement; + /** + * 图片的宽度 + */ width: number; + /** + * 图片的高度 + */ height: number; // hover相关属性 // backgroundShow?: boolean; // 是否显示background + /** + * 背景的展示模式,支持以下属性 + * always: 一直显示 + * hover: 鼠标hover时显示 + */ backgroundShowMode?: 'always' | 'hover'; - backgroundFill?: boolean | IColor; // 背景矩形填充颜色 - backgroundFillOpacity?: number; // 背景矩形填充透明度 - backgroundStroke?: boolean | IColor; // 背景矩形边框颜色 - backgroundStrokeOpacity?: number; // 背景矩形边框透明度 - backgroundRadius?: number; // 背景矩形圆角 + /** + * 背景矩形填充颜色 + */ + backgroundFill?: boolean | IColor; + /** + * 背景矩形填充透明度 + */ + backgroundFillOpacity?: number; + /** + * 背景矩形边框颜色 + */ + backgroundStroke?: boolean | IColor; + /** + * 背景矩形边框透明度 + */ + backgroundStrokeOpacity?: number; + /** + * 背景矩形圆角 + */ + backgroundRadius?: number; // background size 同时控制了该icon的响应范围 + /** + * 背景矩形的宽度 + */ backgroundWidth?: number; + /** + * 背景矩形的高度 + */ backgroundHeight?: number; - // 唯一标识符 + /** + * 唯一标识符 + */ id?: string; // lineHeight?: number; // textAlign?: RichTextTextAlign; // left, right, center // direction?: RichTextLayoutDirectionType; + /** + * 图片与相邻节点的间距 + */ margin?: number | number[]; funcType?: string; hoverImage?: string | HTMLImageElement | HTMLCanvasElement; }; - +/** + * 富文本的字符类型 + */ export type IRichTextCharacter = IRichTextParagraphCharacter | IRichTextImageCharacter; export type IRichTextIconGraphicAttribute = IImageGraphicAttribute & { + /** + * 唯一id + */ id?: string; + /** + * 背景的展示模式,支持以下属性 + * always: 一直显示 + * hover: 鼠标hover时显示 + * never: 不显示 + */ backgroundShowMode?: 'always' | 'hover' | 'never'; - backgroundFill?: boolean | IColor; // 背景矩形填充颜色 - backgroundFillOpacity?: number; // 背景矩形填充透明度 - backgroundStroke?: boolean | IColor; // 背景矩形边框颜色 - backgroundStrokeOpacity?: number; // 背景矩形边框透明度 - backgroundRadius?: number; // 背景矩形圆角 + /** + * 背景矩形填充颜色 + */ + backgroundFill?: boolean | IColor; + /** + * 背景矩形填充透明度 + */ + backgroundFillOpacity?: number; + /** + * 背景矩形边框颜色 + */ + backgroundStroke?: boolean | IColor; + /** + * 背景矩形边框透明度 + */ + backgroundStrokeOpacity?: number; + /** + * 背景矩形圆角 + */ + backgroundRadius?: number; + /** + * 背景矩形的宽度 + */ backgroundWidth?: number; + /** + * 背景矩形的高度 + */ backgroundHeight?: number; // lineHeight?: number; - textAlign?: CanvasTextAlign; // left, right, center + /** + * 文字对齐方式 + * left, right, center + */ + textAlign?: CanvasTextAlign; + /** + * 文字基线 + * top, middle, bottom + */ textBaseline?: CanvasTextBaseline; + /** + * 文字方向 + * horizontal, vertical + */ direction?: RichTextLayoutDirectionType; - + /** + * 图片与相邻节点的间距 + */ margin?: number | number[]; // backgroundShow?: boolean; From be52f12ed9761e9aeac4318c2ae85d69c7581ad3 Mon Sep 17 00:00:00 2001 From: zhouxinyu Date: Thu, 9 Jan 2025 21:35:08 +0800 Subject: [PATCH 21/24] fix: fix issue with measureText in lynx env --- .../src/canvas/contributions/lynx/context.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/vrender-kits/src/canvas/contributions/lynx/context.ts b/packages/vrender-kits/src/canvas/contributions/lynx/context.ts index 8629efcc5..30f827541 100644 --- a/packages/vrender-kits/src/canvas/contributions/lynx/context.ts +++ b/packages/vrender-kits/src/canvas/contributions/lynx/context.ts @@ -74,8 +74,15 @@ export class LynxContext2d extends BrowserContext2d implements IContext2d { method: 'native' | 'simple' | 'quick' = application.global.measureTextMethod ): { width: number } { this.setTransform(1, 0, 0, 1, 0, 0, true, application.global.devicePixelRatio); - const data = super.measureText(text, method); - return data; + const data: any = super.measureText(text, method); + // lynx环境中的fontBoundingBoxDescent和fontBoundingBoxAscent有严重偏移,暂时规避 + return { + width: data.width, + fontBoundingBoxDescent: undefined, + fontBoundingBoxAscent: undefined, + actualBoundingBoxAscent: undefined, + actualBoundingBoxDescent: undefined + } as any; } createPattern(image: HTMLImageElement | HTMLCanvasElement | HTMLVideoElement, repetition: string): CanvasPattern { From 20cd045b1b0467a2a30be93cbf920dfaa33a3a2b Mon Sep 17 00:00:00 2001 From: zhouxinyu Date: Fri, 10 Jan 2025 13:22:10 +0800 Subject: [PATCH 22/24] feat: change effect for connectedType, closed #1660 --- .../feat-line-connect_2025-01-10-05-20.json | 10 + .../vrender-core/src/common/render-area.ts | 265 ++++-------------- .../vrender-core/src/common/render-curve.ts | 2 +- .../vrender-core/src/common/segment/step.ts | 6 +- packages/vrender-core/src/graphic/line.ts | 4 +- .../vrender-core/src/interface/graphic.ts | 2 +- .../contributions/render/area-render.ts | 145 +++------- .../contributions/render/line-render.ts | 69 +---- 8 files changed, 116 insertions(+), 387 deletions(-) create mode 100644 common/changes/@visactor/vrender-core/feat-line-connect_2025-01-10-05-20.json diff --git a/common/changes/@visactor/vrender-core/feat-line-connect_2025-01-10-05-20.json b/common/changes/@visactor/vrender-core/feat-line-connect_2025-01-10-05-20.json new file mode 100644 index 000000000..5bcce79de --- /dev/null +++ b/common/changes/@visactor/vrender-core/feat-line-connect_2025-01-10-05-20.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vrender-core", + "comment": "feat: change effect for connectedType, closed #1660", + "type": "none" + } + ], + "packageName": "@visactor/vrender-core" +} diff --git a/packages/vrender-core/src/common/render-area.ts b/packages/vrender-core/src/common/render-area.ts index ff2133707..743c231a2 100644 --- a/packages/vrender-core/src/common/render-area.ts +++ b/packages/vrender-core/src/common/render-area.ts @@ -24,16 +24,8 @@ export function drawAreaSegments( offsetY?: number; offsetZ?: number; direction?: IDirection; - drawConnect?: boolean; // 是否是绘制connect区域的效果 - mode?: 'none' | 'connect' | 'zero'; - zeroX?: number; - zeroY?: number; } ) { - const { drawConnect = false, mode = 'none' } = params || {}; - if (drawConnect && mode === 'none') { - return; - } // let needMoveTo: boolean = true; const { top, bottom } = segPath; // 如果top和bottom的curves数量不同,那么就跳过 @@ -44,90 +36,26 @@ export function drawAreaSegments( const topList: ICurve[] = []; const bottomList: ICurve[] = []; let lastDefined: boolean = true; - if (drawConnect) { - let defined0 = true; - let lastCurve: ICurve; - let lastBottomCurve: ICurve; - const n = top.curves.length; - top.curves.forEach((curve, i) => { - // step的逻辑 - const bototmCurve = bottom.curves[n - i - 1]; - let currentTopCurve = curve; - let currentBottomCurve = bototmCurve; - if (curve.originP1 === curve.originP2) { - lastCurve = curve; - lastBottomCurve = bototmCurve; - return; - } - if (lastCurve && lastCurve.originP1 === lastCurve.originP2) { - currentTopCurve = lastCurve; - currentBottomCurve = lastBottomCurve; - } - if (curve.defined) { - // 非法变合法需要lineTo,合法变非法需要moveTo,初始非法需要moveTo - if (!defined0) { - topList.push(currentTopCurve); - bottomList.push(currentBottomCurve); - drawAreaConnectBlock(path, topList, bottomList, params); - topList.length = 0; - bottomList.length = 0; - defined0 = !defined0; - } + for (let i = 0, n = top.curves.length; i < n; i++) { + const topCurve = top.curves[i]; + if (lastDefined !== topCurve.defined) { + if (lastDefined) { + drawAreaBlock(path, topList, bottomList, params); + topList.length = 0; + bottomList.length = 0; } else { - // 找到合法的点 - const { originP1, originP2 } = curve; - let validTopCurve: ICurve; - let validBottomCurve: ICurve; - if (originP1 && originP1.defined !== false) { - validTopCurve = currentTopCurve; - validBottomCurve = currentBottomCurve; - } else if (originP1 && originP2.defined !== false) { - validTopCurve = curve; - validBottomCurve = bototmCurve; - } - // 合法/(初始)变非法,moveTo - if (defined0) { - defined0 = !defined0; - topList.push(validTopCurve || curve); - bottomList.push(validBottomCurve || bototmCurve); - } else { - // 非法变非法/合法,看情况要不要lineTo - if (validTopCurve) { - // 非法变合法,需要lineTo - defined0 = !defined0; - topList.push(validTopCurve || curve); - bottomList.push(validBottomCurve || bototmCurve); - drawAreaConnectBlock(path, topList, bottomList, params); - topList.length = 0; - bottomList.length = 0; - } - } + topList.push(topCurve); + bottomList.push(bottom.curves[n - i - 1]); } - lastCurve = curve; - }); - drawAreaConnectBlock(path, topList, bottomList, params); - } else { - for (let i = 0, n = top.curves.length; i < n; i++) { - const topCurve = top.curves[i]; - if (lastDefined !== topCurve.defined) { - if (lastDefined) { - drawAreaBlock(path, topList, bottomList, params); - topList.length = 0; - bottomList.length = 0; - } else { - topList.push(topCurve); - bottomList.push(bottom.curves[n - i - 1]); - } - lastDefined = !lastDefined; - } else { - if (lastDefined) { - topList.push(topCurve); - bottomList.push(bottom.curves[n - i - 1]); - } + lastDefined = !lastDefined; + } else { + if (lastDefined) { + topList.push(topCurve); + bottomList.push(bottom.curves[n - i - 1]); } } - drawAreaBlock(path, topList, bottomList, params); } + drawAreaBlock(path, topList, bottomList, params); return; } @@ -159,7 +87,7 @@ export function drawAreaSegments( let lastDefined: boolean = true; const topList: ICurve[] = []; const bottomList: ICurve[] = []; - let defined0 = true; + const defined0 = true; let lastTopCurve: ICurve; let lastBottomCurve: ICurve; for (let i = 0, n = top.curves.length; i < n; i++) { @@ -171,112 +99,50 @@ export function drawAreaSegments( } drawedLengthUntilLast += curCurveLength; - if (drawConnect) { - // step的逻辑 - const bototmCurve = bottom.curves[n - i - 1]; - let currentTopCurve = topCurve; - let currentBottomCurve = bototmCurve; - if (topCurve.originP1 === topCurve.originP2) { - lastTopCurve = topCurve; - lastBottomCurve = bototmCurve; - continue; - } - if (lastTopCurve && lastTopCurve.originP1 === lastTopCurve.originP2) { - currentTopCurve = lastTopCurve; - currentBottomCurve = lastBottomCurve; - } - if (topCurve.defined) { - // 非法变合法需要lineTo,合法变非法需要moveTo,初始非法需要moveTo - if (!defined0) { - topList.push(currentTopCurve); - bottomList.push(currentBottomCurve); - drawAreaConnectBlock(path, topList, bottomList, params); - topList.length = 0; - bottomList.length = 0; - defined0 = !defined0; - } + let tc: ICurve | null = null; + let bc: ICurve | null = null; + if (lastDefined !== topCurve.defined) { + if (lastDefined) { + drawAreaBlock(path, topList, bottomList, params); + topList.length = 0; + bottomList.length = 0; } else { - // 找到合法的点 - const { originP1, originP2 } = topCurve; - let validTopCurve: ICurve; - let validBottomCurve: ICurve; - if (originP1 && originP1.defined !== false) { - validTopCurve = currentTopCurve; - validBottomCurve = currentBottomCurve; - } else if (originP1 && originP2.defined !== false) { - validTopCurve = topCurve; - validBottomCurve = bototmCurve; - } - // 合法/(初始)变非法,moveTo - if (defined0) { - defined0 = !defined0; - topList.push(validTopCurve || topCurve); - bottomList.push(validBottomCurve || bototmCurve); - } else { - // 非法变非法/合法,看情况要不要lineTo - if (validTopCurve) { - // 非法变合法,需要lineTo - defined0 = !defined0; - topList.push(validTopCurve || topCurve); - bottomList.push(validBottomCurve || bototmCurve); - drawAreaConnectBlock(path, topList, bottomList, params); - topList.length = 0; - bottomList.length = 0; - } - } + tc = topCurve; + bc = bottom.curves[n - i - 1]; } - lastTopCurve = topCurve; - // drawAreaBlock(path, topList, bottomList, params); + lastDefined = !lastDefined; } else { - let tc: ICurve | null = null; - let bc: ICurve | null = null; - if (lastDefined !== topCurve.defined) { - if (lastDefined) { - drawAreaBlock(path, topList, bottomList, params); - topList.length = 0; - bottomList.length = 0; - } else { - tc = topCurve; - bc = bottom.curves[n - i - 1]; - } - lastDefined = !lastDefined; - } else { - if (lastDefined) { - tc = topCurve; - bc = bottom.curves[n - i - 1]; - } + if (lastDefined) { + tc = topCurve; + bc = bottom.curves[n - i - 1]; } + } - if (tc && bc) { - if (percent < 1) { - if (tc.p2 && tc.p3) { - tc = divideCubic(tc as ICubicBezierCurve, percent)[0]; - } else { - tc = divideLinear(tc as ILineCurve, percent)[0]; - } - if (bc.p2 && bc.p3) { - bc = divideCubic(bc as ICubicBezierCurve, 1 - percent)[1]; - } else { - bc = divideLinear(bc as ILineCurve, 1 - percent)[1]; - } + if (tc && bc) { + if (percent < 1) { + if (tc.p2 && tc.p3) { + tc = divideCubic(tc as ICubicBezierCurve, percent)[0]; + } else { + tc = divideLinear(tc as ILineCurve, percent)[0]; + } + if (bc.p2 && bc.p3) { + bc = divideCubic(bc as ICubicBezierCurve, 1 - percent)[1]; + } else { + bc = divideLinear(bc as ILineCurve, 1 - percent)[1]; } - tc.defined = lastDefined; - bc.defined = lastDefined; - topList.push(tc); - bottomList.push(bc); } - - tc = null; - bc = null; + tc.defined = lastDefined; + bc.defined = lastDefined; + topList.push(tc); + bottomList.push(bc); } - } - if (drawConnect) { - drawAreaConnectBlock(path, topList, bottomList, params); - } else { - drawAreaBlock(path, topList, bottomList, params); + tc = null; + bc = null; } + drawAreaBlock(path, topList, bottomList, params); + // const totalLength = segPath.tryUpdateLength(); // // 直到上次绘制的长度 @@ -303,39 +169,6 @@ export function drawAreaSegments( // } } -function drawAreaConnectBlock( - path: IPath2D, - topList: ICurve[], - bottomList: ICurve[], - params?: { - offsetX?: number; - offsetY?: number; - offsetZ?: number; - mode?: 'none' | 'connect' | 'zero'; - zeroX?: number; - zeroY?: number; - } -) { - if (topList.length < 2) { - return; - } - const { offsetX = 0, offsetY = 0, offsetZ = 0, mode } = params || {}; - let curve = topList[0]; - // mode不支持zero - path.moveTo(curve.p0.x + offsetX, curve.p0.y + offsetY, offsetZ); - curve = topList[topList.length - 1]; - let end = curve.p3 || curve.p1; - path.lineTo(end.x + offsetX, end.y + offsetY, offsetZ); - - curve = bottomList[bottomList.length - 1]; - path.lineTo(curve.p0.x + offsetX, curve.p0.y + offsetY, offsetZ); - curve = bottomList[0]; - end = curve.p3 || curve.p1; - path.lineTo(end.x + offsetX, end.y + offsetY, offsetZ); - - path.closePath(); -} - function drawAreaBlock( path: IPath2D, topList: ICurve[], diff --git a/packages/vrender-core/src/common/render-curve.ts b/packages/vrender-core/src/common/render-curve.ts index b22abd04e..6c870ab9a 100644 --- a/packages/vrender-core/src/common/render-curve.ts +++ b/packages/vrender-core/src/common/render-curve.ts @@ -82,7 +82,7 @@ export function drawSegments( offsetY?: number; offsetZ?: number; drawConnect?: boolean; // 是否是绘制connect区域的效果 - mode?: 'none' | 'connect' | 'zero'; + mode?: 'none' | 'connect'; zeroX?: number; zeroY?: number; } diff --git a/packages/vrender-core/src/common/segment/step.ts b/packages/vrender-core/src/common/segment/step.ts index 3fd0db4eb..f6981e038 100644 --- a/packages/vrender-core/src/common/segment/step.ts +++ b/packages/vrender-core/src/common/segment/step.ts @@ -87,7 +87,11 @@ export class Step implements ICurvedSegment { this.context.lineTo(x, y, this._lastDefined !== false && p.defined !== false, p); } else { const x1 = this._x * (1 - this._t) + x * this._t; - this.context.lineTo(x1, this._y, this._lastDefined !== false && p.defined !== false, this.lastPoint); + if (this._t === 0.5) { + this.context.lineTo(x1, this._y, this._lastDefined !== false, this.lastPoint); + } else { + this.context.lineTo(x1, this._y, this._lastDefined !== false && p.defined !== false, this.lastPoint); + } this.context.lineTo(x1, y, this._lastDefined !== false && p.defined !== false, p); } break; diff --git a/packages/vrender-core/src/graphic/line.ts b/packages/vrender-core/src/graphic/line.ts index 20cf0be12..9e188355c 100644 --- a/packages/vrender-core/src/graphic/line.ts +++ b/packages/vrender-core/src/graphic/line.ts @@ -82,7 +82,7 @@ export class Line extends Graphic implements ILine { const { points = lineTheme.points, connectedType } = attribute; const b = aabbBounds; points.forEach(p => { - if (p.defined !== false || connectedType === 'zero' || connectedType === 'connect') { + if (p.defined !== false || connectedType === 'connect') { b.add(p.x, p.y); } }); @@ -98,7 +98,7 @@ export class Line extends Graphic implements ILine { const b = aabbBounds; segments.forEach(s => { s.points.forEach(p => { - if (p.defined !== false || connectedType === 'zero' || connectedType === 'connect') { + if (p.defined !== false || connectedType === 'connect') { b.add(p.x, p.y); } }); diff --git a/packages/vrender-core/src/interface/graphic.ts b/packages/vrender-core/src/interface/graphic.ts index cda04af76..2c6ea9e7d 100644 --- a/packages/vrender-core/src/interface/graphic.ts +++ b/packages/vrender-core/src/interface/graphic.ts @@ -198,7 +198,7 @@ export type IConnectedStyle = { /** * 连接,取零或者断开 */ - connectedType: 'connect' | 'zero' | 'none'; + connectedType: 'connect' | 'none'; /** * 连接线的样式配置 */ diff --git a/packages/vrender-core/src/render/contributions/render/area-render.ts b/packages/vrender-core/src/render/contributions/render/area-render.ts index aed87ba04..71748d6f0 100644 --- a/packages/vrender-core/src/render/contributions/render/area-render.ts +++ b/packages/vrender-core/src/render/contributions/render/area-render.ts @@ -195,7 +195,8 @@ export class DefaultCanvasAreaRender extends BaseRender implements IGraph fillOpacity = areaAttribute.fillOpacity, z = areaAttribute.z, strokeOpacity = areaAttribute.strokeOpacity, - curveTension = areaAttribute.curveTension + curveTension = areaAttribute.curveTension, + connectedType = areaAttribute.connectedType } = area.attribute; const data = this.valid(area, areaAttribute, fillCb, strokeCb); @@ -211,6 +212,13 @@ export class DefaultCanvasAreaRender extends BaseRender implements IGraph curveType = 'linearClosed'; } + function parsePoint(points: IPointLike[], connectedType: 'none' | 'connect') { + if (connectedType !== 'connect') { + return points; + } + return points.filter(p => p.defined !== false); + } + if (clipRange === 1 && !segments && !points.some(p => p.defined === false) && curveType === 'linear') { return this.drawLinearAreaHighPerformance( area, @@ -250,7 +258,7 @@ export class DefaultCanvasAreaRender extends BaseRender implements IGraph startPoint.x = lastTopSeg.endX; startPoint.y = lastTopSeg.endY; } - const data = calcLineCache(seg.points, curveType, { + const data = calcLineCache(parsePoint(seg.points, connectedType), curveType, { startPoint, curveTension }); @@ -281,7 +289,7 @@ export class DefaultCanvasAreaRender extends BaseRender implements IGraph } if (bottomPoints.length > 1) { lastBottomSeg = calcLineCache( - bottomPoints, + parsePoint(bottomPoints, connectedType), curveType === 'stepBefore' ? 'stepAfter' : curveType === 'stepAfter' ? 'stepBefore' : curveType, { curveTension } ); @@ -294,12 +302,12 @@ export class DefaultCanvasAreaRender extends BaseRender implements IGraph })); } else if (points && points.length) { // 转换points - const topPoints = points; + const topPoints = parsePoint(points, connectedType); const bottomPoints: IPointLike[] = []; - for (let i = points.length - 1; i >= 0; i--) { + for (let i = topPoints.length - 1; i >= 0; i--) { bottomPoints.push({ - x: points[i].x1 ?? points[i].x, - y: points[i].y1 ?? points[i].y + x: points[i].x1 ?? topPoints[i].x, + y: points[i].y1 ?? topPoints[i].y }); } const topCache = calcLineCache(topPoints, curveType, { curveTension }); @@ -456,50 +464,24 @@ export class DefaultCanvasAreaRender extends BaseRender implements IGraph themeAttribute: IThemeAttribute | IThemeAttribute[] ) => boolean ): boolean { - let ret = false; - ret = - ret || - this._drawSegmentItem( - context, - cache, - fill, - fillOpacity, - stroke, - strokeOpacity, - attribute, - defaultAttribute, - clipRange, - offsetX, - offsetY, - offsetZ, - area, - drawContext, - false, - fillCb, - strokeCb - ); - ret = - ret || - this._drawSegmentItem( - context, - cache, - fill, - fillOpacity, - stroke, - strokeOpacity, - attribute, - defaultAttribute, - clipRange, - offsetX, - offsetY, - offsetZ, - area, - drawContext, - true, - fillCb, - strokeCb - ); - return ret; + return this._drawSegmentItem( + context, + cache, + fill, + fillOpacity, + stroke, + strokeOpacity, + attribute, + defaultAttribute, + clipRange, + offsetX, + offsetY, + offsetZ, + area, + drawContext, + fillCb, + strokeCb + ); } protected _drawSegmentItem( @@ -517,7 +499,6 @@ export class DefaultCanvasAreaRender extends BaseRender implements IGraph offsetZ: number, area: IArea, drawContext: IDrawContext, - connect: boolean, fillCb?: ( ctx: IContext2d, lineAttribute: Partial, @@ -542,38 +523,6 @@ export class DefaultCanvasAreaRender extends BaseRender implements IGraph ) { return; } - // 绘制connect区域 - let { connectedType, connectedX, connectedY, connectedStyle } = attribute; - const da: any[] = []; - if (connect) { - if (isArray(defaultAttribute)) { - connectedType = connectedType ?? defaultAttribute[0].connectedType ?? defaultAttribute[1].connectedType; - connectedX = connectedX ?? defaultAttribute[0].connectedX ?? defaultAttribute[1].connectedX; - connectedY = connectedY ?? defaultAttribute[0].connectedY ?? defaultAttribute[1].connectedY; - connectedStyle = connectedStyle ?? defaultAttribute[0].connectedStyle ?? defaultAttribute[1].connectedStyle; - } else { - connectedType = connectedType ?? defaultAttribute.connectedType; - connectedX = connectedX ?? defaultAttribute.connectedX; - connectedY = connectedY ?? defaultAttribute.connectedY; - connectedStyle = connectedStyle ?? defaultAttribute.connectedStyle; - } - - // 如果有非法值就是none - if (connectedType !== 'connect' && connectedType !== 'zero') { - connectedType = 'none'; - } - - if (isArray(defaultAttribute)) { - defaultAttribute.forEach(i => da.push(i)); - } else { - da.push(defaultAttribute); - } - da.push(attribute); - } - - if (connect && connectedType === 'none') { - return false; - } context.beginPath(); @@ -606,11 +555,7 @@ export class DefaultCanvasAreaRender extends BaseRender implements IGraph offsetX, offsetY, offsetZ, - direction, - drawConnect: connect, - mode: connectedType, - zeroX: connectedX, - zeroY: connectedY + direction }); this.beforeRenderStep( @@ -638,13 +583,7 @@ export class DefaultCanvasAreaRender extends BaseRender implements IGraph if (fillCb) { fillCb(context, attribute, defaultAttribute); } else if (fillOpacity) { - context.setCommonStyle( - area, - connect ? connectedStyle : attribute, - originX - offsetX, - originY - offsetY, - connect ? da : defaultAttribute - ); + context.setCommonStyle(area, attribute, originX - offsetX, originY - offsetY, defaultAttribute); context.fill(); } } @@ -667,21 +606,11 @@ export class DefaultCanvasAreaRender extends BaseRender implements IGraph { offsetX, offsetY, - offsetZ, - drawConnect: connect, - mode: connectedType, - zeroX: connectedX, - zeroY: connectedY + offsetZ } ); } - context.setStrokeStyle( - area, - connect ? connectedStyle : attribute, - originX - offsetX, - originY - offsetY, - connect ? da : defaultAttribute - ); + context.setStrokeStyle(area, attribute, originX - offsetX, originY - offsetY, defaultAttribute); context.stroke(); } } diff --git a/packages/vrender-core/src/render/contributions/render/line-render.ts b/packages/vrender-core/src/render/contributions/render/line-render.ts index cdbc27e22..ed7730d8d 100644 --- a/packages/vrender-core/src/render/contributions/render/line-render.ts +++ b/packages/vrender-core/src/render/contributions/render/line-render.ts @@ -121,61 +121,6 @@ export class DefaultCanvasLineRender extends BaseRender implements IGraph context.stroke(); } } - - // 绘制connect区域 - let { connectedType, connectedX, connectedY, connectedStyle } = attribute; - if (isArray(defaultAttribute)) { - connectedType = connectedType ?? defaultAttribute[0].connectedType ?? defaultAttribute[1].connectedType; - connectedX = connectedX ?? defaultAttribute[0].connectedX ?? defaultAttribute[1].connectedX; - connectedY = connectedY ?? defaultAttribute[0].connectedY ?? defaultAttribute[1].connectedY; - connectedStyle = connectedStyle ?? defaultAttribute[0].connectedStyle ?? defaultAttribute[1].connectedStyle; - } else { - connectedType = connectedType ?? defaultAttribute.connectedType; - connectedX = connectedX ?? defaultAttribute.connectedX; - connectedY = connectedY ?? defaultAttribute.connectedY; - connectedStyle = connectedStyle ?? defaultAttribute.connectedStyle; - } - // 如果有非法值就是none - if (connectedType !== 'connect' && connectedType !== 'zero') { - connectedType = 'none'; - } - if (connectedType !== 'none') { - context.beginPath(); - drawSegments(context.camera ? context : context.nativeContext, cache, clipRange, clipRangeByDimension, { - offsetX, - offsetY, - offsetZ: z, - drawConnect: true, - mode: connectedType, - zeroX: connectedX, - zeroY: connectedY - }); - - const da = []; - if (isArray(defaultAttribute)) { - defaultAttribute.forEach(i => da.push(i)); - } else { - da.push(defaultAttribute); - } - da.push(attribute); - - if (fill !== false) { - if (fillCb) { - fillCb(context, attribute, defaultAttribute); - } else if (fillOpacity) { - context.setCommonStyle(line, connectedStyle, originX - offsetX, originY - offsetY, da); - context.fill(); - } - } - if (stroke !== false) { - if (strokeCb) { - strokeCb(context, attribute, defaultAttribute); - } else if (strokeOpacity) { - context.setStrokeStyle(line, connectedStyle, originX - offsetX, originY - offsetY, da); - context.stroke(); - } - } - } return !!ret; } @@ -266,7 +211,8 @@ export class DefaultCanvasLineRender extends BaseRender implements IGraph segments, points, closePath, - curveTension = lineAttribute.curveTension + curveTension = lineAttribute.curveTension, + connectedType = lineAttribute.connectedType } = line.attribute; const data = this.valid(line, lineAttribute, fillCb, strokeCb); @@ -301,6 +247,13 @@ export class DefaultCanvasLineRender extends BaseRender implements IGraph } // const { fVisible, sVisible, doFill, doStroke } = data; + function parsePoint(points: IPointLike[], connectedType: 'none' | 'connect') { + if (connectedType === 'none') { + return points; + } + return points.filter(p => p.defined !== false); + } + // 更新cache if (line.shouldUpdateShape()) { const { points, segments } = line.attribute; @@ -335,7 +288,7 @@ export class DefaultCanvasLineRender extends BaseRender implements IGraph startPoint.y = lastSeg.endY; startPoint.defined = lastSeg.curves[lastSeg.curves.length - 1].defined; } - const data = calcLineCache(seg.points, curveType, { + const data = calcLineCache(parsePoint(seg.points, connectedType), curveType, { startPoint, curveTension }); @@ -362,7 +315,7 @@ export class DefaultCanvasLineRender extends BaseRender implements IGraph line.cache[line.cache.length - 1] && line.cache[line.cache.length - 1].lineTo(startP.x, startP.y, true); } } else if (points && points.length) { - line.cache = calcLineCache(_points, curveType, { curveTension }); + line.cache = calcLineCache(parsePoint(_points, connectedType), curveType, { curveTension }); } else { line.cache = null; line.clearUpdateShapeTag(); From baf9739493c79a34e14c02cd0895ed6f83f8929f Mon Sep 17 00:00:00 2001 From: zhouxinyu Date: Mon, 13 Jan 2025 11:21:18 +0800 Subject: [PATCH 23/24] chore: edit change log --- .../vrender-core/feat-line-connect_2025-01-10-05-20.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/changes/@visactor/vrender-core/feat-line-connect_2025-01-10-05-20.json b/common/changes/@visactor/vrender-core/feat-line-connect_2025-01-10-05-20.json index 5bcce79de..a87d67f92 100644 --- a/common/changes/@visactor/vrender-core/feat-line-connect_2025-01-10-05-20.json +++ b/common/changes/@visactor/vrender-core/feat-line-connect_2025-01-10-05-20.json @@ -2,7 +2,7 @@ "changes": [ { "packageName": "@visactor/vrender-core", - "comment": "feat: change effect for connectedType, closed #1660", + "comment": "feat: change effect for connectedType, closed #1660 ", "type": "none" } ], From c5a5dd74cf634d26d21667755068fe4c0731a636 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 13 Jan 2025 03:27:46 +0000 Subject: [PATCH 24/24] build: prelease version 0.21.9 --- .../feat-gif-image_2024-11-14-08-33.json | 10 ------- ...-duplicated-label-id_2025-01-07-06-46.json | 10 ------- .../feat-line-connect_2025-01-10-05-20.json | 10 ------- ...animate-with-noStage_2024-12-30-09-41.json | 10 ------- ...fix-gif-image-render_2025-01-08-10-09.json | 10 ------- common/config/rush/pnpm-lock.yaml | 26 +++++++++---------- common/config/rush/version-policies.json | 2 +- docs/package.json | 2 +- packages/react-vrender-utils/CHANGELOG.json | 6 +++++ packages/react-vrender-utils/CHANGELOG.md | 7 ++++- packages/react-vrender-utils/package.json | 6 ++--- packages/react-vrender/CHANGELOG.json | 6 +++++ packages/react-vrender/CHANGELOG.md | 7 ++++- packages/react-vrender/package.json | 4 +-- packages/vrender-components/CHANGELOG.json | 15 +++++++++++ packages/vrender-components/CHANGELOG.md | 10 ++++++- packages/vrender-components/package.json | 6 ++--- packages/vrender-core/CHANGELOG.json | 15 +++++++++++ packages/vrender-core/CHANGELOG.md | 10 ++++++- packages/vrender-core/package.json | 2 +- packages/vrender-kits/CHANGELOG.json | 12 +++++++++ packages/vrender-kits/CHANGELOG.md | 9 ++++++- packages/vrender-kits/package.json | 4 +-- packages/vrender/CHANGELOG.json | 6 +++++ packages/vrender/CHANGELOG.md | 7 ++++- packages/vrender/package.json | 6 ++--- tools/bugserver-trigger/package.json | 8 +++--- 27 files changed, 137 insertions(+), 89 deletions(-) delete mode 100644 common/changes/@visactor/vrender-components/feat-gif-image_2024-11-14-08-33.json delete mode 100644 common/changes/@visactor/vrender-components/fix-duplicated-label-id_2025-01-07-06-46.json delete mode 100644 common/changes/@visactor/vrender-core/feat-line-connect_2025-01-10-05-20.json delete mode 100644 common/changes/@visactor/vrender-core/fix-animate-with-noStage_2024-12-30-09-41.json delete mode 100644 common/changes/@visactor/vrender-kits/fix-gif-image-render_2025-01-08-10-09.json diff --git a/common/changes/@visactor/vrender-components/feat-gif-image_2024-11-14-08-33.json b/common/changes/@visactor/vrender-components/feat-gif-image_2024-11-14-08-33.json deleted file mode 100644 index beccac877..000000000 --- a/common/changes/@visactor/vrender-components/feat-gif-image_2024-11-14-08-33.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "changes": [ - { - "packageName": "@visactor/vrender-components", - "comment": "feat: add GifImage component", - "type": "none" - } - ], - "packageName": "@visactor/vrender-components" -} \ No newline at end of file diff --git a/common/changes/@visactor/vrender-components/fix-duplicated-label-id_2025-01-07-06-46.json b/common/changes/@visactor/vrender-components/fix-duplicated-label-id_2025-01-07-06-46.json deleted file mode 100644 index 592dab035..000000000 --- a/common/changes/@visactor/vrender-components/fix-duplicated-label-id_2025-01-07-06-46.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "changes": [ - { - "packageName": "@visactor/vrender-components", - "comment": "fix: fix duplicate label issue after custom filtering with label dataFilter", - "type": "none" - } - ], - "packageName": "@visactor/vrender-components" -} \ No newline at end of file diff --git a/common/changes/@visactor/vrender-core/feat-line-connect_2025-01-10-05-20.json b/common/changes/@visactor/vrender-core/feat-line-connect_2025-01-10-05-20.json deleted file mode 100644 index a87d67f92..000000000 --- a/common/changes/@visactor/vrender-core/feat-line-connect_2025-01-10-05-20.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "changes": [ - { - "packageName": "@visactor/vrender-core", - "comment": "feat: change effect for connectedType, closed #1660 ", - "type": "none" - } - ], - "packageName": "@visactor/vrender-core" -} diff --git a/common/changes/@visactor/vrender-core/fix-animate-with-noStage_2024-12-30-09-41.json b/common/changes/@visactor/vrender-core/fix-animate-with-noStage_2024-12-30-09-41.json deleted file mode 100644 index 1e808ce1b..000000000 --- a/common/changes/@visactor/vrender-core/fix-animate-with-noStage_2024-12-30-09-41.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "changes": [ - { - "packageName": "@visactor/vrender-core", - "comment": "fix: fix issue with animate error when graphic.stage is null", - "type": "none" - } - ], - "packageName": "@visactor/vrender-core" -} \ No newline at end of file diff --git a/common/changes/@visactor/vrender-kits/fix-gif-image-render_2025-01-08-10-09.json b/common/changes/@visactor/vrender-kits/fix-gif-image-render_2025-01-08-10-09.json deleted file mode 100644 index 5c31e0437..000000000 --- a/common/changes/@visactor/vrender-kits/fix-gif-image-render_2025-01-08-10-09.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "changes": [ - { - "packageName": "@visactor/vrender-kits", - "comment": "fix: fix drawShape function in gif-image render ", - "type": "none" - } - ], - "packageName": "@visactor/vrender-kits" -} \ No newline at end of file diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index e37606471..3215f8a0f 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -14,7 +14,7 @@ importers: '@types/react-dom': ^18.0.0 '@visactor/vchart': 1.3.0 '@visactor/vgrammar': ~0.5.7 - '@visactor/vrender': workspace:0.21.8 + '@visactor/vrender': workspace:0.21.9 '@visactor/vutils': ~0.19.3 '@vitejs/plugin-react': 3.1.0 axios: ^1.4.0 @@ -71,7 +71,7 @@ importers: '@types/react': ^18.0.0 '@types/react-dom': ^18.0.0 '@types/react-reconciler': ^0.28.2 - '@visactor/vrender': workspace:0.21.8 + '@visactor/vrender': workspace:0.21.9 '@visactor/vutils': ~0.19.3 '@vitejs/plugin-react': 3.1.0 cross-env: ^7.0.3 @@ -111,8 +111,8 @@ importers: '@rushstack/eslint-patch': ~1.1.4 '@types/react': ^18.0.0 '@types/react-dom': ^18.0.0 - '@visactor/react-vrender': workspace:0.21.8 - '@visactor/vrender': workspace:0.21.8 + '@visactor/react-vrender': workspace:0.21.9 + '@visactor/vrender': workspace:0.21.9 '@visactor/vutils': ~0.19.3 '@vitejs/plugin-react': 3.1.0 cross-env: ^7.0.3 @@ -153,8 +153,8 @@ importers: '@types/jest': ^26.0.0 '@types/react': ^18.0.0 '@types/react-dom': ^18.0.0 - '@visactor/vrender-core': workspace:0.21.8 - '@visactor/vrender-kits': workspace:0.21.8 + '@visactor/vrender-core': workspace:0.21.9 + '@visactor/vrender-kits': workspace:0.21.9 '@visactor/vutils': ~0.19.3 '@vitejs/plugin-react': 3.1.0 canvas: 2.11.2 @@ -200,8 +200,8 @@ importers: '@internal/ts-config': workspace:* '@rushstack/eslint-patch': ~1.1.4 '@types/jest': ^26.0.0 - '@visactor/vrender-core': workspace:0.21.8 - '@visactor/vrender-kits': workspace:0.21.8 + '@visactor/vrender-core': workspace:0.21.9 + '@visactor/vrender-kits': workspace:0.21.9 '@visactor/vscale': ~0.19.3 '@visactor/vutils': ~0.19.3 cross-env: ^7.0.3 @@ -287,7 +287,7 @@ importers: '@types/node-fetch': 2.6.4 '@types/react': ^18.0.0 '@types/react-dom': ^18.0.0 - '@visactor/vrender-core': workspace:0.21.8 + '@visactor/vrender-core': workspace:0.21.9 '@visactor/vutils': ~0.19.3 '@vitejs/plugin-react': 3.1.0 canvas: 2.11.2 @@ -371,10 +371,10 @@ importers: '@rushstack/eslint-patch': ~1.1.4 '@types/node': '*' '@types/node-fetch': 2.6.4 - '@visactor/vrender': workspace:0.21.8 - '@visactor/vrender-components': workspace:0.21.8 - '@visactor/vrender-core': workspace:0.21.8 - '@visactor/vrender-kits': workspace:0.21.8 + '@visactor/vrender': workspace:0.21.9 + '@visactor/vrender-components': workspace:0.21.9 + '@visactor/vrender-core': workspace:0.21.9 + '@visactor/vrender-kits': workspace:0.21.9 cross-env: ^7.0.3 eslint: ~8.18.0 form-data: ~4.0.0 diff --git a/common/config/rush/version-policies.json b/common/config/rush/version-policies.json index 6632da0a9..e658de8f6 100644 --- a/common/config/rush/version-policies.json +++ b/common/config/rush/version-policies.json @@ -1 +1 @@ -[{"definitionName":"lockStepVersion","policyName":"vrenderMain","version":"0.21.8","nextBump":"patch"}] +[{"definitionName":"lockStepVersion","policyName":"vrenderMain","version":"0.21.9","nextBump":"patch"}] diff --git a/docs/package.json b/docs/package.json index 7ea72f2f2..b86439163 100644 --- a/docs/package.json +++ b/docs/package.json @@ -13,7 +13,7 @@ "@visactor/vchart": "1.3.0", "@visactor/vutils": "~0.19.3", "@visactor/vgrammar": "~0.5.7", - "@visactor/vrender": "workspace:0.21.8", + "@visactor/vrender": "workspace:0.21.9", "markdown-it": "^13.0.0", "highlight.js": "^11.8.0", "axios": "^1.4.0", diff --git a/packages/react-vrender-utils/CHANGELOG.json b/packages/react-vrender-utils/CHANGELOG.json index 54631d1f6..5a84f2c26 100644 --- a/packages/react-vrender-utils/CHANGELOG.json +++ b/packages/react-vrender-utils/CHANGELOG.json @@ -1,6 +1,12 @@ { "name": "@visactor/react-vrender-utils", "entries": [ + { + "version": "0.21.9", + "tag": "@visactor/react-vrender-utils_v0.21.9", + "date": "Mon, 13 Jan 2025 03:23:50 GMT", + "comments": {} + }, { "version": "0.21.8", "tag": "@visactor/react-vrender-utils_v0.21.8", diff --git a/packages/react-vrender-utils/CHANGELOG.md b/packages/react-vrender-utils/CHANGELOG.md index 260e2690d..d7f3504e0 100644 --- a/packages/react-vrender-utils/CHANGELOG.md +++ b/packages/react-vrender-utils/CHANGELOG.md @@ -1,6 +1,11 @@ # Change Log - @visactor/react-vrender-utils -This log was last generated on Mon, 06 Jan 2025 11:07:36 GMT and should not be manually modified. +This log was last generated on Mon, 13 Jan 2025 03:23:50 GMT and should not be manually modified. + +## 0.21.9 +Mon, 13 Jan 2025 03:23:50 GMT + +_Version update only_ ## 0.21.8 Mon, 06 Jan 2025 11:07:36 GMT diff --git a/packages/react-vrender-utils/package.json b/packages/react-vrender-utils/package.json index 0b3682226..0d7f68320 100644 --- a/packages/react-vrender-utils/package.json +++ b/packages/react-vrender-utils/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/react-vrender-utils", - "version": "0.21.8", + "version": "0.21.9", "description": "", "sideEffects": false, "main": "cjs/index.js", @@ -24,8 +24,8 @@ "react-dom": "^18.2.0" }, "dependencies": { - "@visactor/vrender": "workspace:0.21.8", - "@visactor/react-vrender": "workspace:0.21.8", + "@visactor/vrender": "workspace:0.21.9", + "@visactor/react-vrender": "workspace:0.21.9", "@visactor/vutils": "~0.19.3", "react-reconciler": "^0.29.0", "tslib": "^2.3.1" diff --git a/packages/react-vrender/CHANGELOG.json b/packages/react-vrender/CHANGELOG.json index c4c829daf..31375da1c 100644 --- a/packages/react-vrender/CHANGELOG.json +++ b/packages/react-vrender/CHANGELOG.json @@ -1,6 +1,12 @@ { "name": "@visactor/react-vrender", "entries": [ + { + "version": "0.21.9", + "tag": "@visactor/react-vrender_v0.21.9", + "date": "Mon, 13 Jan 2025 03:23:50 GMT", + "comments": {} + }, { "version": "0.21.8", "tag": "@visactor/react-vrender_v0.21.8", diff --git a/packages/react-vrender/CHANGELOG.md b/packages/react-vrender/CHANGELOG.md index e3543eaa5..87c3f10df 100644 --- a/packages/react-vrender/CHANGELOG.md +++ b/packages/react-vrender/CHANGELOG.md @@ -1,6 +1,11 @@ # Change Log - @visactor/react-vrender -This log was last generated on Mon, 06 Jan 2025 11:07:36 GMT and should not be manually modified. +This log was last generated on Mon, 13 Jan 2025 03:23:50 GMT and should not be manually modified. + +## 0.21.9 +Mon, 13 Jan 2025 03:23:50 GMT + +_Version update only_ ## 0.21.8 Mon, 06 Jan 2025 11:07:36 GMT diff --git a/packages/react-vrender/package.json b/packages/react-vrender/package.json index e45d5de74..09ddbda97 100644 --- a/packages/react-vrender/package.json +++ b/packages/react-vrender/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/react-vrender", - "version": "0.21.8", + "version": "0.21.9", "description": "", "sideEffects": false, "main": "cjs/index.js", @@ -23,7 +23,7 @@ "react": "^18.2.0" }, "dependencies": { - "@visactor/vrender": "workspace:0.21.8", + "@visactor/vrender": "workspace:0.21.9", "@visactor/vutils": "~0.19.3", "react-reconciler": "^0.29.0", "tslib": "^2.3.1" diff --git a/packages/vrender-components/CHANGELOG.json b/packages/vrender-components/CHANGELOG.json index 9364e6029..76072a69f 100644 --- a/packages/vrender-components/CHANGELOG.json +++ b/packages/vrender-components/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@visactor/vrender-components", "entries": [ + { + "version": "0.21.9", + "tag": "@visactor/vrender-components_v0.21.9", + "date": "Mon, 13 Jan 2025 03:23:50 GMT", + "comments": { + "none": [ + { + "comment": "feat: add GifImage component" + }, + { + "comment": "fix: fix duplicate label issue after custom filtering with label dataFilter" + } + ] + } + }, { "version": "0.21.8", "tag": "@visactor/vrender-components_v0.21.8", diff --git a/packages/vrender-components/CHANGELOG.md b/packages/vrender-components/CHANGELOG.md index cffd968aa..ace5b1e23 100644 --- a/packages/vrender-components/CHANGELOG.md +++ b/packages/vrender-components/CHANGELOG.md @@ -1,6 +1,14 @@ # Change Log - @visactor/vrender-components -This log was last generated on Mon, 06 Jan 2025 11:07:36 GMT and should not be manually modified. +This log was last generated on Mon, 13 Jan 2025 03:23:50 GMT and should not be manually modified. + +## 0.21.9 +Mon, 13 Jan 2025 03:23:50 GMT + +### Updates + +- feat: add GifImage component +- fix: fix duplicate label issue after custom filtering with label dataFilter ## 0.21.8 Mon, 06 Jan 2025 11:07:36 GMT diff --git a/packages/vrender-components/package.json b/packages/vrender-components/package.json index 499396d6a..30b9baf67 100644 --- a/packages/vrender-components/package.json +++ b/packages/vrender-components/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/vrender-components", - "version": "0.21.8", + "version": "0.21.9", "description": "components library for dp visualization", "sideEffects": false, "main": "cjs/index.js", @@ -27,8 +27,8 @@ "dependencies": { "@visactor/vutils": "~0.19.3", "@visactor/vscale": "~0.19.3", - "@visactor/vrender-core": "workspace:0.21.8", - "@visactor/vrender-kits": "workspace:0.21.8" + "@visactor/vrender-core": "workspace:0.21.9", + "@visactor/vrender-kits": "workspace:0.21.9" }, "devDependencies": { "@internal/bundler": "workspace:*", diff --git a/packages/vrender-core/CHANGELOG.json b/packages/vrender-core/CHANGELOG.json index 4b4ed0940..d9c98272d 100644 --- a/packages/vrender-core/CHANGELOG.json +++ b/packages/vrender-core/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@visactor/vrender-core", "entries": [ + { + "version": "0.21.9", + "tag": "@visactor/vrender-core_v0.21.9", + "date": "Mon, 13 Jan 2025 03:23:50 GMT", + "comments": { + "none": [ + { + "comment": "feat: change effect for connectedType, closed #1660 " + }, + { + "comment": "fix: fix issue with animate error when graphic.stage is null" + } + ] + } + }, { "version": "0.21.8", "tag": "@visactor/vrender-core_v0.21.8", diff --git a/packages/vrender-core/CHANGELOG.md b/packages/vrender-core/CHANGELOG.md index 14d8f20a0..7050da819 100644 --- a/packages/vrender-core/CHANGELOG.md +++ b/packages/vrender-core/CHANGELOG.md @@ -1,6 +1,14 @@ # Change Log - @visactor/vrender-core -This log was last generated on Mon, 06 Jan 2025 11:07:36 GMT and should not be manually modified. +This log was last generated on Mon, 13 Jan 2025 03:23:50 GMT and should not be manually modified. + +## 0.21.9 +Mon, 13 Jan 2025 03:23:50 GMT + +### Updates + +- feat: change effect for connectedType, closed #1660 +- fix: fix issue with animate error when graphic.stage is null ## 0.21.8 Mon, 06 Jan 2025 11:07:36 GMT diff --git a/packages/vrender-core/package.json b/packages/vrender-core/package.json index 0c5e24ea7..c4812984a 100644 --- a/packages/vrender-core/package.json +++ b/packages/vrender-core/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/vrender-core", - "version": "0.21.8", + "version": "0.21.9", "description": "", "sideEffects": [ "./src/modules.ts", diff --git a/packages/vrender-kits/CHANGELOG.json b/packages/vrender-kits/CHANGELOG.json index 52031d5d6..ebdb7e657 100644 --- a/packages/vrender-kits/CHANGELOG.json +++ b/packages/vrender-kits/CHANGELOG.json @@ -1,6 +1,18 @@ { "name": "@visactor/vrender-kits", "entries": [ + { + "version": "0.21.9", + "tag": "@visactor/vrender-kits_v0.21.9", + "date": "Mon, 13 Jan 2025 03:23:50 GMT", + "comments": { + "none": [ + { + "comment": "fix: fix drawShape function in gif-image render " + } + ] + } + }, { "version": "0.21.8", "tag": "@visactor/vrender-kits_v0.21.8", diff --git a/packages/vrender-kits/CHANGELOG.md b/packages/vrender-kits/CHANGELOG.md index 5b8740064..3a86cdf07 100644 --- a/packages/vrender-kits/CHANGELOG.md +++ b/packages/vrender-kits/CHANGELOG.md @@ -1,6 +1,13 @@ # Change Log - @visactor/vrender-kits -This log was last generated on Mon, 06 Jan 2025 11:07:36 GMT and should not be manually modified. +This log was last generated on Mon, 13 Jan 2025 03:23:50 GMT and should not be manually modified. + +## 0.21.9 +Mon, 13 Jan 2025 03:23:50 GMT + +### Updates + +- fix: fix drawShape function in gif-image render ## 0.21.8 Mon, 06 Jan 2025 11:07:36 GMT diff --git a/packages/vrender-kits/package.json b/packages/vrender-kits/package.json index 61d528b67..9c94d8b4e 100644 --- a/packages/vrender-kits/package.json +++ b/packages/vrender-kits/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/vrender-kits", - "version": "0.21.8", + "version": "0.21.9", "description": "", "sideEffects": false, "main": "cjs/index.js", @@ -21,7 +21,7 @@ }, "dependencies": { "@visactor/vutils": "~0.19.3", - "@visactor/vrender-core": "workspace:0.21.8", + "@visactor/vrender-core": "workspace:0.21.9", "@resvg/resvg-js": "2.4.1", "roughjs": "4.5.2", "gifuct-js": "2.1.2" diff --git a/packages/vrender/CHANGELOG.json b/packages/vrender/CHANGELOG.json index 6ec53716f..da1eb65b8 100644 --- a/packages/vrender/CHANGELOG.json +++ b/packages/vrender/CHANGELOG.json @@ -1,6 +1,12 @@ { "name": "@visactor/vrender", "entries": [ + { + "version": "0.21.9", + "tag": "@visactor/vrender_v0.21.9", + "date": "Mon, 13 Jan 2025 03:23:50 GMT", + "comments": {} + }, { "version": "0.21.8", "tag": "@visactor/vrender_v0.21.8", diff --git a/packages/vrender/CHANGELOG.md b/packages/vrender/CHANGELOG.md index ead7c60c1..760cd7cf6 100644 --- a/packages/vrender/CHANGELOG.md +++ b/packages/vrender/CHANGELOG.md @@ -1,6 +1,11 @@ # Change Log - @visactor/vrender -This log was last generated on Mon, 06 Jan 2025 11:07:36 GMT and should not be manually modified. +This log was last generated on Mon, 13 Jan 2025 03:23:50 GMT and should not be manually modified. + +## 0.21.9 +Mon, 13 Jan 2025 03:23:50 GMT + +_Version update only_ ## 0.21.8 Mon, 06 Jan 2025 11:07:36 GMT diff --git a/packages/vrender/package.json b/packages/vrender/package.json index eecfab3db..a158c1dbe 100644 --- a/packages/vrender/package.json +++ b/packages/vrender/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/vrender", - "version": "0.21.8", + "version": "0.21.9", "description": "", "sideEffects": true, "main": "cjs/index.js", @@ -24,8 +24,8 @@ "test-watch": "cross-env DEBUG_MODE=1 jest --watch" }, "dependencies": { - "@visactor/vrender-core": "workspace:0.21.8", - "@visactor/vrender-kits": "workspace:0.21.8" + "@visactor/vrender-core": "workspace:0.21.9", + "@visactor/vrender-kits": "workspace:0.21.9" }, "devDependencies": { "@internal/bundler": "workspace:*", diff --git a/tools/bugserver-trigger/package.json b/tools/bugserver-trigger/package.json index 831781f91..60f4eed9d 100644 --- a/tools/bugserver-trigger/package.json +++ b/tools/bugserver-trigger/package.json @@ -8,10 +8,10 @@ "ci": "ts-node --transpileOnly --skipProject ./scripts/trigger-test.ts" }, "dependencies": { - "@visactor/vrender": "workspace:0.21.8", - "@visactor/vrender-core": "workspace:0.21.8", - "@visactor/vrender-kits": "workspace:0.21.8", - "@visactor/vrender-components": "workspace:0.21.8" + "@visactor/vrender": "workspace:0.21.9", + "@visactor/vrender-core": "workspace:0.21.9", + "@visactor/vrender-kits": "workspace:0.21.9", + "@visactor/vrender-components": "workspace:0.21.9" }, "devDependencies": { "@rushstack/eslint-patch": "~1.1.4",