mirror of
https://github.com/dream-num/univer.git
synced 2026-09-24 15:32:18 +08:00
feat(docs-drawing-ui): optimize float-dom on doc canvas (#4824)
This commit is contained in:
@@ -115,6 +115,7 @@ export interface IDrawingParam extends IDrawingSearch {
|
||||
// The default value is BooleanNumber.FALSE. if it's true, Please use transforms.
|
||||
isMultiTransform?: BooleanNumber;
|
||||
groupId?: string;
|
||||
allowTransform?: boolean;
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
+8
-2
@@ -130,7 +130,10 @@ export class DocDrawingTransformerController extends Disposable {
|
||||
const drawingData = documentDataModel?.getSnapshot().drawings?.[drawing.drawingId];
|
||||
|
||||
if (drawingData?.layoutType === PositionedObjectLayoutType.INLINE) {
|
||||
(object as Image).setOpacity(0.2);
|
||||
try {
|
||||
(object as Image).setOpacity(0.2);
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
if (drawingData != null) {
|
||||
@@ -202,7 +205,10 @@ export class DocDrawingTransformerController extends Disposable {
|
||||
const drawingCache = this._transformerCache.get(drawing?.drawingId);
|
||||
|
||||
if (drawingCache?.drawing.layoutType === PositionedObjectLayoutType.INLINE) {
|
||||
(object as Image).setOpacity(1);
|
||||
try {
|
||||
(object as Image).setOpacity(1);
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,13 +18,13 @@ import type { DocumentDataModel, IDisposable, IDrawingSearch, Nullable } from '@
|
||||
import type { IDocFloatDom } from '@univerjs/docs-drawing';
|
||||
import type { ISetDocZoomRatioOperationParams } from '@univerjs/docs-ui';
|
||||
import type { IDocFloatDomDataBase } from '@univerjs/drawing';
|
||||
import type { BaseObject, IRender, Rect } from '@univerjs/engine-render';
|
||||
import type { IRender, Rect } from '@univerjs/engine-render';
|
||||
import type { IFloatDomLayout } from '@univerjs/ui';
|
||||
import type { IInsertDrawingCommandParams } from '../commands/commands/interfaces';
|
||||
import { Disposable, DisposableCollection, DrawingTypeEnum, fromEventSubject, generateRandomId, ICommandService, Inject, IUniverInstanceService, ObjectRelativeFromH, ObjectRelativeFromV, PositionedObjectLayoutType, toDisposable, UniverInstanceType } from '@univerjs/core';
|
||||
import { DocSkeletonManagerService } from '@univerjs/docs';
|
||||
import { docDrawingPositionToTransform, SetDocZoomRatioOperation, VIEWPORT_KEY } from '@univerjs/docs-ui';
|
||||
import { getDrawingShapeKeyByDrawingSearch, IDrawingManagerService } from '@univerjs/drawing';
|
||||
import { IDrawingManagerService } from '@univerjs/drawing';
|
||||
import { DrawingRenderService } from '@univerjs/drawing-ui';
|
||||
import { CURSOR_TYPE, IRenderManagerService } from '@univerjs/engine-render';
|
||||
import { CanvasFloatDomService } from '@univerjs/ui';
|
||||
@@ -32,10 +32,10 @@ import { BehaviorSubject, map, of, switchMap } from 'rxjs';
|
||||
import { InsertDocDrawingCommand } from '../commands/commands/insert-doc-drawing.command';
|
||||
|
||||
function calcDocFloatDomPosition(
|
||||
object: BaseObject,
|
||||
object: Rect,
|
||||
renderUnit: IRender
|
||||
): IFloatDomLayout {
|
||||
const { top, left, width, height, angle } = object;
|
||||
const { top, left, width, height, angle, opacity } = object;
|
||||
// const
|
||||
const scene = renderUnit.scene;
|
||||
const viewMain = scene.getViewport(VIEWPORT_KEY.VIEW_MAIN)!;
|
||||
@@ -49,11 +49,12 @@ function calcDocFloatDomPosition(
|
||||
endY: (top + height - viewportScrollY) * scaleY,
|
||||
width,
|
||||
height,
|
||||
rotate: 0,
|
||||
rotate: angle,
|
||||
absolute: {
|
||||
left: false,
|
||||
top: false,
|
||||
},
|
||||
opacity: opacity ?? 1,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -64,6 +65,9 @@ interface ICanvasFloatDomInfo {
|
||||
unitId: string;
|
||||
}
|
||||
|
||||
interface IDocFloatDomParams extends IDocFloatDomDataBase {
|
||||
}
|
||||
|
||||
export class DocFloatDomController extends Disposable {
|
||||
private _domLayerInfoMap = new Map<string, ICanvasFloatDomInfo>();
|
||||
|
||||
@@ -86,7 +90,6 @@ export class DocFloatDomController extends Disposable {
|
||||
|
||||
private _initialize() {
|
||||
this._drawingAddRemoveListener();
|
||||
this._imageUpdateListener();
|
||||
this._initScrollAndZoomEvent();
|
||||
}
|
||||
|
||||
@@ -194,47 +197,6 @@ export class DocFloatDomController extends Disposable {
|
||||
});
|
||||
}
|
||||
|
||||
private _imageUpdateListener() {
|
||||
this.disposeWithMe(
|
||||
this._drawingManagerService.update$.subscribe((params) => {
|
||||
(params).forEach((param) => {
|
||||
const { unitId, subUnitId, drawingId } = param;
|
||||
|
||||
const drawingParam = this._drawingManagerService.getDrawingByParam(param) as IDocFloatDom;
|
||||
|
||||
if (drawingParam == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { transform, drawingType } = drawingParam;
|
||||
|
||||
if (drawingType !== DrawingTypeEnum.DRAWING_IMAGE) {
|
||||
return;
|
||||
}
|
||||
|
||||
const renderObject = this._getSceneAndTransformerByDrawingSearch(unitId);
|
||||
|
||||
if (renderObject == null) {
|
||||
return;
|
||||
}
|
||||
const { scene } = renderObject;
|
||||
|
||||
if (transform == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const drawingShapeKey = getDrawingShapeKeyByDrawingSearch({ unitId, subUnitId, drawingId });
|
||||
|
||||
const imageShape = scene.getObject(drawingShapeKey) as Rect;
|
||||
|
||||
if (imageShape == null) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
private _addHoverForRect(o: Rect) {
|
||||
this.disposeWithMe(
|
||||
toDisposable(
|
||||
@@ -311,7 +273,7 @@ export class DocFloatDomController extends Disposable {
|
||||
}));
|
||||
}
|
||||
|
||||
insertFloatDom(floatDom: IDocFloatDomDataBase, opts: { width?: number; height: number; drawingId?: string }) {
|
||||
insertFloatDom(floatDom: IDocFloatDomParams, opts: { width?: number; height: number; drawingId?: string }) {
|
||||
const currentDoc = this._univerInstanceService.getCurrentUnitOfType(UniverInstanceType.UNIVER_DOC);
|
||||
if (!currentDoc) return false;
|
||||
const render = this._getSceneAndTransformerByDrawingSearch(currentDoc.getUnitId());
|
||||
@@ -337,12 +299,12 @@ export class DocFloatDomController extends Disposable {
|
||||
},
|
||||
angle: 0,
|
||||
};
|
||||
|
||||
const drawingId = opts.drawingId ?? generateRandomId();
|
||||
const params: IInsertDrawingCommandParams = {
|
||||
unitId: currentDoc.getUnitId(),
|
||||
drawings: [
|
||||
{
|
||||
drawingId: opts.drawingId ?? generateRandomId(),
|
||||
drawingId,
|
||||
drawingType: DrawingTypeEnum.DRAWING_DOM,
|
||||
subUnitId: currentDoc.getUnitId(),
|
||||
unitId: currentDoc.getUnitId(),
|
||||
@@ -355,6 +317,8 @@ export class DocFloatDomController extends Disposable {
|
||||
},
|
||||
],
|
||||
};
|
||||
this._commandService.executeCommand(InsertDocDrawingCommand.id, params);
|
||||
this._commandService.syncExecuteCommand(InsertDocDrawingCommand.id, params);
|
||||
|
||||
return drawingId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import type { DocumentDataModel, IDisposable, Nullable } from '@univerjs/core';
|
||||
import type { BaseObject, Scene } from '@univerjs/engine-render';
|
||||
import { FOCUSING_COMMON_DRAWINGS, IContextService, Inject, IUniverInstanceService, RxDisposable, SHEET_EDITOR_UNITS, toDisposable, UniverInstanceType } from '@univerjs/core';
|
||||
import { DrawingTypeEnum, FOCUSING_COMMON_DRAWINGS, IContextService, Inject, IUniverInstanceService, RxDisposable, SHEET_EDITOR_UNITS, toDisposable, UniverInstanceType } from '@univerjs/core';
|
||||
import { DocCanvasPopManagerService } from '@univerjs/docs-ui';
|
||||
import { IDrawingManagerService } from '@univerjs/drawing';
|
||||
import { COMPONENT_IMAGE_POPUP_MENU, ImageCropperObject, ImageResetSizeOperation, OpenImageCropOperation } from '@univerjs/drawing-ui';
|
||||
@@ -114,7 +114,7 @@ export class DocDrawingPopupMenuController extends RxDisposable {
|
||||
return;
|
||||
}
|
||||
|
||||
const { unitId, subUnitId, drawingId } = drawingParam;
|
||||
const { unitId, subUnitId, drawingId, drawingType } = drawingParam;
|
||||
const popup = this._canvasPopManagerService.attachPopupToObject(
|
||||
object,
|
||||
{
|
||||
@@ -122,7 +122,7 @@ export class DocDrawingPopupMenuController extends RxDisposable {
|
||||
direction: 'horizontal',
|
||||
offset: [2, 0],
|
||||
extraProps: {
|
||||
menuItems: this._getImageMenuItems(unitId, subUnitId, drawingId),
|
||||
menuItems: this._getImageMenuItems(unitId, subUnitId, drawingId, drawingType),
|
||||
},
|
||||
},
|
||||
unitId
|
||||
@@ -176,14 +176,14 @@ export class DocDrawingPopupMenuController extends RxDisposable {
|
||||
);
|
||||
}
|
||||
|
||||
private _getImageMenuItems(unitId: string, subUnitId: string, drawingId: string) {
|
||||
private _getImageMenuItems(unitId: string, subUnitId: string, drawingId: string, drawingType: number) {
|
||||
return [
|
||||
{
|
||||
label: 'image-popup.edit',
|
||||
index: 0,
|
||||
commandId: EditDocDrawingOperation.id,
|
||||
commandParams: { unitId, subUnitId, drawingId },
|
||||
disable: !!SHEET_EDITOR_UNITS.includes(unitId),
|
||||
disable: !!SHEET_EDITOR_UNITS.includes(unitId) || drawingType === DrawingTypeEnum.DRAWING_DOM,
|
||||
},
|
||||
{
|
||||
label: 'image-popup.delete',
|
||||
|
||||
+13
-4
@@ -26,8 +26,8 @@ import { DocSelectionManagerService, DocSkeletonManagerService, RichTextEditingM
|
||||
import { IDocDrawingService } from '@univerjs/docs-drawing';
|
||||
import { docDrawingPositionToTransform, DocSelectionRenderService } from '@univerjs/docs-ui';
|
||||
import { DRAWING_IMAGE_ALLOW_IMAGE_LIST, DRAWING_IMAGE_ALLOW_SIZE, DRAWING_IMAGE_COUNT_LIMIT, DRAWING_IMAGE_HEIGHT_LIMIT, DRAWING_IMAGE_WIDTH_LIMIT, getDrawingShapeKeyByDrawingSearch, getImageSize, IDrawingManagerService, IImageIoService, ImageUploadStatusType } from '@univerjs/drawing';
|
||||
|
||||
import { DocumentEditArea, IRenderManagerService } from '@univerjs/engine-render';
|
||||
|
||||
import { ILocalFileService, IMessageService } from '@univerjs/ui';
|
||||
import { debounceTime } from 'rxjs';
|
||||
import { GroupDocDrawingCommand } from '../../commands/commands/group-doc-drawing.command';
|
||||
@@ -351,13 +351,22 @@ export class DocDrawingUpdateRenderController extends Disposable implements IRen
|
||||
if (drawingShapes.length) {
|
||||
for (const shape of drawingShapes) {
|
||||
scene.detachTransformerFrom(shape);
|
||||
(shape as Image).setOpacity(0.5);
|
||||
try {
|
||||
(shape as Image).setOpacity(0.5);
|
||||
} catch (e) {
|
||||
}
|
||||
if (
|
||||
(isEditBody && drawing.isMultiTransform !== BooleanNumber.TRUE)
|
||||
|| (!isEditBody && drawing.isMultiTransform === BooleanNumber.TRUE)
|
||||
) {
|
||||
scene.attachTransformerTo(shape);
|
||||
(shape as Image).setOpacity(1);
|
||||
if (drawing.allowTransform !== false) {
|
||||
scene.attachTransformerTo(shape);
|
||||
}
|
||||
|
||||
try {
|
||||
(shape as Image).setOpacity(1);
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ export class DrawingRenderService {
|
||||
}
|
||||
|
||||
scene.addObject(rect, DRAWING_OBJECT_LAYER_INDEX);
|
||||
if (this._drawingManagerService.getDrawingEditable()) {
|
||||
if (this._drawingManagerService.getDrawingEditable() && param.allowTransform !== false) {
|
||||
scene.attachTransformerTo(rect);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ export class Rect<T extends IRectProps = IRectProps> extends Shape<T> {
|
||||
override objectType = ObjectType.RECT;
|
||||
|
||||
private _radius: number = 0;
|
||||
private _opacity: number = 1;
|
||||
|
||||
/**
|
||||
* For rendering, in many case object size is bigger than visual size for better user interaction.
|
||||
@@ -65,10 +66,18 @@ export class Rect<T extends IRectProps = IRectProps> extends Shape<T> {
|
||||
return this._radius;
|
||||
}
|
||||
|
||||
get opacity() {
|
||||
return this._opacity;
|
||||
}
|
||||
|
||||
setObjectType(type: ObjectType) {
|
||||
this.objectType = type;
|
||||
}
|
||||
|
||||
setOpacity(opacity: number) {
|
||||
this._opacity = opacity;
|
||||
}
|
||||
|
||||
static override drawWith(ctx: UniverRenderingContext, props: IRectProps) {
|
||||
let { radius, width, height } = props;
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ export interface IFloatDomLayout extends IPosition {
|
||||
left: boolean;
|
||||
top: boolean;
|
||||
};
|
||||
opacity?: number;
|
||||
}
|
||||
|
||||
export interface IFloatDom {
|
||||
|
||||
@@ -58,6 +58,7 @@ const FloatDomSingle = memo((props: { layer: IFloatDom; id: string }) => {
|
||||
domRef.current.style.transform = transformRef.current;
|
||||
domRef.current.style.top = `${topRef.current}px`;
|
||||
domRef.current.style.left = `${leftRef.current}px`;
|
||||
domRef.current.style.opacity = `${position.opacity ?? 1}`;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user