Files
excalidraw/src/element/newElement.ts
T
Jed Fox c6a0cfc2b1 Refactor (#862)
* Initial factoring out of parts of the LayerUI component

2360 → 2224 LOC

* Create a Section component

* Break up src/index.tsx

* Refactor actions to reduce duplication, fix CSS

Also consolidate icons

* Move scene/data.ts to its own directory

* Fix accidental reverts, banish further single-character variables

* ACTIVE_ELEM_COLOR → ACTIVE_ELEMENT_COLOR

* Further refactoring the icons file

* Log all errors

* Pointer Event polyfill to make the tests work

* add test hooks & fix tests

Co-authored-by: dwelle <luzar.david@gmail.com>
2020-03-07 16:20:38 +01:00

114 lines
2.7 KiB
TypeScript

import { randomSeed } from "roughjs/bin/math";
import nanoid from "nanoid";
import { Drawable } from "roughjs/bin/core";
import { Point } from "roughjs/bin/geometry";
import { ExcalidrawElement, ExcalidrawTextElement } from "../element/types";
import { measureText } from "../utils";
export function newElement(
type: string,
x: number,
y: number,
strokeColor: string,
backgroundColor: string,
fillStyle: string,
strokeWidth: number,
roughness: number,
opacity: number,
width = 0,
height = 0,
) {
const element = {
id: nanoid(),
type,
x,
y,
width,
height,
strokeColor,
backgroundColor,
fillStyle,
strokeWidth,
roughness,
opacity,
isSelected: false,
seed: randomSeed(),
shape: null as Drawable | Drawable[] | null,
points: [] as Point[],
canvas: null as HTMLCanvasElement | null,
canvasZoom: 1, // The zoom level used to render the cached canvas
canvasOffsetX: 0,
canvasOffsetY: 0,
};
return element;
}
export function newTextElement(
element: ExcalidrawElement,
text: string,
font: string,
) {
const metrics = measureText(text, font);
const textElement: ExcalidrawTextElement = {
...element,
shape: null,
type: "text",
text: text,
font: font,
// Center the text
x: element.x - metrics.width / 2,
y: element.y - metrics.height / 2,
width: metrics.width,
height: metrics.height,
baseline: metrics.baseline,
};
return textElement;
}
// Simplified deep clone for the purpose of cloning ExcalidrawElement only
// (doesn't clone Date, RegExp, Map, Set, Typed arrays etc.)
//
// Adapted from https://github.com/lukeed/klona
function _duplicateElement(val: any, depth: number = 0) {
if (val == null || typeof val !== "object") {
return val;
}
if (Object.prototype.toString.call(val) === "[object Object]") {
const tmp =
typeof val.constructor === "function"
? Object.create(Object.getPrototypeOf(val))
: {};
for (const key in val) {
if (val.hasOwnProperty(key)) {
// don't copy top-level shape property, which we want to regenerate
if (depth === 0 && (key === "shape" || key === "canvas")) {
continue;
}
tmp[key] = _duplicateElement(val[key], depth + 1);
}
}
return tmp;
}
if (Array.isArray(val)) {
let k = val.length;
const arr = new Array(k);
while (k--) {
arr[k] = _duplicateElement(val[k], depth + 1);
}
return arr;
}
return val;
}
export function duplicateElement(element: ReturnType<typeof newElement>) {
const copy = _duplicateElement(element);
copy.id = nanoid();
copy.seed = randomSeed();
return copy;
}