mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Refactor Element Functions (#233)
* Remove `generatedraw` from element object - Create a function that renders a single element - Refactor rendering selected elements * Replace getElementAbsoluteXY with getElementAbsoluteCoords
This commit is contained in:
parent
85365e5bcb
commit
829a65b8cb
14 changed files with 206 additions and 184 deletions
|
@ -2,15 +2,9 @@ import rough from "roughjs/bin/wrappers/rough";
|
|||
|
||||
import { ExcalidrawElement } from "../element/types";
|
||||
|
||||
import {
|
||||
getElementAbsoluteX1,
|
||||
getElementAbsoluteX2,
|
||||
getElementAbsoluteY1,
|
||||
getElementAbsoluteY2,
|
||||
generateDraw
|
||||
} from "../element";
|
||||
import { getElementAbsoluteCoords } from "../element";
|
||||
|
||||
import { renderScene } from "./render";
|
||||
import { renderScene } from "../renderer";
|
||||
import { AppState } from "../types";
|
||||
|
||||
const LOCAL_STORAGE_KEY = "excalidraw";
|
||||
|
@ -94,10 +88,11 @@ export function exportAsPNG(
|
|||
let subCanvasY2 = 0;
|
||||
|
||||
elements.forEach(element => {
|
||||
subCanvasX1 = Math.min(subCanvasX1, getElementAbsoluteX1(element));
|
||||
subCanvasX2 = Math.max(subCanvasX2, getElementAbsoluteX2(element));
|
||||
subCanvasY1 = Math.min(subCanvasY1, getElementAbsoluteY1(element));
|
||||
subCanvasY2 = Math.max(subCanvasY2, getElementAbsoluteY2(element));
|
||||
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
|
||||
subCanvasX1 = Math.min(subCanvasX1, x1);
|
||||
subCanvasY1 = Math.min(subCanvasY1, y1);
|
||||
subCanvasX2 = Math.max(subCanvasX2, x2);
|
||||
subCanvasY2 = Math.max(subCanvasY2, y2);
|
||||
});
|
||||
|
||||
function distance(x: number, y: number) {
|
||||
|
@ -155,8 +150,6 @@ function restore(
|
|||
element.opacity === null || element.opacity === undefined
|
||||
? 100
|
||||
: element.opacity;
|
||||
|
||||
generateDraw(element);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
export { isOverScrollBars } from "./scrollbars";
|
||||
export { renderScene } from "./render";
|
||||
export {
|
||||
clearSelection,
|
||||
getSelectedIndices,
|
||||
|
|
|
@ -1,109 +0,0 @@
|
|||
import { RoughCanvas } from "roughjs/bin/canvas";
|
||||
|
||||
import { ExcalidrawElement } from "../element/types";
|
||||
import {
|
||||
getElementAbsoluteX1,
|
||||
getElementAbsoluteX2,
|
||||
getElementAbsoluteY1,
|
||||
getElementAbsoluteY2,
|
||||
handlerRectangles
|
||||
} from "../element";
|
||||
|
||||
import { roundRect } from "./roundRect";
|
||||
import { SceneState } from "./types";
|
||||
import { getScrollBars, SCROLLBAR_COLOR, SCROLLBAR_WIDTH } from "./scrollbars";
|
||||
import { getSelectedIndices } from "./selection";
|
||||
|
||||
export function renderScene(
|
||||
elements: ExcalidrawElement[],
|
||||
rc: RoughCanvas,
|
||||
canvas: HTMLCanvasElement,
|
||||
sceneState: SceneState,
|
||||
// extra options, currently passed by export helper
|
||||
{
|
||||
offsetX,
|
||||
offsetY,
|
||||
renderScrollbars = true,
|
||||
renderSelection = true
|
||||
}: {
|
||||
offsetX?: number;
|
||||
offsetY?: number;
|
||||
renderScrollbars?: boolean;
|
||||
renderSelection?: boolean;
|
||||
} = {}
|
||||
) {
|
||||
if (!canvas) return;
|
||||
const context = canvas.getContext("2d")!;
|
||||
|
||||
const fillStyle = context.fillStyle;
|
||||
if (typeof sceneState.viewBackgroundColor === "string") {
|
||||
context.fillStyle = sceneState.viewBackgroundColor;
|
||||
context.fillRect(0, 0, canvas.width, canvas.height);
|
||||
} else {
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
context.fillStyle = fillStyle;
|
||||
|
||||
const selectedIndices = getSelectedIndices(elements);
|
||||
|
||||
sceneState = {
|
||||
...sceneState,
|
||||
scrollX: typeof offsetX === "number" ? offsetX : sceneState.scrollX,
|
||||
scrollY: typeof offsetY === "number" ? offsetY : sceneState.scrollY
|
||||
};
|
||||
|
||||
elements.forEach(element => {
|
||||
element.draw(rc, context, sceneState);
|
||||
if (renderSelection && element.isSelected) {
|
||||
const margin = 4;
|
||||
|
||||
const elementX1 = getElementAbsoluteX1(element);
|
||||
const elementX2 = getElementAbsoluteX2(element);
|
||||
const elementY1 = getElementAbsoluteY1(element);
|
||||
const elementY2 = getElementAbsoluteY2(element);
|
||||
const lineDash = context.getLineDash();
|
||||
context.setLineDash([8, 4]);
|
||||
context.strokeRect(
|
||||
elementX1 - margin + sceneState.scrollX,
|
||||
elementY1 - margin + sceneState.scrollY,
|
||||
elementX2 - elementX1 + margin * 2,
|
||||
elementY2 - elementY1 + margin * 2
|
||||
);
|
||||
context.setLineDash(lineDash);
|
||||
|
||||
if (element.type !== "text" && selectedIndices.length === 1) {
|
||||
const handlers = handlerRectangles(element, sceneState);
|
||||
Object.values(handlers).forEach(handler => {
|
||||
context.strokeRect(handler[0], handler[1], handler[2], handler[3]);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (renderScrollbars) {
|
||||
const scrollBars = getScrollBars(
|
||||
elements,
|
||||
context.canvas.width / window.devicePixelRatio,
|
||||
context.canvas.height / window.devicePixelRatio,
|
||||
sceneState.scrollX,
|
||||
sceneState.scrollY
|
||||
);
|
||||
|
||||
const strokeStyle = context.strokeStyle;
|
||||
context.fillStyle = SCROLLBAR_COLOR;
|
||||
context.strokeStyle = "rgba(255,255,255,0.8)";
|
||||
[scrollBars.horizontal, scrollBars.vertical].forEach(scrollBar => {
|
||||
if (scrollBar)
|
||||
roundRect(
|
||||
context,
|
||||
scrollBar.x,
|
||||
scrollBar.y,
|
||||
scrollBar.width,
|
||||
scrollBar.height,
|
||||
SCROLLBAR_WIDTH / 2
|
||||
);
|
||||
});
|
||||
context.strokeStyle = strokeStyle;
|
||||
context.fillStyle = fillStyle;
|
||||
}
|
||||
}
|
|
@ -1,10 +1,5 @@
|
|||
import { ExcalidrawElement } from "../element/types";
|
||||
import {
|
||||
getElementAbsoluteX1,
|
||||
getElementAbsoluteX2,
|
||||
getElementAbsoluteY1,
|
||||
getElementAbsoluteY2
|
||||
} from "../element";
|
||||
import { getElementAbsoluteCoords } from "../element";
|
||||
|
||||
const SCROLLBAR_MIN_SIZE = 15;
|
||||
const SCROLLBAR_MARGIN = 4;
|
||||
|
@ -24,10 +19,11 @@ export function getScrollBars(
|
|||
let maxY = 0;
|
||||
|
||||
elements.forEach(element => {
|
||||
minX = Math.min(minX, getElementAbsoluteX1(element));
|
||||
maxX = Math.max(maxX, getElementAbsoluteX2(element));
|
||||
minY = Math.min(minY, getElementAbsoluteY1(element));
|
||||
maxY = Math.max(maxY, getElementAbsoluteY2(element));
|
||||
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
|
||||
minX = Math.min(minX, x1);
|
||||
minY = Math.min(minY, y1);
|
||||
maxX = Math.max(maxX, x2);
|
||||
maxY = Math.max(maxY, y2);
|
||||
});
|
||||
|
||||
minX += scrollX;
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
import { ExcalidrawElement } from "../element/types";
|
||||
import {
|
||||
getElementAbsoluteX1,
|
||||
getElementAbsoluteX2,
|
||||
getElementAbsoluteY1,
|
||||
getElementAbsoluteY2
|
||||
} from "../element";
|
||||
import { getElementAbsoluteCoords } from "../element";
|
||||
|
||||
export function setSelection(
|
||||
elements: ExcalidrawElement[],
|
||||
selection: ExcalidrawElement
|
||||
) {
|
||||
const selectionX1 = getElementAbsoluteX1(selection);
|
||||
const selectionX2 = getElementAbsoluteX2(selection);
|
||||
const selectionY1 = getElementAbsoluteY1(selection);
|
||||
const selectionY2 = getElementAbsoluteY2(selection);
|
||||
const [
|
||||
selectionX1,
|
||||
selectionY1,
|
||||
selectionX2,
|
||||
selectionY2
|
||||
] = getElementAbsoluteCoords(selection);
|
||||
elements.forEach(element => {
|
||||
const elementX1 = getElementAbsoluteX1(element);
|
||||
const elementX2 = getElementAbsoluteX2(element);
|
||||
const elementY1 = getElementAbsoluteY1(element);
|
||||
const elementY2 = getElementAbsoluteY2(element);
|
||||
const [
|
||||
elementX1,
|
||||
elementY1,
|
||||
elementX2,
|
||||
elementY2
|
||||
] = getElementAbsoluteCoords(element);
|
||||
element.isSelected =
|
||||
element.type !== "selection" &&
|
||||
selectionX1 <= elementX1 &&
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue