|
|
|
|
@ -18,6 +18,21 @@ const LOCAL_STORAGE_KEY_STATE = "excalidraw-state";
@@ -18,6 +18,21 @@ const LOCAL_STORAGE_KEY_STATE = "excalidraw-state";
|
|
|
|
|
|
|
|
|
|
var elements = Array.of<ExcalidrawElement>(); |
|
|
|
|
|
|
|
|
|
// https://stackoverflow.com/questions/521295/seeding-the-random-number-generator-in-javascript/47593316#47593316
|
|
|
|
|
const LCG = (seed: number) => () => |
|
|
|
|
((2 ** 31 - 1) & (seed = Math.imul(48271, seed))) / 2 ** 31; |
|
|
|
|
|
|
|
|
|
// Unfortunately, roughjs doesn't support a seed attribute (https://github.com/pshihn/rough/issues/27).
|
|
|
|
|
// We can achieve the same result by overriding the Math.random function with a
|
|
|
|
|
// pseudo random generator that supports a random seed and swapping it back after.
|
|
|
|
|
function withCustomMathRandom<T>(seed: number, cb: () => T): T { |
|
|
|
|
const random = Math.random; |
|
|
|
|
Math.random = LCG(seed); |
|
|
|
|
const result = cb(); |
|
|
|
|
Math.random = random; |
|
|
|
|
return result; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// https://stackoverflow.com/a/6853926/232122
|
|
|
|
|
function distanceBetweenPointAndSegment( |
|
|
|
|
x: number, |
|
|
|
|
@ -126,6 +141,7 @@ function newElement(
@@ -126,6 +141,7 @@ function newElement(
|
|
|
|
|
isSelected: false, |
|
|
|
|
strokeColor: strokeColor, |
|
|
|
|
backgroundColor: backgroundColor, |
|
|
|
|
seed: Math.floor(Math.random() * 2 ** 31), |
|
|
|
|
draw(rc: RoughCanvas, context: CanvasRenderingContext2D) {} |
|
|
|
|
}; |
|
|
|
|
return element; |
|
|
|
|
@ -307,22 +323,27 @@ function generateDraw(element: ExcalidrawElement) {
@@ -307,22 +323,27 @@ function generateDraw(element: ExcalidrawElement) {
|
|
|
|
|
context.fillStyle = fillStyle; |
|
|
|
|
}; |
|
|
|
|
} else if (element.type === "rectangle") { |
|
|
|
|
const shape = generator.rectangle(0, 0, element.width, element.height, { |
|
|
|
|
stroke: element.strokeColor, |
|
|
|
|
fill: element.backgroundColor |
|
|
|
|
const shape = withCustomMathRandom(element.seed, () => { |
|
|
|
|
return generator.rectangle(0, 0, element.width, element.height, { |
|
|
|
|
stroke: element.strokeColor, |
|
|
|
|
fill: element.backgroundColor |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
element.draw = (rc, context) => { |
|
|
|
|
context.translate(element.x, element.y); |
|
|
|
|
rc.draw(shape); |
|
|
|
|
context.translate(-element.x, -element.y); |
|
|
|
|
}; |
|
|
|
|
} else if (element.type === "ellipse") { |
|
|
|
|
const shape = generator.ellipse( |
|
|
|
|
element.width / 2, |
|
|
|
|
element.height / 2, |
|
|
|
|
element.width, |
|
|
|
|
element.height, |
|
|
|
|
{ stroke: element.strokeColor, fill: element.backgroundColor } |
|
|
|
|
const shape = withCustomMathRandom(element.seed, () => |
|
|
|
|
generator.ellipse( |
|
|
|
|
element.width / 2, |
|
|
|
|
element.height / 2, |
|
|
|
|
element.width, |
|
|
|
|
element.height, |
|
|
|
|
{ stroke: element.strokeColor, fill: element.backgroundColor } |
|
|
|
|
) |
|
|
|
|
); |
|
|
|
|
element.draw = (rc, context) => { |
|
|
|
|
context.translate(element.x, element.y); |
|
|
|
|
@ -331,14 +352,14 @@ function generateDraw(element: ExcalidrawElement) {
@@ -331,14 +352,14 @@ function generateDraw(element: ExcalidrawElement) {
|
|
|
|
|
}; |
|
|
|
|
} else if (element.type === "arrow") { |
|
|
|
|
const [x1, y1, x2, y2, x3, y3, x4, y4] = getArrowPoints(element); |
|
|
|
|
const shapes = [ |
|
|
|
|
const shapes = withCustomMathRandom(element.seed, () => [ |
|
|
|
|
// \
|
|
|
|
|
generator.line(x3, y3, x2, y2, { stroke: element.strokeColor }), |
|
|
|
|
// -----
|
|
|
|
|
generator.line(x1, y1, x2, y2, { stroke: element.strokeColor }), |
|
|
|
|
// /
|
|
|
|
|
generator.line(x4, y4, x2, y2, { stroke: element.strokeColor }) |
|
|
|
|
]; |
|
|
|
|
]); |
|
|
|
|
|
|
|
|
|
element.draw = (rc, context) => { |
|
|
|
|
context.translate(element.x, element.y); |
|
|
|
|
|