fix(editor): note-edgeless-block dimensions mismatch content at non-100% scale (#14577)

### Problem
●In edgeless mode, when the `note-edgeless-block` is scaled below 100%,
its outer dimension becomes larger than its content region. This extra
invisible region will block some user interactions such as clicks and
hovers on editing elements underneath.

<img width="1060" height="541" alt="note-elem-block-click"
src="https://github.com/user-attachments/assets/860d7a4f-d159-437b-bbe8-4560e2463e3d"
/>

●The following video demonstrates this issue:


https://github.com/user-attachments/assets/3b719b25-0d7e-496b-9507-6aa65ed0a797


### Solution
●The root cause is that `transform: scale(...)` CSS property (which
implements the scale) is currently applyed to its **inner root element**
instead of itself, and the solution is to move this CSS property to the
proper place.

### After
●The video below shows the behavior after this fix.



https://github.com/user-attachments/assets/e2dbd75d-c2ea-460d-90a1-5cc13e12d5b8



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Centralized CSS scaling for graphics and edgeless note blocks into
dedicated public methods; rendering now uses these methods instead of
inline transform calculations.
* **Tests**
* Updated end-to-end checks to read scale directly from the edgeless
note element and use a more flexible transform-matching pattern.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
congzhou09
2026-03-06 19:03:36 +08:00
committed by GitHub
parent 7f5f7e79df
commit c249011238
3 changed files with 19 additions and 5 deletions

View File

@@ -221,6 +221,12 @@ export class EdgelessNoteBlockComponent extends toGfxBlockComponent(
}
}
override getCSSScaleVal(): number {
const baseScale = super.getCSSScaleVal();
const extraScale = this.model.props.edgeless?.scale ?? 1;
return baseScale * extraScale;
}
override getRenderingRect() {
const { xywh, edgeless } = this.model.props;
const { collapse, scale = 1 } = edgeless;
@@ -255,7 +261,6 @@ export class EdgelessNoteBlockComponent extends toGfxBlockComponent(
const style = {
borderRadius: borderRadius + 'px',
transform: `scale(${scale})`,
};
const extra = this._editing ? ACTIVE_NOTE_EXTRA_PADDING : 0;

View File

@@ -105,6 +105,12 @@ export abstract class GfxBlockComponent<
onBoxSelected(_: BoxSelectionContext) {}
getCSSScaleVal(): number {
const viewport = this.gfx.viewport;
const { zoom, viewScale } = viewport;
return zoom / viewScale;
}
getCSSTransform() {
const viewport = this.gfx.viewport;
const { translateX, translateY, zoom, viewScale } = viewport;
@@ -115,7 +121,7 @@ export abstract class GfxBlockComponent<
const deltaX = scaledX - bound.x;
const deltaY = scaledY - bound.y;
return `translate(${translateX / viewScale + deltaX}px, ${translateY / viewScale + deltaY}px) scale(${zoom / viewScale})`;
return `translate(${translateX / viewScale + deltaX}px, ${translateY / viewScale + deltaY}px) scale(${this.getCSSScaleVal()})`;
}
getRenderingRect() {
@@ -219,6 +225,10 @@ export function toGfxBlockComponent<
handleGfxConnection(this);
}
getCSSScaleVal(): number {
return GfxBlockComponent.prototype.getCSSScaleVal.call(this);
}
getCSSTransform() {
return GfxBlockComponent.prototype.getCSSTransform.call(this);
}

View File

@@ -49,14 +49,13 @@ async function checkNoteScale(
const edgelessNote = page.locator(
`affine-edgeless-note[data-block-id="${noteId}"]`
);
const noteContainer = edgelessNote.getByTestId('edgeless-note-container');
const style = await noteContainer.getAttribute('style');
const style = await edgelessNote.getAttribute('style');
if (!style) {
throw new Error('Style attribute not found');
}
const scaleMatch = style.match(/transform:\s*scale\(([\d.]+)\)/);
const scaleMatch = style.match(/transform:[^;]*scale\(([\d.]+)\)/);
if (!scaleMatch) {
throw new Error('Scale transform not found in style');
}