From 2bff9cad7cac9508aa5194b2e353ebdf5e3b216d Mon Sep 17 00:00:00 2001 From: xiaoluoHe Date: Thu, 5 Dec 2024 14:36:46 +0800 Subject: [PATCH 1/2] feat: optimize shiftY --- packages/vrender-components/src/label/base.ts | 58 ++++++++++++------- .../src/label/overlap/shiftY.ts | 12 ++-- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/packages/vrender-components/src/label/base.ts b/packages/vrender-components/src/label/base.ts index 08ed969f4..ec4d916cc 100644 --- a/packages/vrender-components/src/label/base.ts +++ b/packages/vrender-components/src/label/base.ts @@ -550,9 +550,15 @@ export class LabelBase extends AbstractComponent { const text = result[i]; const bounds = text.AABBBounds; const range = boundToRange(bmpTool, bounds, true); - if (canPlace(bmpTool, bitmap, bounds, clampForce, text._isClamped ? 0 : overlapPadding)) { + if (canPlace(bmpTool, bitmap, bounds, clampForce, overlapPadding)) { bitmap.setRange(range); } else { + if (clampForce) { + const placedAfterClampForce = this._processClampForce(text as IText, bmpTool, bitmap); + if (placedAfterClampForce) { + continue; + } + } if (hideOnHit) { text.setAttributes({ visible: false }); } else { @@ -563,6 +569,34 @@ export class LabelBase extends AbstractComponent { return result; } + protected _processClampForce(text: IText, bmpTool: BitmapTool, bitmap: Bitmap) { + 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 时,实际上可以放得下 + bitmap.setRange(boundToRange(bmpTool, text.AABBBounds, true)); + return true; + } + } else if ( + canPlace( + bmpTool, + bitmap, + { + x1: text.AABBBounds.x1 + dx, + x2: text.AABBBounds.x2 + dx, + y1: text.AABBBounds.y1 + dy, + y2: text.AABBBounds.y2 + dy + } + // 向内 clamp 只处理超出的位移量,不叠加 overlapPadding + ) + ) { + text.setAttributes({ x: text.attribute.x + dx, y: text.attribute.y + dy }); + bitmap.setRange(boundToRange(bmpTool, text.AABBBounds, true)); + return true; + } + return false; + } + protected _overlapByStrategy( labels: (IText | IRichText)[], option: OverlapAttrs, @@ -658,29 +692,11 @@ export class LabelBase extends AbstractComponent { // 向内挤压不考虑 overlapPadding const { dx = 0, dy = 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 时,实际上可以放得下 - bitmap.setRange(boundToRange(bmpTool, text.AABBBounds, true)); + const placedAfterClampForce = this._processClampForce(text as IText, bmpTool, bitmap); + if (placedAfterClampForce) { result.push(text); continue; } - } else if ( - canPlace( - bmpTool, - bitmap, - { - x1: text.AABBBounds.x1 + dx, - x2: text.AABBBounds.x2 + dx, - y1: text.AABBBounds.y1 + dy, - y2: text.AABBBounds.y2 + dy - } - // 向内 clamp 只处理超出的位移量,不叠加 overlapPadding - ) - ) { - text.setAttributes({ x: text.attribute.x + dx, y: text.attribute.y + dy }); - bitmap.setRange(boundToRange(bmpTool, text.AABBBounds, true)); - result.push(text); - continue; } } diff --git a/packages/vrender-components/src/label/overlap/shiftY.ts b/packages/vrender-components/src/label/overlap/shiftY.ts index 5559daf0c..b4cbfb9b7 100644 --- a/packages/vrender-components/src/label/overlap/shiftY.ts +++ b/packages/vrender-components/src/label/overlap/shiftY.ts @@ -103,17 +103,17 @@ export function shiftY(texts: IText[], option: IShiftYOption) { }; function adjustPositionInOneGroup(texts: IText[]) { - if (texts.length === 1) { - return; - } // 从最后一个 text 向前遍历,如果与前一个 text 相交,则尝试放到下方(需要判断和前一个 text 是否相交,若相交则不能放到下方) - for (let i = texts.length - 1; i > 0; i--) { + for (let i = texts.length - 1; i >= 0; i--) { const curText = texts[i]; const upperText = texts[i - 1]; const lowerText = texts[i + 1]; - // 当前 text 和上面一个 text 相交 - if (isIntersect(getY1(upperText) + getHeight(upperText), getY1(curText))) { + if ( + (upperText && isIntersect(getY1(upperText) + getHeight(upperText), getY1(curText))) || + // 如果是最顶上被 clamp 进来的 text,也尝试向下摆放 + (getY1(curText) === 0 && curText._isClamped) + ) { const { y } = labelling(curText); // 挪动当前 text 后, 和下面一个 text 不相交 if (!lowerText || !isIntersect(y + getHeight(curText) / 2, getY1(lowerText))) { From 82b42a5b60ef0abbd7df990b11cd2fb4746a235a Mon Sep 17 00:00:00 2001 From: xiaoluoHe Date: Thu, 5 Dec 2024 15:36:37 +0800 Subject: [PATCH 2/2] fix: clampForce refactor --- packages/vrender-components/src/label/base.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/vrender-components/src/label/base.ts b/packages/vrender-components/src/label/base.ts index ec4d916cc..a98b0d50a 100644 --- a/packages/vrender-components/src/label/base.ts +++ b/packages/vrender-components/src/label/base.ts @@ -689,14 +689,10 @@ export class LabelBase extends AbstractComponent { // 尝试向内挤压 if (!hasPlace && clampForce) { - // 向内挤压不考虑 overlapPadding - const { dx = 0, dy = 0 } = clampText(text as IText, bmpTool.width, bmpTool.height, bmpTool.padding); - if (dx === 0 && dy === 0) { - const placedAfterClampForce = this._processClampForce(text as IText, bmpTool, bitmap); - if (placedAfterClampForce) { - result.push(text); - continue; - } + const placedAfterClampForce = this._processClampForce(text as IText, bmpTool, bitmap); + if (placedAfterClampForce) { + result.push(text); + continue; } }