diff --git a/blocksuite/affine/gfx/shape/src/text/edgeless-shape-text-editor.ts b/blocksuite/affine/gfx/shape/src/text/edgeless-shape-text-editor.ts index 786b082d4..a7e9109d6 100644 --- a/blocksuite/affine/gfx/shape/src/text/edgeless-shape-text-editor.ts +++ b/blocksuite/affine/gfx/shape/src/text/edgeless-shape-text-editor.ts @@ -434,6 +434,8 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) { const textResizing = this.element.textResizing; const viewport = this.gfx.viewport; const zoom = viewport.zoom; + // Compensate for outer CSS scale, matching GfxBlockComponent.getCSSTransform. + const { viewportX, viewportY, viewScale } = viewport; const rect = getSelectedRect([this.element]); const rotate = this.element.rotate; const [leftTopX, leftTopY] = Vec.rotWith( @@ -441,7 +443,8 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) { [rect.left + rect.width / 2, rect.top + rect.height / 2], toRadian(rotate) ); - const [x, y] = this.gfx.viewport.toViewCoord(leftTopX, leftTopY); + const x = ((leftTopX - viewportX) * zoom) / viewScale; + const y = ((leftTopY - viewportY) * zoom) / viewScale; const autoWidth = textResizing === TextResizing.AUTO_WIDTH_AND_HEIGHT; const constrainedAutoWidth = autoWidth && !!this.element.maxWidth; const editorWidth = constrainedAutoWidth @@ -476,7 +479,7 @@ export class EdgelessShapeTextEditor extends WithDisposable(ShadowlessElement) { fontWeight: this.element.fontWeight, lineHeight: 'normal', outline: 'none', - transform: `scale(${zoom}, ${zoom}) rotate(${rotate}deg)`, + transform: `scale(${zoom / viewScale}, ${zoom / viewScale}) rotate(${rotate}deg)`, transformOrigin: 'top left', color, padding: `${verticalPadding}px ${horiPadding}px`, diff --git a/blocksuite/affine/gfx/text/src/edgeless-text-editor.ts b/blocksuite/affine/gfx/text/src/edgeless-text-editor.ts index 620076bc4..64c3cf3b1 100644 --- a/blocksuite/affine/gfx/text/src/edgeless-text-editor.ts +++ b/blocksuite/affine/gfx/text/src/edgeless-text-editor.ts @@ -418,13 +418,14 @@ export class EdgelessTextEditor extends WithDisposable(ShadowlessElement) { const lineHeight = getLineHeight(fontFamily, fontSize, fontWeight); const rect = getSelectedRect([this.element]); - const { translateX, translateY, zoom } = this.gfx.viewport; + const { translateX, translateY, zoom, viewScale } = this.gfx.viewport; const [visualX, visualY] = this.getVisualPosition(this.element); const containerOffset = this.getContainerOffset(); + // Compensate for outer CSS scale, matching GfxBlockComponent.getCSSTransform. const transformOperation = [ - `translate(${translateX}px, ${translateY}px)`, - `translate(${visualX * zoom}px, ${visualY * zoom}px)`, - `scale(${zoom})`, + `translate(${translateX / viewScale}px, ${translateY / viewScale}px)`, + `translate(${(visualX * zoom) / viewScale}px, ${(visualY * zoom) / viewScale}px)`, + `scale(${zoom / viewScale})`, `rotate(${rotate}deg)`, `translate(${containerOffset})`, ]; diff --git a/blocksuite/affine/widgets/drag-handle/src/watchers/edgeless-watcher.ts b/blocksuite/affine/widgets/drag-handle/src/watchers/edgeless-watcher.ts index 52cff1f58..4b31e8fa2 100644 --- a/blocksuite/affine/widgets/drag-handle/src/watchers/edgeless-watcher.ts +++ b/blocksuite/affine/widgets/drag-handle/src/watchers/edgeless-watcher.ts @@ -264,17 +264,21 @@ export class EdgelessWatcher { const { viewport } = this.gfx; const rect = getSelectedRect([edgelessElement]); - let [left, top] = viewport.toViewCoord(rect.left, rect.top); + // Compensate for outer CSS scale, matching GfxBlockComponent.getCSSTransform. + const { viewportX, viewportY, viewScale } = viewport; const scale = this.widget.scale.peek(); - const width = rect.width * scale; - const height = rect.height * scale; + let left = ((rect.left - viewportX) * scale) / viewScale; + const top = ((rect.top - viewportY) * scale) / viewScale; + const width = (rect.width * scale) / viewScale; + const height = (rect.height * scale) / viewScale; let [right, bottom] = [left + width, top + height]; - const padding = HOVER_AREA_RECT_PADDING_TOP_LEVEL * scale; + const padding = (HOVER_AREA_RECT_PADDING_TOP_LEVEL * scale) / viewScale; - const containerWidth = DRAG_HANDLE_CONTAINER_WIDTH_TOP_LEVEL * scale; - const offsetLeft = DRAG_HANDLE_CONTAINER_OFFSET_LEFT_TOP_LEVEL; + const containerWidth = + (DRAG_HANDLE_CONTAINER_WIDTH_TOP_LEVEL * scale) / viewScale; + const offsetLeft = DRAG_HANDLE_CONTAINER_OFFSET_LEFT_TOP_LEVEL / viewScale; left -= containerWidth + offsetLeft; right += padding; diff --git a/blocksuite/affine/widgets/edgeless-selected-rect/src/edgeless-selected-rect.ts b/blocksuite/affine/widgets/edgeless-selected-rect/src/edgeless-selected-rect.ts index be6eae2e5..0c8efd3bf 100644 --- a/blocksuite/affine/widgets/edgeless-selected-rect/src/edgeless-selected-rect.ts +++ b/blocksuite/affine/widgets/edgeless-selected-rect/src/edgeless-selected-rect.ts @@ -473,12 +473,15 @@ export class EdgelessSelectedRectWidget extends WidgetComponent const { zoom, selection, gfx } = this; const elements = selection.selectedElements; - // in surface const rect = getSelectedRect(elements); - // in viewport - const [left, top] = gfx.viewport.toViewCoord(rect.left, rect.top); - const [width, height] = [rect.width * zoom, rect.height * zoom]; + // Compensate for outer CSS scale (e.g. embed-edgeless-synced-doc), + // matching GfxBlockComponent.getCSSTransform. + const { viewportX, viewportY, viewScale } = gfx.viewport; + const left = ((rect.left - viewportX) * zoom) / viewScale; + const top = ((rect.top - viewportY) * zoom) / viewScale; + const width = (rect.width * zoom) / viewScale; + const height = (rect.height * zoom) / viewScale; let rotate = 0; if (elements.length === 1 && elements[0].rotate) { @@ -714,15 +717,17 @@ export class EdgelessSelectedRectWidget extends WidgetComponent element => element.id, element => { const [modelX, modelY, w, h] = deserializeXYWH(element.xywh); - const [x, y] = gfx.viewport.toViewCoord(modelX, modelY); + const { viewportX, viewportY, zoom, viewScale } = gfx.viewport; + const x = ((modelX - viewportX) * zoom) / viewScale; + const y = ((modelY - viewportY) * zoom) / viewScale; const { left, top, borderWidth } = this._selectedRect; const style = { position: 'absolute', boxSizing: 'border-box', left: `${x - left - borderWidth}px`, top: `${y - top - borderWidth}px`, - width: `${w * this.zoom}px`, - height: `${h * this.zoom}px`, + width: `${(w * zoom) / viewScale}px`, + height: `${(h * zoom) / viewScale}px`, transform: `rotate(${element.rotate}deg)`, border: `1px solid var(--affine-primary-color)`, }; diff --git a/blocksuite/affine/widgets/remote-selection/src/edgeless/index.ts b/blocksuite/affine/widgets/remote-selection/src/edgeless/index.ts index 00de7e110..ae689bec9 100644 --- a/blocksuite/affine/widgets/remote-selection/src/edgeless/index.ts +++ b/blocksuite/affine/widgets/remote-selection/src/edgeless/index.ts @@ -148,13 +148,14 @@ export class EdgelessRemoteSelectionWidget extends WidgetComponent { - const { translateX, translateY, zoom } = this.gfx.viewport; + const { translateX, translateY, zoom, viewScale } = this.gfx.viewport; - this.style.setProperty('--v-zoom', `${zoom}`); + // Compensate for outer CSS scale, matching GfxBlockComponent.getCSSTransform. + this.style.setProperty('--v-zoom', `${zoom / viewScale}`); this.style.setProperty( 'transform', - `translate(${translateX}px, ${translateY}px) scale(var(--v-zoom))` + `translate(${translateX / viewScale}px, ${translateY / viewScale}px) scale(var(--v-zoom))` ); }, this);