diff --git a/packages/vrender-components/src/label/base.ts b/packages/vrender-components/src/label/base.ts index 08ed969f4..a98b0d50a 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, @@ -655,30 +689,8 @@ 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) { - if (canPlace(bmpTool, bitmap, text.AABBBounds)) { - // xy方向偏移都为0,意味着不考虑 overlapPadding 时,实际上可以放得下 - bitmap.setRange(boundToRange(bmpTool, text.AABBBounds, true)); - 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)); + const placedAfterClampForce = this._processClampForce(text as IText, bmpTool, bitmap); + if (placedAfterClampForce) { 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))) {