mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Remove generatedraw
from element object
- Create a function that renders a single element - Refactor rendering selected elements
This commit is contained in:
parent
85365e5bcb
commit
8593273775
9 changed files with 96 additions and 112 deletions
|
@ -11,5 +11,4 @@ export {
|
|||
export { handlerRectangles } from "./handlerRectangles";
|
||||
export { hitTest } from "./collision";
|
||||
export { resizeTest } from "./resizeTest";
|
||||
export { generateDraw } from "./generateDraw";
|
||||
export { isTextElement } from "./typeChecks";
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
import { RoughCanvas } from "roughjs/bin/canvas";
|
||||
|
||||
import { SceneState } from "../scene/types";
|
||||
import { randomSeed } from "../random";
|
||||
|
||||
export function newElement(
|
||||
|
@ -17,24 +14,19 @@ export function newElement(
|
|||
height = 0
|
||||
) {
|
||||
const element = {
|
||||
type: type,
|
||||
x: x,
|
||||
y: y,
|
||||
width: width,
|
||||
height: height,
|
||||
type,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
strokeColor,
|
||||
backgroundColor,
|
||||
fillStyle,
|
||||
strokeWidth,
|
||||
roughness,
|
||||
opacity,
|
||||
isSelected: false,
|
||||
strokeColor: strokeColor,
|
||||
backgroundColor: backgroundColor,
|
||||
fillStyle: fillStyle,
|
||||
strokeWidth: strokeWidth,
|
||||
roughness: roughness,
|
||||
opacity: opacity,
|
||||
seed: randomSeed(),
|
||||
draw(
|
||||
rc: RoughCanvas,
|
||||
context: CanvasRenderingContext2D,
|
||||
sceneState: SceneState
|
||||
) {}
|
||||
seed: randomSeed()
|
||||
};
|
||||
return element;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { ExcalidrawElement } from "./element/types";
|
||||
import { generateDraw } from "./element";
|
||||
|
||||
class SceneHistory {
|
||||
private recording: boolean = true;
|
||||
|
@ -27,7 +26,6 @@ class SceneHistory {
|
|||
const newElements = JSON.parse(entry);
|
||||
elements.splice(0, elements.length);
|
||||
newElements.forEach((newElement: ExcalidrawElement) => {
|
||||
generateDraw(newElement);
|
||||
elements.push(newElement);
|
||||
});
|
||||
// When restoring, we shouldn't add an history entry otherwise we'll be stuck with it and can't go back
|
||||
|
|
|
@ -4,9 +4,8 @@ import rough from "roughjs/bin/wrappers/rough";
|
|||
|
||||
import { moveOneLeft, moveAllLeft, moveOneRight, moveAllRight } from "./zindex";
|
||||
import { randomSeed } from "./random";
|
||||
import { newElement, resizeTest, generateDraw, isTextElement } from "./element";
|
||||
import { newElement, resizeTest, isTextElement } from "./element";
|
||||
import {
|
||||
renderScene,
|
||||
clearSelection,
|
||||
getSelectedIndices,
|
||||
deleteSelectedElements,
|
||||
|
@ -26,6 +25,8 @@ import {
|
|||
getElementAtPosition,
|
||||
createScene
|
||||
} from "./scene";
|
||||
|
||||
import { renderScene } from "./renderer";
|
||||
import { AppState } from "./types";
|
||||
import { ExcalidrawElement, ExcalidrawTextElement } from "./element/types";
|
||||
|
||||
|
@ -267,7 +268,6 @@ class App extends React.Component<{}, AppState> {
|
|||
element.fillStyle = pastedElement?.fillStyle;
|
||||
element.opacity = pastedElement?.opacity;
|
||||
element.roughness = pastedElement?.roughness;
|
||||
generateDraw(element);
|
||||
}
|
||||
});
|
||||
this.forceUpdate();
|
||||
|
@ -303,7 +303,6 @@ class App extends React.Component<{}, AppState> {
|
|||
elements.forEach(element => {
|
||||
if (element.isSelected) {
|
||||
callback(element);
|
||||
generateDraw(element);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -697,7 +696,6 @@ class App extends React.Component<{}, AppState> {
|
|||
}
|
||||
}
|
||||
|
||||
generateDraw(element);
|
||||
elements.push(element);
|
||||
if (this.state.elementType === "text") {
|
||||
this.setState({
|
||||
|
@ -805,7 +803,6 @@ class App extends React.Component<{}, AppState> {
|
|||
|
||||
el.x = element.x;
|
||||
el.y = element.y;
|
||||
generateDraw(el);
|
||||
});
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
|
@ -856,8 +853,6 @@ class App extends React.Component<{}, AppState> {
|
|||
? Math.abs(width) * Math.sign(height)
|
||||
: height;
|
||||
|
||||
generateDraw(draggingElement);
|
||||
|
||||
if (this.state.elementType === "selection") {
|
||||
setSelection(elements, draggingElement);
|
||||
}
|
||||
|
@ -932,7 +927,6 @@ class App extends React.Component<{}, AppState> {
|
|||
return;
|
||||
}
|
||||
|
||||
generateDraw(element);
|
||||
elements.push(element);
|
||||
|
||||
this.setState({
|
||||
|
@ -989,7 +983,6 @@ class App extends React.Component<{}, AppState> {
|
|||
parsedElement.x = dx ? parsedElement.x + dx : 10 - this.state.scrollX;
|
||||
parsedElement.y = dy ? parsedElement.y + dy : 10 - this.state.scrollY;
|
||||
parsedElement.seed = randomSeed();
|
||||
generateDraw(parsedElement);
|
||||
elements.push(parsedElement);
|
||||
});
|
||||
this.forceUpdate();
|
||||
|
|
1
src/renderer/index.ts
Normal file
1
src/renderer/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export { renderScene } from "./renderScene";
|
|
@ -2,17 +2,23 @@ import rough from "roughjs/bin/wrappers/rough";
|
|||
|
||||
import { withCustomMathRandom } from "../random";
|
||||
|
||||
import { ExcalidrawElement } from "./types";
|
||||
import { isTextElement } from "./typeChecks";
|
||||
import { getDiamondPoints, getArrowPoints } from "./bounds";
|
||||
import { ExcalidrawElement } from "../element/types";
|
||||
import { isTextElement } from "../element/typeChecks";
|
||||
import { getDiamondPoints, getArrowPoints } from "../element/bounds";
|
||||
import { RoughCanvas } from "roughjs/bin/canvas";
|
||||
import { SceneState } from "../scene/types";
|
||||
|
||||
// Casting second argument (DrawingSurface) to any,
|
||||
// because it is requred by TS definitions and not required at runtime
|
||||
const generator = rough.generator(null, null as any);
|
||||
|
||||
export function generateDraw(element: ExcalidrawElement) {
|
||||
export function renderElement(
|
||||
element: ExcalidrawElement,
|
||||
rc: RoughCanvas,
|
||||
context: CanvasRenderingContext2D,
|
||||
{ scrollX, scrollY }: SceneState
|
||||
) {
|
||||
if (element.type === "selection") {
|
||||
element.draw = (rc, context, { scrollX, scrollY }) => {
|
||||
const fillStyle = context.fillStyle;
|
||||
context.fillStyle = "rgba(0, 0, 255, 0.10)";
|
||||
context.fillRect(
|
||||
|
@ -22,7 +28,6 @@ export function generateDraw(element: ExcalidrawElement) {
|
|||
element.height
|
||||
);
|
||||
context.fillStyle = fillStyle;
|
||||
};
|
||||
} else if (element.type === "rectangle") {
|
||||
const shape = withCustomMathRandom(element.seed, () => {
|
||||
return generator.rectangle(0, 0, element.width, element.height, {
|
||||
|
@ -33,13 +38,12 @@ export function generateDraw(element: ExcalidrawElement) {
|
|||
roughness: element.roughness
|
||||
});
|
||||
});
|
||||
element.draw = (rc, context, { scrollX, scrollY }) => {
|
||||
|
||||
context.globalAlpha = element.opacity / 100;
|
||||
context.translate(element.x + scrollX, element.y + scrollY);
|
||||
rc.draw(shape);
|
||||
context.translate(-element.x - scrollX, -element.y - scrollY);
|
||||
context.globalAlpha = 1;
|
||||
};
|
||||
} else if (element.type === "diamond") {
|
||||
const shape = withCustomMathRandom(element.seed, () => {
|
||||
const [
|
||||
|
@ -68,13 +72,11 @@ export function generateDraw(element: ExcalidrawElement) {
|
|||
}
|
||||
);
|
||||
});
|
||||
element.draw = (rc, context, { scrollX, scrollY }) => {
|
||||
context.globalAlpha = element.opacity / 100;
|
||||
context.translate(element.x + scrollX, element.y + scrollY);
|
||||
rc.draw(shape);
|
||||
context.translate(-element.x - scrollX, -element.y - scrollY);
|
||||
context.globalAlpha = 1;
|
||||
};
|
||||
} else if (element.type === "ellipse") {
|
||||
const shape = withCustomMathRandom(element.seed, () =>
|
||||
generator.ellipse(
|
||||
|
@ -91,13 +93,12 @@ export function generateDraw(element: ExcalidrawElement) {
|
|||
}
|
||||
)
|
||||
);
|
||||
element.draw = (rc, context, { scrollX, scrollY }) => {
|
||||
|
||||
context.globalAlpha = element.opacity / 100;
|
||||
context.translate(element.x + scrollX, element.y + scrollY);
|
||||
rc.draw(shape);
|
||||
context.translate(-element.x - scrollX, -element.y - scrollY);
|
||||
context.globalAlpha = 1;
|
||||
};
|
||||
} else if (element.type === "arrow") {
|
||||
const [x1, y1, x2, y2, x3, y3, x4, y4] = getArrowPoints(element);
|
||||
const options = {
|
||||
|
@ -115,16 +116,13 @@ export function generateDraw(element: ExcalidrawElement) {
|
|||
generator.line(x4, y4, x2, y2, options)
|
||||
]);
|
||||
|
||||
element.draw = (rc, context, { scrollX, scrollY }) => {
|
||||
context.globalAlpha = element.opacity / 100;
|
||||
context.translate(element.x + scrollX, element.y + scrollY);
|
||||
shapes.forEach(shape => rc.draw(shape));
|
||||
context.translate(-element.x - scrollX, -element.y - scrollY);
|
||||
context.globalAlpha = 1;
|
||||
};
|
||||
return;
|
||||
} else if (isTextElement(element)) {
|
||||
element.draw = (rc, context, { scrollX, scrollY }) => {
|
||||
context.globalAlpha = element.opacity / 100;
|
||||
const font = context.font;
|
||||
context.font = element.font;
|
||||
|
@ -138,7 +136,6 @@ export function generateDraw(element: ExcalidrawElement) {
|
|||
context.fillStyle = fillStyle;
|
||||
context.font = font;
|
||||
context.globalAlpha = 1;
|
||||
};
|
||||
} else {
|
||||
throw new Error("Unimplemented type " + element.type);
|
||||
}
|
|
@ -9,10 +9,15 @@ import {
|
|||
handlerRectangles
|
||||
} from "../element";
|
||||
|
||||
import { roundRect } from "./roundRect";
|
||||
import { SceneState } from "./types";
|
||||
import { getScrollBars, SCROLLBAR_COLOR, SCROLLBAR_WIDTH } from "./scrollbars";
|
||||
import { getSelectedIndices } from "./selection";
|
||||
import { roundRect } from "../scene/roundRect";
|
||||
import { SceneState } from "../scene/types";
|
||||
import {
|
||||
getScrollBars,
|
||||
SCROLLBAR_COLOR,
|
||||
SCROLLBAR_WIDTH
|
||||
} from "../scene/scrollbars";
|
||||
|
||||
import { renderElement } from "./renderElement";
|
||||
|
||||
export function renderScene(
|
||||
elements: ExcalidrawElement[],
|
||||
|
@ -44,8 +49,6 @@ export function renderScene(
|
|||
}
|
||||
context.fillStyle = fillStyle;
|
||||
|
||||
const selectedIndices = getSelectedIndices(elements);
|
||||
|
||||
sceneState = {
|
||||
...sceneState,
|
||||
scrollX: typeof offsetX === "number" ? offsetX : sceneState.scrollX,
|
||||
|
@ -53,8 +56,13 @@ export function renderScene(
|
|||
};
|
||||
|
||||
elements.forEach(element => {
|
||||
element.draw(rc, context, sceneState);
|
||||
if (renderSelection && element.isSelected) {
|
||||
renderElement(element, rc, context, sceneState);
|
||||
});
|
||||
|
||||
if (renderSelection) {
|
||||
const selectedElements = elements.filter(el => el.isSelected);
|
||||
|
||||
selectedElements.forEach(element => {
|
||||
const margin = 4;
|
||||
|
||||
const elementX1 = getElementAbsoluteX1(element);
|
||||
|
@ -70,15 +78,15 @@ export function renderScene(
|
|||
elementY2 - elementY1 + margin * 2
|
||||
);
|
||||
context.setLineDash(lineDash);
|
||||
});
|
||||
|
||||
if (element.type !== "text" && selectedIndices.length === 1) {
|
||||
const handlers = handlerRectangles(element, sceneState);
|
||||
if (selectedElements.length === 1 && selectedElements[0].type !== "text") {
|
||||
const handlers = handlerRectangles(selectedElements[0], sceneState);
|
||||
Object.values(handlers).forEach(handler => {
|
||||
context.strokeRect(handler[0], handler[1], handler[2], handler[3]);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (renderScrollbars) {
|
||||
const scrollBars = getScrollBars(
|
|
@ -6,11 +6,10 @@ import {
|
|||
getElementAbsoluteX1,
|
||||
getElementAbsoluteX2,
|
||||
getElementAbsoluteY1,
|
||||
getElementAbsoluteY2,
|
||||
generateDraw
|
||||
getElementAbsoluteY2
|
||||
} from "../element";
|
||||
|
||||
import { renderScene } from "./render";
|
||||
import { renderScene } from "../renderer";
|
||||
import { AppState } from "../types";
|
||||
|
||||
const LOCAL_STORAGE_KEY = "excalidraw";
|
||||
|
@ -155,8 +154,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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue