simplify crop properties
This commit is contained in:
parent
997fec6c75
commit
064bede0c5
@ -7604,6 +7604,11 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
pointerDownState: PointerDownState,
|
pointerDownState: PointerDownState,
|
||||||
) {
|
) {
|
||||||
return withBatchedUpdatesThrottled((event: PointerEvent) => {
|
return withBatchedUpdatesThrottled((event: PointerEvent) => {
|
||||||
|
const pointerCoords = viewportCoordsToSceneCoords(event, this.state);
|
||||||
|
const lastPointerCoords =
|
||||||
|
this.lastPointerMoveCoords ?? pointerDownState.origin;
|
||||||
|
this.lastPointerMoveCoords = pointerCoords;
|
||||||
|
|
||||||
// We need to initialize dragOffsetXY only after we've updated
|
// We need to initialize dragOffsetXY only after we've updated
|
||||||
// `state.selectedElementIds` on pointerDown. Doing it here in pointerMove
|
// `state.selectedElementIds` on pointerDown. Doing it here in pointerMove
|
||||||
// event handler should hopefully ensure we're already working with
|
// event handler should hopefully ensure we're already working with
|
||||||
@ -7626,8 +7631,6 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const pointerCoords = viewportCoordsToSceneCoords(event, this.state);
|
|
||||||
|
|
||||||
if (isEraserActive(this.state)) {
|
if (isEraserActive(this.state)) {
|
||||||
this.handleEraser(event, pointerDownState, pointerCoords);
|
this.handleEraser(event, pointerDownState, pointerCoords);
|
||||||
return;
|
return;
|
||||||
@ -7852,53 +7855,55 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
selectedElements[0].crop !== null
|
selectedElements[0].crop !== null
|
||||||
) {
|
) {
|
||||||
const crop = selectedElements[0].crop;
|
const crop = selectedElements[0].crop;
|
||||||
const image = selectedElements[0];
|
const image =
|
||||||
|
isInitializedImageElement(selectedElements[0]) &&
|
||||||
|
this.imageCache.get(selectedElements[0].fileId)?.image;
|
||||||
|
|
||||||
const lastPointerCoords =
|
if (image && !(image instanceof Promise)) {
|
||||||
this.lastPointerMoveCoords ?? pointerDownState.origin;
|
const instantDragOffset = {
|
||||||
|
x: pointerCoords.x - lastPointerCoords.x,
|
||||||
|
y: pointerCoords.y - lastPointerCoords.y,
|
||||||
|
};
|
||||||
|
|
||||||
const instantDragOffset = {
|
// current offset is based on the element's width and height
|
||||||
x: pointerCoords.x - lastPointerCoords.x,
|
const uncroppedWidth =
|
||||||
y: pointerCoords.y - lastPointerCoords.y,
|
selectedElements[0].initialWidth *
|
||||||
};
|
selectedElements[0].resizeFactors[0];
|
||||||
|
const uncroppedHeight =
|
||||||
|
selectedElements[0].initialHeight *
|
||||||
|
selectedElements[0].resizeFactors[1];
|
||||||
|
|
||||||
// current offset is based on the element's width and height
|
const SENSITIVITY_FACTOR = 3;
|
||||||
const uncroppedWidth = image.widthAtCreation * image.resizedFactorX;
|
|
||||||
const uncroppedHeight =
|
|
||||||
image.heightAtCreation * image.resizedFactorY;
|
|
||||||
|
|
||||||
const SENSITIVITY_FACTOR = 3;
|
const adjustedOffset = {
|
||||||
|
x:
|
||||||
|
instantDragOffset.x *
|
||||||
|
(uncroppedWidth / image.naturalWidth) *
|
||||||
|
SENSITIVITY_FACTOR,
|
||||||
|
y:
|
||||||
|
instantDragOffset.y *
|
||||||
|
(uncroppedHeight / image.naturalHeight) *
|
||||||
|
SENSITIVITY_FACTOR,
|
||||||
|
};
|
||||||
|
|
||||||
const adjustedOffset = {
|
const nextCrop = {
|
||||||
x:
|
...crop,
|
||||||
instantDragOffset.x *
|
x: clamp(
|
||||||
(uncroppedWidth / image.naturalWidth) *
|
crop.x - adjustedOffset.x,
|
||||||
SENSITIVITY_FACTOR,
|
0,
|
||||||
y:
|
image.naturalWidth - crop.width,
|
||||||
instantDragOffset.y *
|
),
|
||||||
(uncroppedHeight / image.naturalHeight) *
|
y: clamp(
|
||||||
SENSITIVITY_FACTOR,
|
crop.y - adjustedOffset.y,
|
||||||
};
|
0,
|
||||||
|
image.naturalHeight - crop.height,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
const nextCrop = {
|
mutateElement(selectedElements[0], {
|
||||||
...crop,
|
crop: nextCrop,
|
||||||
x: clamp(
|
});
|
||||||
crop.x - adjustedOffset.x,
|
}
|
||||||
0,
|
|
||||||
image.naturalWidth - crop.width,
|
|
||||||
),
|
|
||||||
y: clamp(
|
|
||||||
crop.y - adjustedOffset.y,
|
|
||||||
0,
|
|
||||||
image.naturalHeight - crop.height,
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
||||||
mutateElement(image, {
|
|
||||||
crop: nextCrop,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.lastPointerMoveCoords = pointerCoords;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -8037,7 +8042,6 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
this.maybeCacheReferenceSnapPoints(event, selectedElements, true);
|
this.maybeCacheReferenceSnapPoints(event, selectedElements, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.lastPointerMoveCoords = pointerCoords;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9478,12 +9482,14 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
y,
|
y,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
widthAtCreation: width,
|
initialWidth: width,
|
||||||
heightAtCreation: height,
|
initialHeight: height,
|
||||||
naturalWidth: image.naturalWidth,
|
crop: {
|
||||||
naturalHeight: image.naturalHeight,
|
x: 0,
|
||||||
resizedFactorX: 1,
|
y: 0,
|
||||||
resizedFactorY: 1,
|
width: image.naturalWidth,
|
||||||
|
height: image.naturalHeight,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -10053,6 +10059,7 @@ class App extends React.Component<AppProps, AppState> {
|
|||||||
cropElement(
|
cropElement(
|
||||||
elementToCrop,
|
elementToCrop,
|
||||||
this.scene.getNonDeletedElementsMap(),
|
this.scene.getNonDeletedElementsMap(),
|
||||||
|
this.imageCache,
|
||||||
transformHandleType,
|
transformHandleType,
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
|
@ -255,13 +255,9 @@ const restoreElement = (
|
|||||||
fileId: element.fileId,
|
fileId: element.fileId,
|
||||||
scale: element.scale || [1, 1],
|
scale: element.scale || [1, 1],
|
||||||
crop: element.crop ?? null,
|
crop: element.crop ?? null,
|
||||||
// TODO: restore properly
|
initialWidth: element.initialWidth ?? element.width,
|
||||||
widthAtCreation: element.widthAtCreation,
|
initialHeight: element.initialHeight ?? element.height,
|
||||||
heightAtCreation: element.heightAtCreation,
|
resizeFactors: element.resizeFactors ?? [1, 1],
|
||||||
naturalWidth: element.naturalWidth,
|
|
||||||
naturalHeight: element.naturalHeight,
|
|
||||||
resizedFactorX: element.resizedFactorX,
|
|
||||||
resizedFactorY: element.resizedFactorY,
|
|
||||||
});
|
});
|
||||||
case "line":
|
case "line":
|
||||||
// @ts-ignore LEGACY type
|
// @ts-ignore LEGACY type
|
||||||
|
@ -26,19 +26,22 @@ import {
|
|||||||
getElementAbsoluteCoords,
|
getElementAbsoluteCoords,
|
||||||
getResizedElementAbsoluteCoords,
|
getResizedElementAbsoluteCoords,
|
||||||
} from "./bounds";
|
} from "./bounds";
|
||||||
|
import { AppClassProperties } from "../types";
|
||||||
|
import { isInitializedImageElement } from "./typeChecks";
|
||||||
|
|
||||||
// i split out these 'internal' functions so that this functionality can be easily unit tested
|
const _cropElement = (
|
||||||
const cropElementInternal = (
|
|
||||||
element: ExcalidrawImageElement,
|
element: ExcalidrawImageElement,
|
||||||
transformHandle: TransformHandleType,
|
transformHandle: TransformHandleType,
|
||||||
|
naturalWidth: number,
|
||||||
|
naturalHeight: number,
|
||||||
pointerX: number,
|
pointerX: number,
|
||||||
pointerY: number,
|
pointerY: number,
|
||||||
) => {
|
) => {
|
||||||
const uncroppedWidth = element.widthAtCreation * element.resizedFactorX;
|
const uncroppedWidth = element.initialWidth * element.resizeFactors[0];
|
||||||
const uncroppedHeight = element.heightAtCreation * element.resizedFactorY;
|
const uncroppedHeight = element.initialHeight * element.resizeFactors[1];
|
||||||
|
|
||||||
const naturalWidthToUncropped = element.naturalWidth / uncroppedWidth;
|
const naturalWidthToUncropped = naturalWidth / uncroppedWidth;
|
||||||
const naturalHeightToUncropped = element.naturalHeight / uncroppedHeight;
|
const naturalHeightToUncropped = naturalHeight / uncroppedHeight;
|
||||||
|
|
||||||
const croppedLeft = (element.crop?.x ?? 0) / naturalWidthToUncropped;
|
const croppedLeft = (element.crop?.x ?? 0) / naturalWidthToUncropped;
|
||||||
const croppedTop = (element.crop?.y ?? 0) / naturalHeightToUncropped;
|
const croppedTop = (element.crop?.y ?? 0) / naturalHeightToUncropped;
|
||||||
@ -71,8 +74,8 @@ const cropElementInternal = (
|
|||||||
const crop = element.crop ?? {
|
const crop = element.crop ?? {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
width: element.naturalWidth,
|
width: naturalWidth,
|
||||||
height: element.naturalHeight,
|
height: naturalHeight,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (transformHandle.includes("n")) {
|
if (transformHandle.includes("n")) {
|
||||||
@ -84,9 +87,8 @@ const cropElementInternal = (
|
|||||||
const pointerDeltaY = pointerY - element.y;
|
const pointerDeltaY = pointerY - element.y;
|
||||||
nextHeight = element.height - pointerDeltaY;
|
nextHeight = element.height - pointerDeltaY;
|
||||||
|
|
||||||
crop.y =
|
crop.y = ((pointerDeltaY + croppedTop) / uncroppedHeight) * naturalHeight;
|
||||||
((pointerDeltaY + croppedTop) / uncroppedHeight) * element.naturalHeight;
|
crop.height = (nextHeight / uncroppedHeight) * naturalHeight;
|
||||||
crop.height = (nextHeight / uncroppedHeight) * element.naturalHeight;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transformHandle.includes("s")) {
|
if (transformHandle.includes("s")) {
|
||||||
@ -96,7 +98,7 @@ const cropElementInternal = (
|
|||||||
pointerY = clamp(pointerY, northBound, southBound);
|
pointerY = clamp(pointerY, northBound, southBound);
|
||||||
|
|
||||||
nextHeight = pointerY - element.y;
|
nextHeight = pointerY - element.y;
|
||||||
crop.height = (nextHeight / uncroppedHeight) * element.naturalHeight;
|
crop.height = (nextHeight / uncroppedHeight) * naturalHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transformHandle.includes("w")) {
|
if (transformHandle.includes("w")) {
|
||||||
@ -108,9 +110,8 @@ const cropElementInternal = (
|
|||||||
const pointerDeltaX = pointerX - element.x;
|
const pointerDeltaX = pointerX - element.x;
|
||||||
nextWidth = element.width - pointerDeltaX;
|
nextWidth = element.width - pointerDeltaX;
|
||||||
|
|
||||||
crop.x =
|
crop.x = ((pointerDeltaX + croppedLeft) / uncroppedWidth) * naturalWidth;
|
||||||
((pointerDeltaX + croppedLeft) / uncroppedWidth) * element.naturalWidth;
|
crop.width = (nextWidth / uncroppedWidth) * naturalWidth;
|
||||||
crop.width = (nextWidth / uncroppedWidth) * element.naturalWidth;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transformHandle.includes("e")) {
|
if (transformHandle.includes("e")) {
|
||||||
@ -120,7 +121,7 @@ const cropElementInternal = (
|
|||||||
pointerX = clamp(pointerX, westBound, eastBound);
|
pointerX = clamp(pointerX, westBound, eastBound);
|
||||||
|
|
||||||
nextWidth = pointerX - element.x;
|
nextWidth = pointerX - element.x;
|
||||||
crop.width = (nextWidth / uncroppedWidth) * element.naturalWidth;
|
crop.width = (nextWidth / uncroppedWidth) * naturalWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newOrigin = recomputeOrigin(
|
const newOrigin = recomputeOrigin(
|
||||||
@ -142,22 +143,30 @@ const cropElementInternal = (
|
|||||||
export const cropElement = (
|
export const cropElement = (
|
||||||
element: ExcalidrawImageElement,
|
element: ExcalidrawImageElement,
|
||||||
elementsMap: NonDeletedSceneElementsMap,
|
elementsMap: NonDeletedSceneElementsMap,
|
||||||
|
imageCache: AppClassProperties["imageCache"],
|
||||||
transformHandle: TransformHandleType,
|
transformHandle: TransformHandleType,
|
||||||
pointerX: number,
|
pointerX: number,
|
||||||
pointerY: number,
|
pointerY: number,
|
||||||
) => {
|
) => {
|
||||||
const mutation = cropElementInternal(
|
const image =
|
||||||
element,
|
isInitializedImageElement(element) && imageCache.get(element.fileId)?.image;
|
||||||
transformHandle,
|
|
||||||
pointerX,
|
|
||||||
pointerY,
|
|
||||||
);
|
|
||||||
|
|
||||||
mutateElement(element, mutation);
|
if (image && !(image instanceof Promise)) {
|
||||||
|
const mutation = _cropElement(
|
||||||
|
element,
|
||||||
|
transformHandle,
|
||||||
|
image.naturalWidth,
|
||||||
|
image.naturalHeight,
|
||||||
|
pointerX,
|
||||||
|
pointerY,
|
||||||
|
);
|
||||||
|
|
||||||
updateBoundElements(element, elementsMap, {
|
mutateElement(element, mutation);
|
||||||
oldSize: { width: element.width, height: element.height },
|
|
||||||
});
|
updateBoundElements(element, elementsMap, {
|
||||||
|
oldSize: { width: element.width, height: element.height },
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: replace with the refactored resizeSingleElement
|
// TODO: replace with the refactored resizeSingleElement
|
||||||
@ -222,71 +231,77 @@ const recomputeOrigin = (
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getUncroppedImageElement = (
|
export const getUncroppedImageElement = (
|
||||||
image: ExcalidrawImageElement,
|
element: ExcalidrawImageElement,
|
||||||
elementsMap: ElementsMap,
|
elementsMap: ElementsMap,
|
||||||
|
imageCache: AppClassProperties["imageCache"],
|
||||||
) => {
|
) => {
|
||||||
if (image.crop) {
|
const image =
|
||||||
const width = image.widthAtCreation * image.resizedFactorX;
|
isInitializedImageElement(element) && imageCache.get(element.fileId)?.image;
|
||||||
const height = image.heightAtCreation * image.resizedFactorY;
|
|
||||||
|
|
||||||
const [x1, y1, x2, y2, cx, cy] = getElementAbsoluteCoords(
|
if (image && !(image instanceof Promise)) {
|
||||||
image,
|
if (element.crop) {
|
||||||
elementsMap,
|
const width = element.initialWidth * element.resizeFactors[0];
|
||||||
);
|
const height = element.initialHeight * element.resizeFactors[1];
|
||||||
|
|
||||||
const topLeftVector = vectorFromPoint(
|
const [x1, y1, x2, y2, cx, cy] = getElementAbsoluteCoords(
|
||||||
pointRotateRads(point(x1, y1), point(cx, cy), image.angle),
|
element,
|
||||||
);
|
elementsMap,
|
||||||
const topRightVector = vectorFromPoint(
|
);
|
||||||
pointRotateRads(point(x2, y1), point(cx, cy), image.angle),
|
|
||||||
);
|
|
||||||
const topEdgeNormalized = vectorNormalize(
|
|
||||||
vectorSubtract(topRightVector, topLeftVector),
|
|
||||||
);
|
|
||||||
const bottomLeftVector = vectorFromPoint(
|
|
||||||
pointRotateRads(point(x1, y2), point(cx, cy), image.angle),
|
|
||||||
);
|
|
||||||
const leftEdgeVector = vectorSubtract(bottomLeftVector, topLeftVector);
|
|
||||||
const leftEdgeNormalized = vectorNormalize(leftEdgeVector);
|
|
||||||
|
|
||||||
const rotatedTopLeft = vectorAdd(
|
const topLeftVector = vectorFromPoint(
|
||||||
vectorAdd(
|
pointRotateRads(point(x1, y1), point(cx, cy), element.angle),
|
||||||
topLeftVector,
|
);
|
||||||
vectorScale(
|
const topRightVector = vectorFromPoint(
|
||||||
topEdgeNormalized,
|
pointRotateRads(point(x2, y1), point(cx, cy), element.angle),
|
||||||
(-image.crop.x * width) / image.naturalWidth,
|
);
|
||||||
|
const topEdgeNormalized = vectorNormalize(
|
||||||
|
vectorSubtract(topRightVector, topLeftVector),
|
||||||
|
);
|
||||||
|
const bottomLeftVector = vectorFromPoint(
|
||||||
|
pointRotateRads(point(x1, y2), point(cx, cy), element.angle),
|
||||||
|
);
|
||||||
|
const leftEdgeVector = vectorSubtract(bottomLeftVector, topLeftVector);
|
||||||
|
const leftEdgeNormalized = vectorNormalize(leftEdgeVector);
|
||||||
|
|
||||||
|
const rotatedTopLeft = vectorAdd(
|
||||||
|
vectorAdd(
|
||||||
|
topLeftVector,
|
||||||
|
vectorScale(
|
||||||
|
topEdgeNormalized,
|
||||||
|
(-element.crop.x * width) / image.naturalWidth,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
vectorScale(
|
||||||
vectorScale(
|
leftEdgeNormalized,
|
||||||
leftEdgeNormalized,
|
(-element.crop.y * height) / image.naturalHeight,
|
||||||
(-image.crop.y * height) / image.naturalHeight,
|
),
|
||||||
),
|
);
|
||||||
);
|
|
||||||
|
|
||||||
const center = pointFromVector(
|
const center = pointFromVector(
|
||||||
vectorAdd(
|
vectorAdd(
|
||||||
vectorAdd(rotatedTopLeft, vectorScale(topEdgeNormalized, width / 2)),
|
vectorAdd(rotatedTopLeft, vectorScale(topEdgeNormalized, width / 2)),
|
||||||
vectorScale(leftEdgeNormalized, height / 2),
|
vectorScale(leftEdgeNormalized, height / 2),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
const unrotatedTopLeft = pointRotateRads(
|
const unrotatedTopLeft = pointRotateRads(
|
||||||
pointFromVector(rotatedTopLeft),
|
pointFromVector(rotatedTopLeft),
|
||||||
center,
|
center,
|
||||||
-image.angle as Radians,
|
-element.angle as Radians,
|
||||||
);
|
);
|
||||||
|
|
||||||
const uncroppedElement: ExcalidrawImageElement = {
|
const uncroppedElement: ExcalidrawImageElement = {
|
||||||
...image,
|
...element,
|
||||||
x: unrotatedTopLeft[0],
|
x: unrotatedTopLeft[0],
|
||||||
y: unrotatedTopLeft[1],
|
y: unrotatedTopLeft[1],
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
crop: null,
|
crop: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
return uncroppedElement;
|
return uncroppedElement;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return image;
|
return element;
|
||||||
};
|
};
|
||||||
|
@ -489,13 +489,10 @@ export const newImageElement = (
|
|||||||
status: opts.status ?? "pending",
|
status: opts.status ?? "pending",
|
||||||
fileId: opts.fileId ?? null,
|
fileId: opts.fileId ?? null,
|
||||||
scale: opts.scale ?? [1, 1],
|
scale: opts.scale ?? [1, 1],
|
||||||
widthAtCreation: 0,
|
initialWidth: opts.width ?? 0,
|
||||||
heightAtCreation: 0,
|
initialHeight: opts.height ?? 0,
|
||||||
naturalWidth: 0,
|
resizeFactors: [1, 1],
|
||||||
naturalHeight: 0,
|
|
||||||
crop: opts.crop ?? null,
|
crop: opts.crop ?? null,
|
||||||
resizedFactorX: 1,
|
|
||||||
resizedFactorY: 1,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -782,8 +782,10 @@ const updateInternalScale = (
|
|||||||
scaleY = Math.abs(scaleY);
|
scaleY = Math.abs(scaleY);
|
||||||
|
|
||||||
mutateElement(element, {
|
mutateElement(element, {
|
||||||
resizedFactorX: element.resizedFactorX * scaleX,
|
resizeFactors: [
|
||||||
resizedFactorY: element.resizedFactorY * scaleY,
|
element.resizeFactors[0] * scaleX,
|
||||||
|
element.resizeFactors[1] * scaleY,
|
||||||
|
],
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -141,15 +141,11 @@ export type ExcalidrawImageElement = _ExcalidrawElementBase &
|
|||||||
/** X and Y scale factors <-1, 1>, used for image axis flipping */
|
/** X and Y scale factors <-1, 1>, used for image axis flipping */
|
||||||
scale: [number, number];
|
scale: [number, number];
|
||||||
|
|
||||||
/** the image's dimension after adjustment at creation */
|
/** the image's dimension after initialization */
|
||||||
widthAtCreation: number;
|
initialWidth: number;
|
||||||
heightAtCreation: number;
|
initialHeight: number;
|
||||||
/** how much the image has been resized with respect the dimension at creation */
|
/** how much the image has been resized with respect the dimension at creation */
|
||||||
resizedFactorX: number;
|
resizeFactors: [number, number];
|
||||||
resizedFactorY: number;
|
|
||||||
|
|
||||||
naturalWidth: number;
|
|
||||||
naturalHeight: number;
|
|
||||||
|
|
||||||
crop: {
|
crop: {
|
||||||
x: number;
|
x: number;
|
||||||
|
@ -446,8 +446,8 @@ const drawElementOnCanvas = (
|
|||||||
: {
|
: {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
width: element.naturalWidth,
|
width: img.naturalWidth,
|
||||||
height: element.naturalHeight,
|
height: img.naturalHeight,
|
||||||
};
|
};
|
||||||
|
|
||||||
context.drawImage(
|
context.drawImage(
|
||||||
@ -950,7 +950,11 @@ export const renderElement = (
|
|||||||
context.globalAlpha = 0.1;
|
context.globalAlpha = 0.1;
|
||||||
|
|
||||||
const uncroppedElementCanvas = generateElementCanvas(
|
const uncroppedElementCanvas = generateElementCanvas(
|
||||||
getUncroppedImageElement(elementWithCanvas.element, elementsMap),
|
getUncroppedImageElement(
|
||||||
|
elementWithCanvas.element,
|
||||||
|
elementsMap,
|
||||||
|
renderConfig.imageCache,
|
||||||
|
),
|
||||||
allElementsMap,
|
allElementsMap,
|
||||||
appState.zoom,
|
appState.zoom,
|
||||||
renderConfig,
|
renderConfig,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user