From 7eb2d222093c518c8119bb927f5b8fe0a669c091 Mon Sep 17 00:00:00 2001 From: zhouxinyu Date: Mon, 24 Feb 2025 17:19:44 +0800 Subject: [PATCH] fix: fix issue with text edit include textAlign and bounds --- .../fix-text-edit_2025-02-24-09-19.json | 10 + .../src/plugins/builtin-plugin/edit-module.ts | 19 +- .../builtin-plugin/richtext-edit-plugin.ts | 5 +- .../browser/src/pages/richtext-editor.ts | 332 ++---------------- 4 files changed, 67 insertions(+), 299 deletions(-) create mode 100644 common/changes/@visactor/vrender-core/fix-text-edit_2025-02-24-09-19.json diff --git a/common/changes/@visactor/vrender-core/fix-text-edit_2025-02-24-09-19.json b/common/changes/@visactor/vrender-core/fix-text-edit_2025-02-24-09-19.json new file mode 100644 index 000000000..c1ba9dc8c --- /dev/null +++ b/common/changes/@visactor/vrender-core/fix-text-edit_2025-02-24-09-19.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vrender-core", + "comment": "fix: fix issue with text edit include textAlign and bounds", + "type": "none" + } + ], + "packageName": "@visactor/vrender-core" +} \ No newline at end of file diff --git a/packages/vrender-core/src/plugins/builtin-plugin/edit-module.ts b/packages/vrender-core/src/plugins/builtin-plugin/edit-module.ts index 58ebd735a..6f494a008 100644 --- a/packages/vrender-core/src/plugins/builtin-plugin/edit-module.ts +++ b/packages/vrender-core/src/plugins/builtin-plugin/edit-module.ts @@ -18,7 +18,14 @@ import type { // } export function getDefaultCharacterConfig(attribute: IRichTextGraphicAttribute) { - const { fill = 'black', stroke = false, fontWeight = 'normal', lineHeight, fontFamily = 'Arial' } = attribute; + const { + fill = 'black', + stroke = false, + fontWeight = 'normal', + lineHeight, + fontFamily = 'Arial', + textAlign + } = attribute; let { fontSize = 12 } = attribute; if (!isFinite(fontSize)) { fontSize = 12; @@ -29,7 +36,8 @@ export function getDefaultCharacterConfig(attribute: IRichTextGraphicAttribute) fontSize, fontWeight, fontFamily, - lineHeight + lineHeight, + textAlign } as any; } @@ -219,7 +227,12 @@ export class EditModule { } else { const configIdx = this.composingConfigIdx; const lastConfig = textConfig[configIdx] || textConfig[configIdx - 1]; - textConfig.splice(configIdx, 0, { fill: 'black', ...lastConfig, text: '' }); + textConfig.splice(configIdx, 0, { + fill: 'black', + ...getDefaultCharacterConfig(this.currRt.attribute), + ...lastConfig, + text: '' + }); } }; handleCompositionEnd = () => { diff --git a/packages/vrender-core/src/plugins/builtin-plugin/richtext-edit-plugin.ts b/packages/vrender-core/src/plugins/builtin-plugin/richtext-edit-plugin.ts index d32c40436..a60df0018 100644 --- a/packages/vrender-core/src/plugins/builtin-plugin/richtext-edit-plugin.ts +++ b/packages/vrender-core/src/plugins/builtin-plugin/richtext-edit-plugin.ts @@ -617,6 +617,8 @@ export class RichTextEditPlugin implements IPlugin { if (!editOptions || !boundsStrokeWhenInput) { return; } + // 得先偏移,不然上一次的Bounds会影响后续的计算 + this.offsetShadowRoot(); // const { attribute } = this.currRt; const b = this.getRichTextAABBBounds(this.currRt); const height = b.height(); @@ -641,7 +643,6 @@ export class RichTextEditPlugin implements IPlugin { // shadow.add(this.shadowBounds); this.offsetLineBgAndShadowBounds(); - this.offsetShadowRoot(); } trySyncPlaceholderToTextConfig() { @@ -1089,7 +1090,7 @@ export class RichTextEditPlugin implements IPlugin { protected getShadow(rt: IRichText) { const sr = rt.shadowRoot || rt.attachShadow(); // TODO 这里比较hack,因为emptyBoundsContainer是empty,导致shadowRoot的Bounds为空,所以这里给一个1*1的rect,让其能绘制 - sr.setAttributes({ width: 1, height: 1 }); + sr.setAttributes({ width: 0, height: 0 }); return sr; } diff --git a/packages/vrender/__tests__/browser/src/pages/richtext-editor.ts b/packages/vrender/__tests__/browser/src/pages/richtext-editor.ts index 523589d9c..4eb8a2960 100644 --- a/packages/vrender/__tests__/browser/src/pages/richtext-editor.ts +++ b/packages/vrender/__tests__/browser/src/pages/richtext-editor.ts @@ -28,308 +28,52 @@ export const page = () => { shapes.push( createRichText({ visible: true, + x: 162.07207758976318, + y: 216.49803822714284, + textAlign: 'center', + text: null, fontSize: 16, - _debug_bounds: true, - width: 0, + whiteSpace: 'normal', + graphicAlign: 'center', + graphicBaseline: 'middle', + fill: '#1F2329', + ignoreBuf: true, + anchor: [-162.07207758976318, 216.49803822714284], + angle: 0, + editOptions: { + placeholder: '请输入文本', + placeholderColor: '#B3B8C3', + keepHeightWhileEmpty: true, + boundsStrokeWhenInput: '#3073F2', + syncPlaceholderToTextConfig: false, + stopPropagation: true + }, + editable: true, + fontFamily: 'D-Din', height: 0, - x: 100, - y: 100, + heightLimit: 999999, lineHeight: '150%', - editable: true, - upgradeAttrs: { - multiBreakLine: true - }, - // background: 'green', - // "textAlign": "center", + maxWidth: 120, + strokeBoundsBuffer: -1, + textBaseline: 'top', textConfig: [ { - text: '我', - fontSize: 16, - - textAlign: 'center', - background: 'rgba(255, 0, 0, 0.3)', - fill: '#0f51b5' - }, - { - text: '们', - fontSize: 16, - - textAlign: 'center', - background: 'rgba(255, 0, 0, 0.3)', - fill: '#0f51b5' - }, - { - text: '是', - fontSize: 16, - - textAlign: 'center', - background: 'rgba(255, 0, 0, 0.3)', - fill: '#0f51b5' - }, - { - text: '\n', - fontSize: 16, - - textAlign: 'center', - background: 'rgba(255, 0, 0, 0.3)', - fill: '#0f51b5' - }, - { - text: '\n', - fontSize: 16, - - textAlign: 'center', - background: 'rgba(255, 0, 0, 0.3)', - fill: '#0f51b5' - }, - { - text: '\n', - fontSize: 16, - - textAlign: 'center', - background: 'rgba(255, 0, 0, 0.3)', - fill: '#0f51b5' - }, - { - text: '无', + fill: '#1F2329', + stroke: false, fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '缘', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { + fontWeight: 'normal', + fontFamily: 'D-Din', + lineHeight: '150%', text: 'a', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '无', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '故', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '的', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '尘😁', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '埃\n', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '无', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '缘', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '无', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '故', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '的', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '游', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '走\n', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '黑', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '暗', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '只', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '需', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '要', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '张', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '开', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '一', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '张', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '缝', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '隙\n', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '就', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '能', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '挂', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '起', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '飓', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '[4]', - script: 'super', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: '风\n', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' - }, - { - text: 'and this is our world, \nthat we call life', - fontSize: 16, - - textAlign: 'center', - fill: '#0f51b5' + isComposing: false } - ] + ], + upgradeAttrs: { + lineHeight: true, + multiBreakLine: true + }, + verticalDirection: 'middle', + width: 0 }) );