fix: drag block issue (#9902)

### Changed
- Added support for changing the preview offset during dragging.
- Fixed the preview rendering for embed block and surface-ref block
- Resolved an issue where the host element might be reused in certain cases, which could cause unexpected behavior
- Moved viewport-related constants and methods to a more appropriate location
This commit is contained in:
doouding
2025-02-05 07:25:53 +00:00
parent abeff8bb1a
commit 02122098c7
22 changed files with 177 additions and 138 deletions

View File

@@ -2,6 +2,7 @@ import {
assertType,
Bound,
DisposableGroup,
getCommonBound,
getCommonBoundWithRotation,
type IBound,
last,
@@ -30,7 +31,7 @@ import {
GfxPrimitiveElementModel,
} from './model/surface/element-model.js';
import type { SurfaceBlockModel } from './model/surface/surface-model.js';
import { Viewport } from './viewport.js';
import { FIT_TO_SCREEN_PADDING, Viewport, ZOOM_INITIAL } from './viewport.js';
export class GfxController extends LifeCycleWatcher {
static override key = gfxControllerKey;
@@ -300,4 +301,28 @@ export class GfxController extends LifeCycleWatcher {
block && this.doc.updateBlock(block.model, props);
}
}
fitToScreen(
options: {
bounds?: Bound[];
smooth?: boolean;
padding?: [number, number, number, number];
} = {
smooth: false,
padding: [0, 0, 0, 0],
}
) {
const elemBounds =
options.bounds ??
this.gfxElements.map(element => Bound.deserialize(element.xywh));
const commonBound = getCommonBound(elemBounds);
const { zoom, centerX, centerY } = this.viewport.getFitToScreenData(
commonBound,
options.padding,
ZOOM_INITIAL,
FIT_TO_SCREEN_PADDING
);
this.viewport.setViewport(zoom, [centerX, centerY], options.smooth);
}
}

View File

@@ -60,9 +60,12 @@ export class ViewManager extends GfxExtension {
this._disposable.add(
surface.elementAdded.on(payload => {
const model = surface.getElementById(payload.id)!;
const View = this._viewCtorMap.get(model.type) ?? GfxElementModelView;
const ViewCtor =
this._viewCtorMap.get(model.type) ?? GfxElementModelView;
const view = new ViewCtor(model, this.gfx);
this._viewMap.set(model.id, new View(model, this.gfx));
this._viewMap.set(model.id, view);
view.onCreated();
})
);

View File

@@ -72,7 +72,6 @@ export class GfxElementModelView<
readonly gfx: GfxController
) {
this.model = model;
this.onCreated();
}
static setup(di: Container): void {

View File

@@ -15,6 +15,10 @@ function cutoff(value: number, ref: number, sign: number) {
export const ZOOM_MAX = 6.0;
export const ZOOM_MIN = 0.1;
export const ZOOM_STEP = 0.25;
export const ZOOM_INITIAL = 1.0;
export const FIT_TO_SCREEN_PADDING = 100;
export class Viewport {
private _cachedBoundingClientRect: DOMRect | null = null;