fix: do not modify elements while erasing (#7531)

This commit is contained in:
David Luzar 2024-01-11 16:00:07 +01:00 committed by GitHub
parent 3ecf72a507
commit 872973f145
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 101 additions and 113 deletions

View file

@ -5,6 +5,7 @@ import {
ExcalidrawFreeDrawElement,
ExcalidrawImageElement,
ExcalidrawTextElementWithContainer,
ExcalidrawFrameLikeElement,
} from "../element/types";
import {
isTextElement,
@ -36,10 +37,12 @@ import {
BinaryFiles,
Zoom,
InteractiveCanvasAppState,
ElementsPendingErasure,
} from "../types";
import { getDefaultAppState } from "../appState";
import {
BOUND_TEXT_PADDING,
ELEMENT_READY_TO_ERASE_OPACITY,
FRAME_STYLE,
MAX_DECIMALS_FOR_SVG_EXPORT,
MIME_TYPES,
@ -94,6 +97,27 @@ const shouldResetImageFilter = (
const getCanvasPadding = (element: ExcalidrawElement) =>
element.type === "freedraw" ? element.strokeWidth * 12 : 20;
export const getRenderOpacity = (
element: ExcalidrawElement,
containingFrame: ExcalidrawFrameLikeElement | null,
elementsPendingErasure: ElementsPendingErasure,
) => {
// multiplying frame opacity with element opacity to combine them
// (e.g. frame 50% and element 50% opacity should result in 25% opacity)
let opacity = ((containingFrame?.opacity ?? 100) * element.opacity) / 10000;
// if pending erasure, multiply again to combine further
// (so that erasing always results in lower opacity than original)
if (
elementsPendingErasure.has(element.id) ||
(containingFrame && elementsPendingErasure.has(containingFrame.id))
) {
opacity *= ELEMENT_READY_TO_ERASE_OPACITY / 100;
}
return opacity;
};
export interface ExcalidrawElementWithCanvas {
element: ExcalidrawElement | ExcalidrawTextElement;
canvas: HTMLCanvasElement;
@ -269,8 +293,6 @@ const drawElementOnCanvas = (
renderConfig: StaticCanvasRenderConfig,
appState: StaticCanvasAppState,
) => {
context.globalAlpha =
((getContainingFrame(element)?.opacity ?? 100) * element.opacity) / 10000;
switch (element.type) {
case "rectangle":
case "iframe":
@ -372,7 +394,6 @@ const drawElementOnCanvas = (
}
}
}
context.globalAlpha = 1;
};
export const elementWithCanvasCache = new WeakMap<
@ -595,6 +616,12 @@ export const renderElement = (
renderConfig: StaticCanvasRenderConfig,
appState: StaticCanvasAppState,
) => {
context.globalAlpha = getRenderOpacity(
element,
getContainingFrame(element),
renderConfig.elementsPendingErasure,
);
switch (element.type) {
case "magicframe":
case "frame": {
@ -831,6 +858,8 @@ export const renderElement = (
throw new Error(`Unimplemented type ${element.type}`);
}
}
context.globalAlpha = 1;
};
const roughSVGDrawWithPrecision = (