fix(editor): limit max width when uploading or pasting image into edgeless (#9273)

[BS-2180](https://linear.app/affine-design/issue/BS-2180/白板中粘贴图片,限定一下最大宽度)
This commit is contained in:
donteatfriedrice
2024-12-24 06:28:59 +00:00
parent 4ce5cf20c3
commit 338835a4aa
7 changed files with 34 additions and 14 deletions

View File

@@ -1,4 +1,3 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import {
CanvasElementType,
SurfaceGroupLikeModel,
@@ -9,6 +8,7 @@ import {
BookmarkStyles,
DEFAULT_NOTE_HEIGHT,
DEFAULT_NOTE_WIDTH,
MAX_IMAGE_WIDTH,
ReferenceInfoSchema,
} from '@blocksuite/affine-model';
import {
@@ -256,7 +256,10 @@ export class EdgelessClipboardController extends PageClipboard {
// when only images in clipboard, add image-blocks else add all files as attachments
if (attachmentFiles.length === 0) {
await addImages(this.std, imageFiles, point);
await addImages(this.std, imageFiles, {
point,
maxWidth: MAX_IMAGE_WIDTH,
});
} else {
await addAttachments(this.std, [...files], point);
}
@@ -359,7 +362,7 @@ export class EdgelessClipboardController extends PageClipboard {
const svg = tryGetSvgFromClipboard(data);
if (svg) {
await addImages(this.std, [svg], point);
await addImages(this.std, [svg], { point, maxWidth: MAX_IMAGE_WIDTH });
return;
}
try {

View File

@@ -1,4 +1,5 @@
import { AttachmentIcon, LinkIcon } from '@blocksuite/affine-components/icons';
import { MAX_IMAGE_WIDTH } from '@blocksuite/affine-model';
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
import type { GfxToolsFullOptionValue } from '@blocksuite/block-std/gfx';
import { effect } from '@preact/signals-core';
@@ -55,7 +56,9 @@ export class EdgelessNoteMenu extends EdgelessToolbarToolMixin(LitElement) {
private async _addImages() {
this._imageLoading = true;
const imageFiles = await getImageFilesFromLocal();
const ids = await addImages(this.edgeless.std, imageFiles);
const ids = await addImages(this.edgeless.std, imageFiles, {
maxWidth: MAX_IMAGE_WIDTH,
});
this._imageLoading = false;
this.edgeless.gfx.tool.setTool('default');
this.edgeless.gfx.selection.set({ elements: ids });

View File

@@ -118,7 +118,10 @@ export async function addAttachments(
export async function addImages(
std: BlockStdScope,
files: File[],
point?: IVec
options: {
point?: IVec;
maxWidth?: number;
}
): Promise<string[]> {
const imageFiles = [...files].filter(file => file.type.startsWith('image/'));
if (!imageFiles.length) return [];
@@ -145,6 +148,7 @@ export async function addImages(
return [];
}
const { point, maxWidth } = options;
let { x, y } = gfx.viewport.center;
if (point) [x, y] = gfx.viewport.toModelCoord(...point);
@@ -166,6 +170,7 @@ export async function addImages(
{
size: file.size,
xywh: bound.serialize(),
index: gfx.layer.generateIndex(),
},
gfx.surface
);
@@ -180,17 +185,22 @@ export async function addImages(
const imageSize = await readImageSize(file);
const center = Vec.toVec(point);
const bound = calcBoundByOrigin(
center,
inTopLeft,
imageSize.width,
imageSize.height
);
// If maxWidth is provided, limit the width of the image to maxWidth
// Otherwise, use the original width
const width = maxWidth
? Math.min(imageSize.width, maxWidth)
: imageSize.width;
const height = maxWidth
? (imageSize.height / imageSize.width) * width
: imageSize.height;
const bound = calcBoundByOrigin(center, inTopLeft, width, height);
std.doc.withoutTransact(() => {
gfx.updateElement(blockId, {
sourceId,
...imageSize,
width,
height,
xywh: bound.serialize(),
} satisfies Partial<ImageBlockProps>);
});