diff --git a/common/changes/@visactor/vrender-kits/fix-gesture-compatible_2024-12-23-09-54.json b/common/changes/@visactor/vrender-kits/fix-gesture-compatible_2024-12-23-09-54.json new file mode 100644 index 000000000..66f46320a --- /dev/null +++ b/common/changes/@visactor/vrender-kits/fix-gesture-compatible_2024-12-23-09-54.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vrender-kits", + "comment": "fix: fix issue with gesture emitEvent when gesture is released", + "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 cd415a7e5..e3107517a 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.1 + '@visactor/vrender': workspace:0.21.3 '@visactor/vutils': ~0.19.2 '@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.1 + '@visactor/vrender': workspace:0.21.3 '@visactor/vutils': ~0.19.2 '@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.1 - '@visactor/vrender': workspace:0.21.1 + '@visactor/react-vrender': workspace:0.21.3 + '@visactor/vrender': workspace:0.21.3 '@visactor/vutils': ~0.19.2 '@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.1 - '@visactor/vrender-kits': workspace:0.21.1 + '@visactor/vrender-core': workspace:0.21.3 + '@visactor/vrender-kits': workspace:0.21.3 '@visactor/vutils': ~0.19.2 '@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.1 - '@visactor/vrender-kits': workspace:0.21.1 + '@visactor/vrender-core': workspace:0.21.3 + '@visactor/vrender-kits': workspace:0.21.3 '@visactor/vscale': ~0.19.2 '@visactor/vutils': ~0.19.2 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.1 + '@visactor/vrender-core': workspace:0.21.3 '@visactor/vutils': ~0.19.2 '@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.1 - '@visactor/vrender-components': workspace:0.21.1 - '@visactor/vrender-core': workspace:0.21.1 - '@visactor/vrender-kits': workspace:0.21.1 + '@visactor/vrender': workspace:0.21.3 + '@visactor/vrender-components': workspace:0.21.3 + '@visactor/vrender-core': workspace:0.21.3 + '@visactor/vrender-kits': workspace:0.21.3 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 dc9457656..ae6d22b59 100644 --- a/common/config/rush/version-policies.json +++ b/common/config/rush/version-policies.json @@ -1 +1 @@ -[{"definitionName":"lockStepVersion","policyName":"vrenderMain","version":"0.21.1","nextBump":"patch"}] +[{"definitionName":"lockStepVersion","policyName":"vrenderMain","version":"0.21.3","nextBump":"patch"}] diff --git a/docs/assets/changelog/en/changelog.md b/docs/assets/changelog/en/changelog.md index 55ccf1058..09fb203e4 100644 --- a/docs/assets/changelog/en/changelog.md +++ b/docs/assets/changelog/en/changelog.md @@ -1,3 +1,28 @@ +# v0.21.3 + +2024-12-23 + + +**🆕 New feature** + +- **@visactor/vrender-components**: optimization legend layout in isHorizontal +- **@visactor/vrender-kits**: support loadFont +- **@visactor/vrender-core**: support loadFont +- **@visactor/vrender-core**: support penetrateEventList + +**🐛 Bug fix** + +- **@visactor/vrender-components**: axis break should filter ticks when set `tickStep` +- **@visactor/vrender-components**: obb autoHide should support autoHideSeparation(without rotate) +- **@visactor/vrender-components**: label overlapPadding not work correctly +- **@visactor/vrender-components**: optimize the performance of ticks in time-scale +- **@visactor/vrender-core**: fix issue with image stroke and background +- **@visactor/vrender-core**: fix issue with html when include interactive layer +- **@visactor/vrender-core**: fix issue with richtext not support setShadowBlendStyle +- **@visactor/vrender-core**: optimize the performance of ticks in time-scale + +[more detail about v0.21.3](https://github.com/VisActor/VRender/releases/tag/v0.21.3) + # v0.21.1 2024-12-05 diff --git a/docs/assets/changelog/zh/changelog.md b/docs/assets/changelog/zh/changelog.md index 0c0d11392..c1cac48e1 100644 --- a/docs/assets/changelog/zh/changelog.md +++ b/docs/assets/changelog/zh/changelog.md @@ -1,3 +1,28 @@ +# v0.21.3 + +2024-12-23 + + +**🆕 新增功能** + +- **@visactor/vrender-components**: optimization legend layout in isHorizontal +- **@visactor/vrender-kits**: support loadFont +- **@visactor/vrender-core**: support loadFont +- **@visactor/vrender-core**: support penetrateEventList + +**🐛 功能修复** + +- **@visactor/vrender-components**: axis break should filter ticks when set `tickStep` +- **@visactor/vrender-components**: obb autoHide should support autoHideSeparation(without rotate) +- **@visactor/vrender-components**: label overlapPadding not work correctly +- **@visactor/vrender-components**: optimize the performance of ticks in time-scale +- **@visactor/vrender-core**: fix issue with image stroke and background +- **@visactor/vrender-core**: fix issue with html when include interactive layer +- **@visactor/vrender-core**: fix issue with richtext not support setShadowBlendStyle +- **@visactor/vrender-core**: optimize the performance of ticks in time-scale + +[更多详情请查看 v0.21.3](https://github.com/VisActor/VRender/releases/tag/v0.21.3) + # v0.21.1 2024-12-05 diff --git a/docs/package.json b/docs/package.json index fa7473622..8fa171eb2 100644 --- a/docs/package.json +++ b/docs/package.json @@ -13,7 +13,7 @@ "@visactor/vchart": "1.3.0", "@visactor/vutils": "~0.19.2", "@visactor/vgrammar": "~0.5.7", - "@visactor/vrender": "workspace:0.21.1", + "@visactor/vrender": "workspace:0.21.3", "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 a64b11760..53e53d5b2 100644 --- a/packages/react-vrender-utils/CHANGELOG.json +++ b/packages/react-vrender-utils/CHANGELOG.json @@ -1,6 +1,18 @@ { "name": "@visactor/react-vrender-utils", "entries": [ + { + "version": "0.21.3", + "tag": "@visactor/react-vrender-utils_v0.21.3", + "date": "Mon, 23 Dec 2024 08:28:14 GMT", + "comments": {} + }, + { + "version": "0.21.2", + "tag": "@visactor/react-vrender-utils_v0.21.2", + "date": "Thu, 12 Dec 2024 10:23:51 GMT", + "comments": {} + }, { "version": "0.21.1", "tag": "@visactor/react-vrender-utils_v0.21.1", diff --git a/packages/react-vrender-utils/CHANGELOG.md b/packages/react-vrender-utils/CHANGELOG.md index 05ea94f90..ebff27066 100644 --- a/packages/react-vrender-utils/CHANGELOG.md +++ b/packages/react-vrender-utils/CHANGELOG.md @@ -1,6 +1,16 @@ # Change Log - @visactor/react-vrender-utils -This log was last generated on Thu, 05 Dec 2024 07:50:46 GMT and should not be manually modified. +This log was last generated on Mon, 23 Dec 2024 08:28:14 GMT and should not be manually modified. + +## 0.21.3 +Mon, 23 Dec 2024 08:28:14 GMT + +_Version update only_ + +## 0.21.2 +Thu, 12 Dec 2024 10:23:51 GMT + +_Version update only_ ## 0.21.1 Thu, 05 Dec 2024 07:50:46 GMT diff --git a/packages/react-vrender-utils/package.json b/packages/react-vrender-utils/package.json index bd36b627f..dcc8ba649 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.1", + "version": "0.21.3", "description": "", "sideEffects": false, "main": "cjs/index.js", @@ -24,8 +24,8 @@ "react-dom": "^18.2.0" }, "dependencies": { - "@visactor/vrender": "workspace:0.21.1", - "@visactor/react-vrender": "workspace:0.21.1", + "@visactor/vrender": "workspace:0.21.3", + "@visactor/react-vrender": "workspace:0.21.3", "@visactor/vutils": "~0.19.2", "react-reconciler": "^0.29.0", "tslib": "^2.3.1" diff --git a/packages/react-vrender/CHANGELOG.json b/packages/react-vrender/CHANGELOG.json index 68bf47c02..46f8e5aad 100644 --- a/packages/react-vrender/CHANGELOG.json +++ b/packages/react-vrender/CHANGELOG.json @@ -1,6 +1,18 @@ { "name": "@visactor/react-vrender", "entries": [ + { + "version": "0.21.3", + "tag": "@visactor/react-vrender_v0.21.3", + "date": "Mon, 23 Dec 2024 08:28:14 GMT", + "comments": {} + }, + { + "version": "0.21.2", + "tag": "@visactor/react-vrender_v0.21.2", + "date": "Thu, 12 Dec 2024 10:23:51 GMT", + "comments": {} + }, { "version": "0.21.1", "tag": "@visactor/react-vrender_v0.21.1", diff --git a/packages/react-vrender/CHANGELOG.md b/packages/react-vrender/CHANGELOG.md index 750bfc604..d0ce86e11 100644 --- a/packages/react-vrender/CHANGELOG.md +++ b/packages/react-vrender/CHANGELOG.md @@ -1,6 +1,16 @@ # Change Log - @visactor/react-vrender -This log was last generated on Thu, 05 Dec 2024 07:50:46 GMT and should not be manually modified. +This log was last generated on Mon, 23 Dec 2024 08:28:14 GMT and should not be manually modified. + +## 0.21.3 +Mon, 23 Dec 2024 08:28:14 GMT + +_Version update only_ + +## 0.21.2 +Thu, 12 Dec 2024 10:23:51 GMT + +_Version update only_ ## 0.21.1 Thu, 05 Dec 2024 07:50:46 GMT diff --git a/packages/react-vrender/package.json b/packages/react-vrender/package.json index 8be3ed039..59e8d9c97 100644 --- a/packages/react-vrender/package.json +++ b/packages/react-vrender/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/react-vrender", - "version": "0.21.1", + "version": "0.21.3", "description": "", "sideEffects": false, "main": "cjs/index.js", @@ -23,7 +23,7 @@ "react": "^18.2.0" }, "dependencies": { - "@visactor/vrender": "workspace:0.21.1", + "@visactor/vrender": "workspace:0.21.3", "@visactor/vutils": "~0.19.2", "react-reconciler": "^0.29.0", "tslib": "^2.3.1" diff --git a/packages/vrender-components/CHANGELOG.json b/packages/vrender-components/CHANGELOG.json index 658e5a182..8b32d7ece 100644 --- a/packages/vrender-components/CHANGELOG.json +++ b/packages/vrender-components/CHANGELOG.json @@ -1,6 +1,42 @@ { "name": "@visactor/vrender-components", "entries": [ + { + "version": "0.21.3", + "tag": "@visactor/vrender-components_v0.21.3", + "date": "Mon, 23 Dec 2024 08:28:14 GMT", + "comments": { + "none": [ + { + "comment": "feat: optimization legend layout in isHorizontal\n\n" + }, + { + "comment": "fix: axis break should filter ticks when set `tickStep`\n\n" + }, + { + "comment": "fix: obb autoHide should support autoHideSeparation(without rotate)" + }, + { + "comment": "fix: label overlapPadding not work correctly" + }, + { + "comment": "fix: optimize the performance of ticks in time-scale\n\n" + } + ] + } + }, + { + "version": "0.21.2", + "tag": "@visactor/vrender-components_v0.21.2", + "date": "Thu, 12 Dec 2024 10:23:51 GMT", + "comments": { + "none": [ + { + "comment": "feat: support 'inside-middle' position for line-data label" + } + ] + } + }, { "version": "0.21.1", "tag": "@visactor/vrender-components_v0.21.1", diff --git a/packages/vrender-components/CHANGELOG.md b/packages/vrender-components/CHANGELOG.md index 6734fc366..efad89fcc 100644 --- a/packages/vrender-components/CHANGELOG.md +++ b/packages/vrender-components/CHANGELOG.md @@ -1,6 +1,30 @@ # Change Log - @visactor/vrender-components -This log was last generated on Thu, 05 Dec 2024 07:50:47 GMT and should not be manually modified. +This log was last generated on Mon, 23 Dec 2024 08:28:14 GMT and should not be manually modified. + +## 0.21.3 +Mon, 23 Dec 2024 08:28:14 GMT + +### Updates + +- feat: optimization legend layout in isHorizontal + + +- fix: axis break should filter ticks when set `tickStep` + + +- fix: obb autoHide should support autoHideSeparation(without rotate) +- fix: label overlapPadding not work correctly +- fix: optimize the performance of ticks in time-scale + + + +## 0.21.2 +Thu, 12 Dec 2024 10:23:51 GMT + +### Updates + +- feat: support 'inside-middle' position for line-data label ## 0.21.1 Thu, 05 Dec 2024 07:50:47 GMT diff --git a/packages/vrender-components/__tests__/browser/examples/discrete-legend.ts b/packages/vrender-components/__tests__/browser/examples/discrete-legend.ts index c0792073f..68da1b9d1 100644 --- a/packages/vrender-components/__tests__/browser/examples/discrete-legend.ts +++ b/packages/vrender-components/__tests__/browser/examples/discrete-legend.ts @@ -1,6 +1,7 @@ import '@visactor/vrender'; import { DiscreteLegend, Pager } from '../../../src'; import render from '../../util/render'; +import { IGraphic } from '../../../../vrender-core/es/interface'; const hLegend = new DiscreteLegend({ x: 20, @@ -460,7 +461,158 @@ const vLegend = new DiscreteLegend({ // reversed: true }); -const stage = render([hLegend, vLegend, legend, disableTriggerEventLegend, hLegend2], 'main'); +const hLegend3 = new DiscreteLegend({ + x: 20, + y: 440, + + // ==== 测试使用 ==== + stroke: 'red', + // ==== 测试使用 end ==== + + maxWidth: 400, + maxRow: 1, + title: { + visible: true, + text: '水平布局', + padding: 4, + background: { + visible: true, + style: { + fill: 'red' + } + } + }, + item: { + focus: true, + // padding: [0, 20, 0, 0], + // width: 120, + shape: { + style: { + size: 8 + } + }, + value: { + alignRight: true, + style: { + fill: '#666', + fontWeight: 'bold' + } + }, + background: { + style: { + stroke: '#000', + lineWidth: 1 + } + } + }, + items: [ + { label: '苹果', shape: { fill: 'red', symbolType: 'circle' } }, + { label: '香蕉', shape: { fill: 'yellow', symbolType: 'square' } }, + { label: '橘子', shape: { fill: 'orange', symbolType: 'triangle' } }, + { label: '葡萄', shape: { fill: 'purple', symbolType: 'diamond' } }, + { label: '梨', shape: { fill: 'green', symbolType: 'star' } }, + { label: '苹果1', value: 100, shape: { fill: 'red', symbolType: 'circle' } }, + { label: '香蕉1', value: 100, shape: { fill: 'yellow', symbolType: 'square' } }, + { label: '橘子1', value: 100, shape: { fill: 'orange', symbolType: 'triangle' } }, + { label: '葡萄1', value: 100, shape: { fill: 'purple', symbolType: 'diamond' } }, + { label: '梨1', value: 100, shape: { fill: 'green', symbolType: 'star' } }, + { label: '苹果2', value: 100, shape: { fill: 'red', symbolType: 'circle' } }, + { label: '香蕉2', value: 100, shape: { fill: 'yellow', symbolType: 'square' } }, + { label: '橘子2', value: 100, shape: { fill: 'orange', symbolType: 'triangle' } }, + { label: '葡萄2', value: 100, shape: { fill: 'purple', symbolType: 'diamond' } }, + { label: '梨2', value: 100, shape: { fill: 'green', symbolType: 'star' } } + ], + allowAllCanceled: false, + pager: { + fill: 'red', + padding: 10 + } +}); + +const hLegend4 = new DiscreteLegend({ + x: 20, + y: 510, + + // ==== 测试使用 ==== + stroke: 'red', + // ==== 测试使用 end ==== + + maxWidth: 500, + maxHeight: 500, + title: { + visible: true, + text: '水平布局-不同行高', + padding: 4, + background: { + visible: true, + style: { + fill: 'red' + } + } + }, + items: [ + { + label: [ + '0啊实打实的啊实打实的啊实打实的啊实打实的啊实打实的啊实打实的', + '啊实打实的', + '啊实打实的', + '啊实打实的' + ], + shape: { + symbolType: 'square', + fillOpacity: 1, + fill: 'red' + } + }, + { + label: ['1'], + shape: { + symbolType: 'square', + fillOpacity: 1, + fill: 'blue' + } + }, + { + label: ['2', '啊实打实的'], + shape: { + symbolType: 'square', + fillOpacity: 1, + fill: 'green' + } + }, + { + label: ['3', 'a', 'b', 'c', 'd'], + shape: { + symbolType: 'square', + fillOpacity: 1, + fill: 'yellow' + } + } + ], + item: { + verticalAlign: 'top' + }, + allowAllCanceled: false, + autoPage: false, + pager: { + fill: 'red', + padding: 10 + } +}); + +const stage = render( + [hLegend, vLegend, legend, disableTriggerEventLegend, hLegend2, hLegend4] as unknown as IGraphic[], + 'main', + { + viewBox: { + x1: 50, + y1: 50, + x2: 550, + y2: 750 + }, + height: 800 + } +); vLegend.addEventListener('legendItemClick', e => { console.log(e, e.detail.currentSelected); diff --git a/packages/vrender-components/package.json b/packages/vrender-components/package.json index dcaa29858..da2c6a4f6 100644 --- a/packages/vrender-components/package.json +++ b/packages/vrender-components/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/vrender-components", - "version": "0.21.1", + "version": "0.21.3", "description": "components library for dp visualization", "sideEffects": false, "main": "cjs/index.js", @@ -27,8 +27,8 @@ "dependencies": { "@visactor/vutils": "~0.19.2", "@visactor/vscale": "~0.19.2", - "@visactor/vrender-core": "workspace:0.21.1", - "@visactor/vrender-kits": "workspace:0.21.1" + "@visactor/vrender-core": "workspace:0.21.3", + "@visactor/vrender-kits": "workspace:0.21.3" }, "devDependencies": { "@internal/bundler": "workspace:*", diff --git a/packages/vrender-components/src/axis/overlap/util.ts b/packages/vrender-components/src/axis/overlap/util.ts index d3326118a..47619eda0 100644 --- a/packages/vrender-components/src/axis/overlap/util.ts +++ b/packages/vrender-components/src/axis/overlap/util.ts @@ -53,14 +53,14 @@ export function itemIntersect(item1: IText, item2: IText) { } const DELTA_ANGLE = Math.sin(Math.PI / 10); -export function isAngleVertical(angle: number) { +export function isAngleVertical(angle: number, delta = DELTA_ANGLE) { const hasAngle = !isNil(angle) && angle !== 0; const cos = hasAngle ? Math.cos(angle) : 1; - return hasAngle && Math.abs(cos) <= DELTA_ANGLE; + return hasAngle && Math.abs(cos) <= delta; } -export function isAngleHorizontal(angle: number) { +export function isAngleHorizontal(angle: number, delta = DELTA_ANGLE) { const hasAngle = !isNil(angle) && angle !== 0; const sin = hasAngle ? Math.sin(angle) : 0; - return !hasAngle || Math.abs(sin) <= DELTA_ANGLE; + return !hasAngle || Math.abs(sin) <= delta; } diff --git a/packages/vrender-components/src/axis/tick-data/continuous.ts b/packages/vrender-components/src/axis/tick-data/continuous.ts index b1435d6d5..777203125 100644 --- a/packages/vrender-components/src/axis/tick-data/continuous.ts +++ b/packages/vrender-components/src/axis/tick-data/continuous.ts @@ -6,6 +6,16 @@ import type { ICartesianTickDataOpt, ILabelItem, ITickData, ITickDataOpt } from // eslint-disable-next-line no-duplicate-imports import { convertDomainToTickData, getCartesianLabelBounds } from './util'; import { textIntersect as intersect, hasOverlap } from '../util'; + +const filterTicksByBreak = (ticks: number[], breakDomains: [number, number][]) => { + return breakDomains && breakDomains.length + ? ticks.filter(tick => { + return breakDomains.every(breakDomain => { + return tick < breakDomain[0] || tick > breakDomain[1]; + }); + }) + : ticks; +}; function getScaleTicks( op: ITickDataOpt, scale: ContinuousScale, @@ -92,7 +102,10 @@ export const continuousTicks = (scale: ContinuousScale, op: ITickDataOpt): ITick let scaleTicks: number[]; if (isValid(tickStep)) { - scaleTicks = (scale as LinearScale).stepTicks(tickStep); + scaleTicks = filterTicksByBreak( + (scale as LinearScale).stepTicks(tickStep), + breakData && breakData() ? breakData().breakDomains : null + ); } else if (isValid(forceTickCount)) { scaleTicks = getScaleTicks(op, scale, forceTickCount, (count: number, subDomain?: [number, number]) => { if (subDomain && subDomain.length) { @@ -142,16 +155,35 @@ export const continuousTicks = (scale: ContinuousScale, op: ITickDataOpt): ITick // 判断重叠 if (op.coordinateType === 'cartesian' || (op.coordinateType === 'polar' && op.axisOrientType === 'radius')) { const { labelGap = 4, labelFlush } = op as ICartesianTickDataOpt; - let items = getCartesianLabelBounds(scale, scaleTicks, op as ICartesianTickDataOpt).map( - (bounds, i) => - ({ - AABBBounds: bounds, - value: scaleTicks[i] - } as ILabelItem) - ); - const source = [...items]; - const firstSourceItem = source[0]; - const lastSourceItem = last(source); + const MIN_FONT_SIZE = 6; + let items: ILabelItem[]; + // 刻度个数 > 像素个数的情况,先做一层预估,减少计算,避免卡死的情况 + if (scaleTicks.length * MIN_FONT_SIZE > rangeSize) { + const samplingScaleTicks: number[] = []; + const step = Math.floor((scaleTicks.length * MIN_FONT_SIZE) / rangeSize); + scaleTicks.forEach((tick, index) => { + if (index % step === 0 || index === scaleTicks.length - 1) { + samplingScaleTicks.push(tick); + } + }); + items = getCartesianLabelBounds(scale, samplingScaleTicks, op as ICartesianTickDataOpt).map( + (bounds, i) => + ({ + AABBBounds: bounds, + value: samplingScaleTicks[i] + } as ILabelItem) + ); + } else { + items = getCartesianLabelBounds(scale, scaleTicks, op as ICartesianTickDataOpt).map( + (bounds, i) => + ({ + AABBBounds: bounds, + value: scaleTicks[i] + } as ILabelItem) + ); + } + const firstSourceItem = items[0]; + const lastSourceItem = last(items); const samplingMethod = breakData && breakData() ? methods.greedy : methods.parity; // 由于轴截断后刻度会存在不均匀的情况,所以不能使用 parity 算法 while (items.length >= 3 && hasOverlap(items as any, labelGap)) { diff --git a/packages/vrender-components/src/axis/util.ts b/packages/vrender-components/src/axis/util.ts index 57888c7d4..53e8a4010 100644 --- a/packages/vrender-components/src/axis/util.ts +++ b/packages/vrender-components/src/axis/util.ts @@ -10,6 +10,7 @@ import { scale, length } from '../util'; import type { BreakSymbol } from './type'; import { DEFAULT_AXIS_BREAK_SYMBOL_STYLE } from './config'; import type { Point } from '../core/type'; +import { isAngleHorizontal } from './overlap/util'; // 和 vutils 版本不同 export const clampRadian = (angle: number = 0) => { @@ -152,14 +153,46 @@ export function getPolygonPath(points: Point[], closed: boolean) { } export function textIntersect(textA: IText, textB: IText, sep: number) { - let a: IBounds = textA.OBBBounds; - let b: IBounds = textB.OBBBounds; - if (a && b && !a.empty() && !b.empty()) { - return a.intersects(b); + let a: IBounds; + let b: IBounds; + // 注意:默认旋转角度一样 + const angle = textA.attribute?.angle; + const isHorizontal = isAngleHorizontal(angle, Number.EPSILON); + const isAABBIntersects = (textA: IText, textB: IText, sep: number) => { + a = textA.AABBBounds; + b = textB.AABBBounds; + return sep > Math.max(b.x1 - a.x2, a.x1 - b.x2, b.y1 - a.y2, a.y1 - b.y2); + }; + + // 水平文字可以直接用 AABB 包围盒计算 + if (isHorizontal) { + return isAABBIntersects(textA, textB, sep); + } + + a = textA.OBBBounds; + b = textB.OBBBounds; + + // 没有 OBB bounds 则用 AABB 包围盒计算 + if (!a || !b || a.empty() || b.empty()) { + return isAABBIntersects(textA, textB, sep); } - a = textA.AABBBounds; - b = textB.AABBBounds; - return sep > Math.max(b.x1 - a.x2, a.x1 - b.x2, b.y1 - a.y2, a.y1 - b.y2); + + // 非水平文字且有 OBB 包围盒 + // TODO: 待支持有旋转角度下的 sep 计算逻辑 + return a.intersects(b); + // const expandedTextA = textA.clone(); + // const boundsPaddingA = textA.attribute.boundsPadding ?? 0; + // expandedTextA.setAttributes({ + // boundsPadding: isNumber(boundsPaddingA) ? boundsPaddingA + sep / 2 : boundsPaddingA.map(v => v + sep / 2) + // }); + // const expandTextB = textB.clone(); + // const boundsPaddingB = textB.attribute.boundsPadding ?? 0; + + // expandTextB.setAttributes({ + // boundsPadding: isNumber(boundsPaddingB) ? boundsPaddingB + sep / 2 : boundsPaddingB.map(v => v + sep / 2) + // }); + + // return expandedTextA.OBBBounds.intersects(expandTextB.OBBBounds); } export function hasOverlap(items: IText[], pad: number): boolean { diff --git a/packages/vrender-components/src/label/base.ts b/packages/vrender-components/src/label/base.ts index a98b0d50a..918a90e5e 100644 --- a/packages/vrender-components/src/label/base.ts +++ b/packages/vrender-components/src/label/base.ts @@ -554,7 +554,7 @@ export class LabelBase extends AbstractComponent { bitmap.setRange(range); } else { if (clampForce) { - const placedAfterClampForce = this._processClampForce(text as IText, bmpTool, bitmap); + const placedAfterClampForce = this._processClampForce(text as IText, bmpTool, bitmap, overlapPadding); if (placedAfterClampForce) { continue; } @@ -569,11 +569,11 @@ export class LabelBase extends AbstractComponent { return result; } - protected _processClampForce(text: IText, bmpTool: BitmapTool, bitmap: Bitmap) { + protected _processClampForce(text: IText, bmpTool: BitmapTool, bitmap: Bitmap, overlapPadding = 0) { const { dy = 0, dx = 0 } = clampText(text as IText, bmpTool.width, bmpTool.height, bmpTool.padding); if (dx === 0 && dy === 0) { - if (canPlace(bmpTool, bitmap, text.AABBBounds)) { - // xy方向偏移都为0,意味着不考虑 overlapPadding 时,实际上可以放得下 + // 再次检查,若不考虑边界,仍然可以放得下,代表当前 text 没有与其他 text 重叠 + if (canPlace(bmpTool, bitmap, text.AABBBounds, false, overlapPadding)) { bitmap.setRange(boundToRange(bmpTool, text.AABBBounds, true)); return true; } @@ -689,7 +689,7 @@ export class LabelBase extends AbstractComponent { // 尝试向内挤压 if (!hasPlace && clampForce) { - const placedAfterClampForce = this._processClampForce(text as IText, bmpTool, bitmap); + const placedAfterClampForce = this._processClampForce(text as IText, bmpTool, bitmap, overlapPadding); if (placedAfterClampForce) { result.push(text); continue; @@ -709,8 +709,11 @@ export class LabelBase extends AbstractComponent { return (this.getRootNode() as IGroup).find(node => node.name === baseMarkGroupName, true) as IGroup; } - protected getGraphicBounds(graphic?: IGraphic, point?: Partial, position?: string): IBoundsLike; - protected getGraphicBounds(graphic?: IGraphic, point: Partial = {}): IBoundsLike { + protected getGraphicBounds( + graphic?: IGraphic, + point: Partial = {}, + position?: string + ): IBoundsLike { if (graphic) { if (graphic.attribute.visible !== false) { return graphic.AABBBounds; @@ -718,6 +721,15 @@ export class LabelBase extends AbstractComponent { const { x, y } = graphic.attribute; return { x1: x, x2: x, y1: y, y2: y } as IBoundsLike; } + if (point && position && position === 'inside-middle') { + const { x, y, x1 = x, y1 = y } = point; + return { + x1: (x + x1) / 2, + x2: (x + x1) / 2, + y1: (y + y1) / 2, + y2: (y + y1) / 2 + }; + } const { x, y } = point; return { x1: x, x2: x, y1: y, y2: y } as IBoundsLike; } diff --git a/packages/vrender-components/src/label/overlap/place.ts b/packages/vrender-components/src/label/overlap/place.ts index c8b1e2bb9..aa9f3260f 100644 --- a/packages/vrender-components/src/label/overlap/place.ts +++ b/packages/vrender-components/src/label/overlap/place.ts @@ -191,17 +191,17 @@ export function clampText( let dy = 0; // x 方向 - if (minX < minXWithPadding && maxX - minX <= width) { + if (minX < minXWithPadding) { dx = -minX; - } else if (maxX > maxXWithPadding && minX - (maxX - width) >= minXWithPadding) { - dx = width - maxX; + } else if (maxX > maxXWithPadding) { + dx = maxXWithPadding - maxX; } // y 方向 - if (minY < minYWithPadding && maxY - minY <= height) { + if (minY < minYWithPadding) { dy = -minY; - } else if (maxY > maxYWithPadding && minY - (maxY - height) >= minYWithPadding) { - dy = height - maxY; + } else if (maxY > maxYWithPadding) { + dy = maxYWithPadding - maxY; } return { dx, dy }; diff --git a/packages/vrender-components/src/label/overlap/shiftY.ts b/packages/vrender-components/src/label/overlap/shiftY.ts index b4cbfb9b7..0d108864b 100644 --- a/packages/vrender-components/src/label/overlap/shiftY.ts +++ b/packages/vrender-components/src/label/overlap/shiftY.ts @@ -185,7 +185,7 @@ export function shiftY(texts: IText[], option: IShiftYOption) { deltaYTolerance = Number.MAX_VALUE } = globalShiftY; for (let iter = 0; iter < maxIterations; iter++) { - texts.sort((a, b) => getY1(a) - getY1(b)); + texts.sort((a, b) => getY1Initial(a) - getY1Initial(b)); let error = 0; for (let i = 0; i < n - 1; i++) { const curText = texts[i]; diff --git a/packages/vrender-components/src/label/type.ts b/packages/vrender-components/src/label/type.ts index f8f316e4b..3c30021ff 100644 --- a/packages/vrender-components/src/label/type.ts +++ b/packages/vrender-components/src/label/type.ts @@ -104,11 +104,22 @@ export interface BaseLabelAttrs extends IGroupGraphicAttribute { /** 动画配置 */ animation?: ILabelAnimation | boolean; + /** + * 新增标签动画 + */ animationEnter?: ILabelUpdateAnimation | boolean; + /** + * 标签更新动画 + */ animationUpdate?: ILabelUpdateAnimation | ILabelUpdateChannelAnimation[] | boolean; + /** + * 标签被删除的动画配置 + */ animationExit?: ILabelExitAnimation | boolean; - // 排序 or 删减 + /** + * 数据过滤自定义函数,可以用于 排序 or 删减 + */ dataFilter?: (data: LabelItem[]) => LabelItem[]; /** 自定义布局函数 @@ -384,8 +395,9 @@ export interface LineDataLabelAttrs extends BaseLabelAttrs { /** * 标签位置 * @default 'top' + * @since 0.21.1 支持 'inside-middle' 在面积图元中显示在中间位置 */ - position?: Functional; + position?: Functional; } export interface PolygonLabelAttrs extends BaseLabelAttrs { diff --git a/packages/vrender-components/src/legend/discrete/discrete.ts b/packages/vrender-components/src/legend/discrete/discrete.ts index a6fb8c3d3..c1827a34d 100644 --- a/packages/vrender-components/src/legend/discrete/discrete.ts +++ b/packages/vrender-components/src/legend/discrete/discrete.ts @@ -234,7 +234,11 @@ export class DiscreteLegend extends LegendBase { lazyload, autoPage } = this.attribute as DiscreteLegendAttrs; - const { spaceCol = DEFAULT_ITEM_SPACE_COL, spaceRow = DEFAULT_ITEM_SPACE_ROW } = itemAttrs; + const { + spaceCol = DEFAULT_ITEM_SPACE_COL, + spaceRow = DEFAULT_ITEM_SPACE_ROW, + verticalAlign = 'middle' + } = itemAttrs; const itemsContainer = this._itemsContainer; const { items: legendItems, isHorizontal, startIndex, isScrollbar } = this._itemContext; @@ -245,6 +249,8 @@ export class DiscreteLegend extends LegendBase { let item: LegendItemDatum; let lastItemWidth = 0; + let lastLineHeight = 0; + const lastLineItemGroup: IGroup[] = []; for (let index = startIndex, len = legendItems.length; index < len; index++) { if (lazyload && pages > this._itemContext.currentPage * maxPages) { break; @@ -277,15 +283,32 @@ export class DiscreteLegend extends LegendBase { // 水平布局 if (isValid(maxWidth)) { if (isScrollbar && autoPage) { + // 不需要换行时 pages = Math.ceil((startX + itemWidth) / maxWidth); doWrap = pages > 1; } else if (startX + itemWidth > maxWidth) { + // 需要换行 doWrap = true; - + // 避免第一个元素就超出最大宽度,额外换了一行,所以限制 startX > 0 ? if (startX > 0) { + // 进行换行 + // 换行前,先将上一行的元素按照最大高度进行居中 + if (verticalAlign === 'middle' || verticalAlign === 'bottom') { + // eslint-disable-next-line no-loop-func + lastLineItemGroup.forEach(i => { + i.setAttributes({ + y: i.attribute.y + (lastLineHeight - i.attribute.height) / (verticalAlign === 'middle' ? 2 : 1) + }); + }); + } + pages += 1; startX = 0; - startY += itemHeight + spaceRow; + // 应该增加的是上一行的高度 而不是当前元素高度 + startY += lastLineHeight + spaceRow; + // 重置上一行的临时内容 + lastLineHeight = 0; + lastLineItemGroup.length = 0; } } } @@ -296,6 +319,9 @@ export class DiscreteLegend extends LegendBase { }); } startX += spaceCol + itemWidth; + // 此时记录当前行的最大高度 + lastLineHeight = Math.max(lastLineHeight, itemHeight); + lastLineItemGroup.push(itemGroup); } else { // 垂直布局 if (isValid(maxHeight)) { @@ -332,6 +358,15 @@ export class DiscreteLegend extends LegendBase { lastItemWidth = itemWidth; } + if (isHorizontal && (verticalAlign === 'middle' || verticalAlign === 'bottom')) { + // 水平布局 最后一行居中 + lastLineItemGroup.forEach(i => { + i.setAttributes({ + y: i.attribute.y + (lastLineHeight - i.attribute.height) / (verticalAlign === 'middle' ? 2 : 1) + }); + }); + } + this._itemContext.doWrap = doWrap; this._itemContext.startX = startX; this._itemContext.startY = startY; diff --git a/packages/vrender-components/src/legend/discrete/type.ts b/packages/vrender-components/src/legend/discrete/type.ts index 11b73f872..d31475a3d 100644 --- a/packages/vrender-components/src/legend/discrete/type.ts +++ b/packages/vrender-components/src/legend/discrete/type.ts @@ -208,6 +208,11 @@ export type LegendItem = { * 'right' 图标在右侧 */ align?: 'left' | 'right'; + /** + * @since 0.21.3 + * 水平方向时,一行中多个图例的垂直对齐方式 + */ + verticalAlign?: 'top' | 'middle' | 'bottom'; }; export type DiscreteLegendAttrs = { diff --git a/packages/vrender-core/CHANGELOG.json b/packages/vrender-core/CHANGELOG.json index 1d699eb09..5916fd7e3 100644 --- a/packages/vrender-core/CHANGELOG.json +++ b/packages/vrender-core/CHANGELOG.json @@ -1,6 +1,45 @@ { "name": "@visactor/vrender-core", "entries": [ + { + "version": "0.21.3", + "tag": "@visactor/vrender-core_v0.21.3", + "date": "Mon, 23 Dec 2024 08:28:14 GMT", + "comments": { + "none": [ + { + "comment": "feat: support loadFont" + }, + { + "comment": "feat: support penetrateEventList" + }, + { + "comment": "fix: fix issue with image stroke and background" + }, + { + "comment": "fix: fix issue with html when include interactive layer" + }, + { + "comment": "fix: fix issue with richtext not support setShadowBlendStyle" + }, + { + "comment": "fix: optimize the performance of ticks in time-scale\n\n" + } + ] + } + }, + { + "version": "0.21.2", + "tag": "@visactor/vrender-core_v0.21.2", + "date": "Thu, 12 Dec 2024 10:23:51 GMT", + "comments": { + "none": [ + { + "comment": "fix: fix issue with shadow-root transform" + } + ] + } + }, { "version": "0.21.1", "tag": "@visactor/vrender-core_v0.21.1", diff --git a/packages/vrender-core/CHANGELOG.md b/packages/vrender-core/CHANGELOG.md index ed7f15751..9e4b243c8 100644 --- a/packages/vrender-core/CHANGELOG.md +++ b/packages/vrender-core/CHANGELOG.md @@ -1,6 +1,27 @@ # Change Log - @visactor/vrender-core -This log was last generated on Thu, 05 Dec 2024 07:50:47 GMT and should not be manually modified. +This log was last generated on Mon, 23 Dec 2024 08:28:14 GMT and should not be manually modified. + +## 0.21.3 +Mon, 23 Dec 2024 08:28:14 GMT + +### Updates + +- feat: support loadFont +- feat: support penetrateEventList +- fix: fix issue with image stroke and background +- fix: fix issue with html when include interactive layer +- fix: fix issue with richtext not support setShadowBlendStyle +- fix: optimize the performance of ticks in time-scale + + + +## 0.21.2 +Thu, 12 Dec 2024 10:23:51 GMT + +### Updates + +- fix: fix issue with shadow-root transform ## 0.21.1 Thu, 05 Dec 2024 07:50:47 GMT diff --git a/packages/vrender-core/package.json b/packages/vrender-core/package.json index fe476c736..098003215 100644 --- a/packages/vrender-core/package.json +++ b/packages/vrender-core/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/vrender-core", - "version": "0.21.1", + "version": "0.21.3", "description": "", "sideEffects": [ "./src/modules.ts", diff --git a/packages/vrender-core/src/core/contributions/env/base-contribution.ts b/packages/vrender-core/src/core/contributions/env/base-contribution.ts index fe34bd18f..0baed3f40 100644 --- a/packages/vrender-core/src/core/contributions/env/base-contribution.ts +++ b/packages/vrender-core/src/core/contributions/env/base-contribution.ts @@ -182,4 +182,12 @@ export abstract class BaseEnvContribution implements IEnvContribution { getElementTopLeft(dom: any, baseWindow?: boolean): { top: number; left: number } { return { top: 0, left: 0 }; } + + async loadFont( + font: string, + source: string | BinaryData, + descriptors?: FontFaceDescriptors + ): Promise<{ loadState: 'success' | 'fail' }> { + return { loadState: 'fail' }; + } } diff --git a/packages/vrender-core/src/core/global.ts b/packages/vrender-core/src/core/global.ts index 5f5090d07..4c1ec7f75 100644 --- a/packages/vrender-core/src/core/global.ts +++ b/packages/vrender-core/src/core/global.ts @@ -347,6 +347,13 @@ export class DefaultGlobal implements IGlobal { return this.envContribution.loadBlob(url); } + async loadFont(name: string, source: string | BinaryData, descriptors?: FontFaceDescriptors) { + if (!this._env) { + this.setEnv('browser'); + } + return this.envContribution.loadFont(name, source, descriptors); + } + isChrome(): boolean { if (this._isChrome != null) { return this._isChrome; diff --git a/packages/vrender-core/src/interface/global.ts b/packages/vrender-core/src/interface/global.ts index a70c9d464..efca682f0 100644 --- a/packages/vrender-core/src/interface/global.ts +++ b/packages/vrender-core/src/interface/global.ts @@ -119,6 +119,21 @@ export interface IEnvContribution loadState: 'success' | 'fail'; data: Blob | null; }>; + // @since 0.21.3 + /** + * 加载字体,参数对应Font类 + * @param font 字体名 + * @param source 数据源 + * @param descriptors 其他描述 + * @returns + */ + loadFont: ( + font: string, + source: string | BinaryData, + descriptors?: FontFaceDescriptors + ) => Promise<{ + loadState: 'success' | 'fail'; + }>; } export type IMiniAppEnvParams = { diff --git a/packages/vrender-core/src/interface/graphic.ts b/packages/vrender-core/src/interface/graphic.ts index b28d7d121..e5ddc38dd 100644 --- a/packages/vrender-core/src/interface/graphic.ts +++ b/packages/vrender-core/src/interface/graphic.ts @@ -203,6 +203,9 @@ export interface CommonDomOptions { container: string | HTMLElement | null; // id或者dom visible?: boolean; pointerEvents?: boolean | string; + // 可穿透的事件列表 + // @since 0.21.2 + penetrateEventList?: string[]; anchorType?: 'position' | 'boundsLeftTop' | BoundsAnchorType; } diff --git a/packages/vrender-core/src/interface/graphic/creator.ts b/packages/vrender-core/src/interface/graphic/creator.ts index 6719b2ff4..5467d3e12 100644 --- a/packages/vrender-core/src/interface/graphic/creator.ts +++ b/packages/vrender-core/src/interface/graphic/creator.ts @@ -8,7 +8,7 @@ import type { IImageAttribute, IImageGraphicAttribute } from './image'; import type { IIsogonAttribute } from './isogon'; import type { ILineAttribute, ILineGraphicAttribute } from './line'; import type { IPathAttribute, IPathGraphicAttribute } from './path'; -import type { IPolygonAttribute } from './polygon'; +import type { IPolygonAttribute, IPolygonGraphicAttribute } from './polygon'; import type { IRectAttribute, IRectGraphicAttribute } from './rect'; import type { IRichTextAttribute, IRichTextGraphicAttribute } from './richText'; import type { ISvgAttribute } from './svg'; @@ -68,6 +68,7 @@ export interface GraphicAttributeMap { readonly text: ITextGraphicAttribute; readonly richtext: IRichTextGraphicAttribute; readonly wrapText: IWrapTextGraphicAttribute; + readonly polygon: IPolygonGraphicAttribute; } // export declare function createArc(params: Partial): IArc; diff --git a/packages/vrender-core/src/plugins/builtin-plugin/html-attribute-plugin.ts b/packages/vrender-core/src/plugins/builtin-plugin/html-attribute-plugin.ts index 3e371baa4..2b531c604 100644 --- a/packages/vrender-core/src/plugins/builtin-plugin/html-attribute-plugin.ts +++ b/packages/vrender-core/src/plugins/builtin-plugin/html-attribute-plugin.ts @@ -9,7 +9,8 @@ import type { CreateDOMParamsType, CommonDomOptions, SimpleDomStyleOptions, - IText + IText, + ILayer } from '../../interface'; import { application } from '../../application'; import { getTheme } from '../../graphic/theme'; @@ -43,7 +44,8 @@ export class HtmlAttributePlugin implements IPlugin { return; } - this.drawHTML(context.stage.renderService); + // 全量查找,因为可能会有只渲染交互层的情况 + this.drawHTML([...(context.stage.getChildren() as any)]); }); } deactivate(context: IPluginService): void { @@ -116,6 +118,17 @@ export class HtmlAttributePlugin implements IPlugin { }; } + onWheel = (ev: Event) => { + try { + const newEvent = new (ev as any).constructor(ev.type, ev); + const canvas = this.pluginService.stage.window.getContext().getCanvas().nativeCanvas; + canvas.dispatchEvent(newEvent); + } catch (err) { + return; + // console.log(err); + } + }; + updateStyleOfWrapContainer( graphic: IGraphic, stage: IStage, @@ -123,12 +136,23 @@ export class HtmlAttributePlugin implements IPlugin { nativeContainer: HTMLElement, options: SimpleDomStyleOptions & CommonDomOptions ) { - const { pointerEvents } = options; + const { pointerEvents, penetrateEventList = [] } = options; let calculateStyle = this.parseDefaultStyleFromGraphic(graphic); calculateStyle.display = graphic.attribute.visible !== false ? 'block' : 'none'; // 事件穿透 calculateStyle.pointerEvents = pointerEvents === true ? 'all' : pointerEvents ? pointerEvents : 'none'; + if (calculateStyle.pointerEvents !== 'none') { + // 删除所有的事件 + this.removeWrapContainerEventListener(wrapContainer); + // 监听所有的事件 + penetrateEventList.forEach(event => { + if (event === 'wheel') { + wrapContainer.addEventListener('wheel', this.onWheel); + } + }); + } + // 定位wrapGroup if (!wrapContainer.style.position) { wrapContainer.style.position = 'absolute'; @@ -213,9 +237,9 @@ export class HtmlAttributePlugin implements IPlugin { this.renderId += 1; } - protected drawHTML(renderService: IRenderService) { + protected drawHTML(layers: ILayer[]) { if (application.global.env === 'browser') { - renderService.renderTreeRoots + layers .sort((a, b) => { return (a.attribute.zIndex ?? DefaultAttribute.zIndex) - (b.attribute.zIndex ?? DefaultAttribute.zIndex); }) @@ -244,12 +268,17 @@ export class HtmlAttributePlugin implements IPlugin { } const { wrapContainer } = this.htmlMap[id]; - - wrapContainer && application.global.removeDom(wrapContainer); + if (wrapContainer) { + application.global.removeDom(wrapContainer); + } this.htmlMap[id] = null; } + removeWrapContainerEventListener(wrapContainer: HTMLElement) { + wrapContainer.removeEventListener('wheel', this.onWheel); + } + renderGraphicHTML(graphic: IGraphic) { const { html } = graphic.attribute; if (!html) { 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..bb0e833de 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 @@ -40,7 +40,9 @@ export class DefaultImageBackgroundRenderContribution const { background, backgroundMode = graphicAttribute.backgroundMode, - backgroundFit = graphicAttribute.backgroundFit + backgroundFit = graphicAttribute.backgroundFit, + width, + height } = graphic.attribute; if (!background) { return; @@ -82,8 +84,9 @@ export class DefaultImageBackgroundRenderContribution } } else { context.beginPath(); - const b = graphic.AABBBounds; - context.rect(x, y, b.width(), b.height()); + // const b = graphic.AABBBounds; + // image的背景不包括Bounds了 + context.rect(x, y, width || 0, height || 0); context.fillStyle = background as string; context.globalAlpha = 1; context.fill(); diff --git a/packages/vrender-core/src/render/contributions/render/draw-interceptor.ts b/packages/vrender-core/src/render/contributions/render/draw-interceptor.ts index ed768d25b..71f34908d 100644 --- a/packages/vrender-core/src/render/contributions/render/draw-interceptor.ts +++ b/packages/vrender-core/src/render/contributions/render/draw-interceptor.ts @@ -94,9 +94,7 @@ export class ShadowRootDrawItemInterceptorContribution implements IDrawItemInter const { context } = drawContext; context.highPerformanceSave(); // 直接transform - const t1 = graphic.parent.globalTransMatrix; - const t2 = graphic.stage.window.getViewBoxTransform().clone().multiply(t1.a, t1.b, t1.c, t1.d, t1.e, t1.f); - graphic.parent && context.setTransformFromMatrix(t2, true); + context.transformFromMatrix(graphic.transMatrix, true); // 变换dirtyBounds if (drawContribution.dirtyBounds && drawContribution.backupDirtyBounds) { 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..540b09a07 100644 --- a/packages/vrender-core/src/render/contributions/render/image-render.ts +++ b/packages/vrender-core/src/render/contributions/render/image-render.ts @@ -81,7 +81,7 @@ export class DefaultCanvasImageRender extends BaseRender implements IGra const { fVisible, sVisible, doFill, doStroke } = data; // shadow - context.setShadowBlendStyle && context.setShadowBlendStyle(image, imageAttribute); + context.setShadowBlendStyle && context.setShadowBlendStyle(image, image.attribute, imageAttribute); this.beforeRenderStep(image, context, x, y, doFill, false, fVisible, false, imageAttribute, drawContext, fillCb); @@ -144,7 +144,7 @@ export class DefaultCanvasImageRender extends BaseRender implements IGra strokeCb(context, image.attribute, imageAttribute); } else if (sVisible) { context.setStrokeStyle(image, image.attribute, originX - x, originY - y, imageAttribute); - context.stroke(); + context.strokeRect(x, y, width, height); } } }; diff --git a/packages/vrender-core/src/render/contributions/render/richtext-render.ts b/packages/vrender-core/src/render/contributions/render/richtext-render.ts index 06a9e2298..dceec8d1e 100644 --- a/packages/vrender-core/src/render/contributions/render/richtext-render.ts +++ b/packages/vrender-core/src/render/contributions/render/richtext-render.ts @@ -44,6 +44,9 @@ export class DefaultCanvasRichTextRender extends BaseRender implement return; } + // shadow + context.setShadowBlendStyle && context.setShadowBlendStyle(richtext, richtext.attribute, richtextAttribute); + context.translate(x, y); this.beforeRenderStep( richtext, diff --git a/packages/vrender-kits/CHANGELOG.json b/packages/vrender-kits/CHANGELOG.json index 3b4cd3ee4..9f8a890a2 100644 --- a/packages/vrender-kits/CHANGELOG.json +++ b/packages/vrender-kits/CHANGELOG.json @@ -1,6 +1,24 @@ { "name": "@visactor/vrender-kits", "entries": [ + { + "version": "0.21.3", + "tag": "@visactor/vrender-kits_v0.21.3", + "date": "Mon, 23 Dec 2024 08:28:14 GMT", + "comments": { + "none": [ + { + "comment": "feat: support loadFont" + } + ] + } + }, + { + "version": "0.21.2", + "tag": "@visactor/vrender-kits_v0.21.2", + "date": "Thu, 12 Dec 2024 10:23:51 GMT", + "comments": {} + }, { "version": "0.21.1", "tag": "@visactor/vrender-kits_v0.21.1", diff --git a/packages/vrender-kits/CHANGELOG.md b/packages/vrender-kits/CHANGELOG.md index 73c95f45a..2e1918671 100644 --- a/packages/vrender-kits/CHANGELOG.md +++ b/packages/vrender-kits/CHANGELOG.md @@ -1,6 +1,18 @@ # Change Log - @visactor/vrender-kits -This log was last generated on Thu, 05 Dec 2024 07:50:47 GMT and should not be manually modified. +This log was last generated on Mon, 23 Dec 2024 08:28:14 GMT and should not be manually modified. + +## 0.21.3 +Mon, 23 Dec 2024 08:28:14 GMT + +### Updates + +- feat: support loadFont + +## 0.21.2 +Thu, 12 Dec 2024 10:23:51 GMT + +_Version update only_ ## 0.21.1 Thu, 05 Dec 2024 07:50:47 GMT diff --git a/packages/vrender-kits/package.json b/packages/vrender-kits/package.json index 8129f6551..27e6282b9 100644 --- a/packages/vrender-kits/package.json +++ b/packages/vrender-kits/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/vrender-kits", - "version": "0.21.1", + "version": "0.21.3", "description": "", "sideEffects": false, "main": "cjs/index.js", @@ -21,7 +21,7 @@ }, "dependencies": { "@visactor/vutils": "~0.19.2", - "@visactor/vrender-core": "workspace:0.21.1", + "@visactor/vrender-core": "workspace:0.21.3", "@resvg/resvg-js": "2.4.1", "roughjs": "4.5.2", "lottie-web": "^5.12.2" diff --git a/packages/vrender-kits/src/canvas/contributions/node-canvas.d.ts b/packages/vrender-kits/src/canvas/contributions/node-canvas.d.ts index 7e506970c..c491ccfaa 100644 --- a/packages/vrender-kits/src/canvas/contributions/node-canvas.d.ts +++ b/packages/vrender-kits/src/canvas/contributions/node-canvas.d.ts @@ -342,7 +342,7 @@ export function loadImage(src: string | Buffer, options?: any): Promise; * @param fontFace Description of the font face, corresponding to CSS properties * used in `@font-face` rules. */ -export function registerFont(path: string, fontFace: { family: string; weight?: string; style?: string }): void; +export function loadFont(path: string, fontFace: { family: string; weight?: string; style?: string }): void; /** This class must not be constructed directly; use `canvas.createPNGStream()`. */ export class PNGStream extends Readable {} diff --git a/packages/vrender-kits/src/env/contributions/browser-contribution.ts b/packages/vrender-kits/src/env/contributions/browser-contribution.ts index 7cc190170..82fd1f493 100644 --- a/packages/vrender-kits/src/env/contributions/browser-contribution.ts +++ b/packages/vrender-kits/src/env/contributions/browser-contribution.ts @@ -350,4 +350,26 @@ export class BrowserEnvContribution extends BaseEnvContribution implements IEnvC left: actualLeft }; } + + async loadFont( + font: string, + source: string | BinaryData, + descriptors?: FontFaceDescriptors + ): Promise<{ loadState: 'success' | 'fail' }> { + // 创建字体实例 + const myFont = new FontFace(font, isString(source) ? `url(${source})` : source, descriptors); + + // 加载字体 + return myFont + .load() + .then(function (loadedFont) { + // 将字体添加到文档中 + (document.fonts as any).add(loadedFont); + return { loadState: 'success' } as { loadState: 'success' | 'fail' }; + }) + .catch(function (error) { + console.error('Failed to load font:', error); + return { loadState: 'fail' } as { loadState: 'success' | 'fail' }; + }); + } } diff --git a/packages/vrender-kits/src/event/extension/gesture.ts b/packages/vrender-kits/src/event/extension/gesture.ts index d5319d136..24d7988c9 100644 --- a/packages/vrender-kits/src/event/extension/gesture.ts +++ b/packages/vrender-kits/src/event/extension/gesture.ts @@ -423,6 +423,9 @@ export class Gesture extends EventEmitter { } private emitEvent(type: string, e: GestureEvent) { + if (!this.element) { + return; + } const events = (this.element as unknown as any)._events; const listeners = events[WILDCARD]; if (listeners) { diff --git a/packages/vrender/CHANGELOG.json b/packages/vrender/CHANGELOG.json index eb005aec2..fed22b258 100644 --- a/packages/vrender/CHANGELOG.json +++ b/packages/vrender/CHANGELOG.json @@ -1,6 +1,18 @@ { "name": "@visactor/vrender", "entries": [ + { + "version": "0.21.3", + "tag": "@visactor/vrender_v0.21.3", + "date": "Mon, 23 Dec 2024 08:28:14 GMT", + "comments": {} + }, + { + "version": "0.21.2", + "tag": "@visactor/vrender_v0.21.2", + "date": "Thu, 12 Dec 2024 10:23:51 GMT", + "comments": {} + }, { "version": "0.21.1", "tag": "@visactor/vrender_v0.21.1", diff --git a/packages/vrender/CHANGELOG.md b/packages/vrender/CHANGELOG.md index d76fe89d3..c5fbdc02d 100644 --- a/packages/vrender/CHANGELOG.md +++ b/packages/vrender/CHANGELOG.md @@ -1,6 +1,16 @@ # Change Log - @visactor/vrender -This log was last generated on Thu, 05 Dec 2024 07:50:47 GMT and should not be manually modified. +This log was last generated on Mon, 23 Dec 2024 08:28:14 GMT and should not be manually modified. + +## 0.21.3 +Mon, 23 Dec 2024 08:28:14 GMT + +_Version update only_ + +## 0.21.2 +Thu, 12 Dec 2024 10:23:51 GMT + +_Version update only_ ## 0.21.1 Thu, 05 Dec 2024 07:50:47 GMT diff --git a/packages/vrender/package.json b/packages/vrender/package.json index a8c4167a1..9b8a391c3 100644 --- a/packages/vrender/package.json +++ b/packages/vrender/package.json @@ -1,6 +1,6 @@ { "name": "@visactor/vrender", - "version": "0.21.1", + "version": "0.21.3", "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.1", - "@visactor/vrender-kits": "workspace:0.21.1" + "@visactor/vrender-core": "workspace:0.21.3", + "@visactor/vrender-kits": "workspace:0.21.3" }, "devDependencies": { "@internal/bundler": "workspace:*", diff --git a/tools/bugserver-trigger/package.json b/tools/bugserver-trigger/package.json index 69ccb1f00..78f399fde 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.1", - "@visactor/vrender-core": "workspace:0.21.1", - "@visactor/vrender-kits": "workspace:0.21.1", - "@visactor/vrender-components": "workspace:0.21.1" + "@visactor/vrender": "workspace:0.21.3", + "@visactor/vrender-core": "workspace:0.21.3", + "@visactor/vrender-kits": "workspace:0.21.3", + "@visactor/vrender-components": "workspace:0.21.3" }, "devDependencies": { "@rushstack/eslint-patch": "~1.1.4",