alternative clipping improvement
This commit is contained in:
parent
d636abff79
commit
683b80ad2b
@ -77,7 +77,11 @@ import {
|
||||
isEmbeddableOrLabel,
|
||||
createPlaceholderEmbeddableLabel,
|
||||
} from "../element/embeddable";
|
||||
import { getTargetFrame, isElementInFrame } from "../frame";
|
||||
import {
|
||||
elementsAreInFrameBounds,
|
||||
getTargetFrame,
|
||||
isElementInFrame,
|
||||
} from "../frame";
|
||||
import "canvas-roundrect-polyfill";
|
||||
|
||||
export const DEFAULT_SPACING = 2;
|
||||
@ -357,54 +361,6 @@ const renderLinearElementPointHighlight = (
|
||||
context.restore();
|
||||
};
|
||||
|
||||
const getContiguousElements = (
|
||||
elements: readonly ExcalidrawElement[],
|
||||
appState: StaticCanvasAppState,
|
||||
) => {
|
||||
const contiguousElementsArray: ExcalidrawElement[][] = [];
|
||||
|
||||
let previousFrame: ExcalidrawFrameElement | null = null;
|
||||
const contiguousElements: ExcalidrawElement[] = [];
|
||||
|
||||
const isNewContiguous = (
|
||||
element: ExcalidrawElement,
|
||||
targetFrame: ExcalidrawFrameElement | null,
|
||||
) => {
|
||||
return (
|
||||
// element going to be added to some frame or not in any frame
|
||||
!element.frameId ||
|
||||
// element in frame but is either going to be put to a different frame / removed
|
||||
(element.frameId &&
|
||||
appState.selectedElementIds[element.id] &&
|
||||
appState.selectedElementsAreBeingDragged &&
|
||||
(!targetFrame ||
|
||||
isElementInFrame(element, elements, appState, targetFrame))) ||
|
||||
// element in a different frame from previous element
|
||||
element.frameId !== previousFrame?.id
|
||||
);
|
||||
};
|
||||
|
||||
for (const element of elements) {
|
||||
const targetFrame = getTargetFrame(element, appState);
|
||||
if (isNewContiguous(element, targetFrame)) {
|
||||
if (contiguousElements.length > 0) {
|
||||
contiguousElementsArray.push([...contiguousElements]);
|
||||
contiguousElements.length = 0;
|
||||
}
|
||||
|
||||
previousFrame = targetFrame;
|
||||
}
|
||||
|
||||
contiguousElements.push(element);
|
||||
}
|
||||
|
||||
if (contiguousElements.length > 0) {
|
||||
contiguousElementsArray.push([...contiguousElements]);
|
||||
}
|
||||
|
||||
return contiguousElementsArray;
|
||||
};
|
||||
|
||||
const frameClip = (
|
||||
frame: ExcalidrawFrameElement,
|
||||
context: CanvasRenderingContext2D,
|
||||
@ -943,38 +899,6 @@ const _renderInteractiveScene = ({
|
||||
};
|
||||
};
|
||||
|
||||
const renderContiguousElements = (
|
||||
rc: StaticSceneRenderConfig["rc"],
|
||||
appState: StaticSceneRenderConfig["appState"],
|
||||
renderConfig: StaticSceneRenderConfig["renderConfig"],
|
||||
context: CanvasRenderingContext2D,
|
||||
contiguousElements: ExcalidrawElement[],
|
||||
) => {
|
||||
const { isExporting } = renderConfig;
|
||||
|
||||
for (const element of contiguousElements) {
|
||||
try {
|
||||
renderElement(element, rc, context, renderConfig, appState);
|
||||
|
||||
if (
|
||||
isEmbeddableElement(element) &&
|
||||
(isExporting || !element.validated) &&
|
||||
element.width &&
|
||||
element.height
|
||||
) {
|
||||
const label = createPlaceholderEmbeddableLabel(element);
|
||||
renderElement(label, rc, context, renderConfig, appState);
|
||||
}
|
||||
|
||||
if (!isExporting) {
|
||||
renderLinkIcon(element, context, appState);
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const _renderStaticScene = ({
|
||||
canvas,
|
||||
rc,
|
||||
@ -1030,38 +954,58 @@ const _renderStaticScene = ({
|
||||
isEmbeddableOrLabel(el),
|
||||
);
|
||||
|
||||
const contiguousElementsArray = [
|
||||
...getContiguousElements(visibleNonEmbeddableOrLabelElements, appState),
|
||||
...getContiguousElements(visibleEmbeddableOrLabelElements, appState),
|
||||
const visibleElementsToRender = [
|
||||
...visibleNonEmbeddableOrLabelElements,
|
||||
...visibleEmbeddableOrLabelElements,
|
||||
];
|
||||
|
||||
for (const contiguousElements of contiguousElementsArray) {
|
||||
const firstElement = contiguousElements[0];
|
||||
|
||||
if (firstElement) {
|
||||
context.save();
|
||||
const frameId = firstElement.frameId || appState.frameToHighlight?.id;
|
||||
const _renderElement = (element: ExcalidrawElement) => {
|
||||
try {
|
||||
renderElement(element, rc, context, renderConfig, appState);
|
||||
|
||||
if (
|
||||
frameId &&
|
||||
appState.frameRendering.enabled &&
|
||||
appState.frameRendering.clip
|
||||
isEmbeddableElement(element) &&
|
||||
(isExporting || !element.validated) &&
|
||||
element.width &&
|
||||
element.height
|
||||
) {
|
||||
const frame = getTargetFrame(firstElement, appState);
|
||||
|
||||
if (frame && isElementInFrame(firstElement, elements, appState)) {
|
||||
frameClip(frame, context, renderConfig, appState);
|
||||
}
|
||||
const label = createPlaceholderEmbeddableLabel(element);
|
||||
renderElement(label, rc, context, renderConfig, appState);
|
||||
}
|
||||
|
||||
renderContiguousElements(
|
||||
rc,
|
||||
appState,
|
||||
renderConfig,
|
||||
context,
|
||||
contiguousElements,
|
||||
);
|
||||
context.restore();
|
||||
if (!isExporting) {
|
||||
renderLinkIcon(element, context, appState);
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
for (const element of visibleElementsToRender) {
|
||||
const frameId = element.frameId || appState.frameToHighlight?.id;
|
||||
|
||||
if (
|
||||
frameId &&
|
||||
appState.frameRendering.enabled &&
|
||||
appState.frameRendering.clip
|
||||
) {
|
||||
const targetFrame = getTargetFrame(element, appState);
|
||||
// for perf:
|
||||
// only clip elements that are not completely in the target frame
|
||||
if (
|
||||
targetFrame &&
|
||||
!elementsAreInFrameBounds([element], targetFrame) &&
|
||||
isElementInFrame(element, elements, appState)
|
||||
) {
|
||||
context.save();
|
||||
frameClip(targetFrame, context, renderConfig, appState);
|
||||
_renderElement(element);
|
||||
context.restore();
|
||||
} else {
|
||||
_renderElement(element);
|
||||
}
|
||||
} else {
|
||||
_renderElement(element);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user