js-draw
Version:
Draw pictures using a pen, touchscreen, or mouse! JS-draw is a drawing library for JavaScript and TypeScript.
112 lines (111 loc) • 4.01 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const AbstractComponent_1 = __importDefault(require("../components/AbstractComponent"));
const describeComponentList_1 = __importDefault(require("../components/util/describeComponentList"));
const EditorImage_1 = __importDefault(require("../image/EditorImage"));
const SerializableCommand_1 = __importDefault(require("./SerializableCommand"));
/**
* Removes the given {@link AbstractComponent}s from the image.
*
* **Example**:
* ```ts,runnable
* import { Editor, Erase, uniteCommands, Color4, Path, Stroke, Rect2, pathToRenderable } from 'js-draw';
*
* const editor = new Editor(document.body);
* editor.addToolbar();
*
* // Add a large number of strokes
* const commands = [];
* for (let x = -20; x < 20; x++) {
* for (let y = 0; y < 60; y++) {
* const stroke = new Stroke([
* pathToRenderable(
* Path.fromString(`m${x * 5},${y * 5}l1,1`),
* { fill: Color4.transparent, stroke: {width: 2, color: Color4.ofRGB(x / 10, y / 10, 0.5)}} )
* ]);
* commands.push(editor.image.addElement(stroke));
* }
* }
* await editor.dispatch(uniteCommands(commands, 100));
*
* ---visible---
* // Given some editor...
*
* // Find all elements intersecting the rectangle with top left (-10,-30) and
* // (width,height)=(50,100).
* const elems = editor.image.getComponentsIntersecting(
* new Rect2(-10, -30, 50, 100)
* );
*
* // Create a command that erases [elems] when applied
* const eraseElemsCmd = new Erase(elems);
*
* // Apply the command (and make it undoable)
* editor.dispatch(eraseElemsCmd);
* ```
*/
class Erase extends SerializableCommand_1.default {
constructor(toRemove) {
super('erase');
// Clone the list
this.toRemove = toRemove.map((elem) => elem);
this.applied = false;
}
apply(editor) {
for (const part of this.toRemove) {
const parent = editor.image.findParent(part);
if (parent) {
parent.remove();
editor.image.onDestroyElement(part);
}
}
this.applied = true;
editor.queueRerender();
}
unapply(editor) {
for (const part of this.toRemove) {
if (!editor.image.findParent(part)) {
EditorImage_1.default.addComponent(part).apply(editor);
}
}
this.applied = false;
editor.queueRerender();
}
onDrop(editor) {
if (this.applied) {
for (const part of this.toRemove) {
editor.image.onDestroyElement(part);
}
}
}
description(_editor, localizationTable) {
if (this.toRemove.length === 0) {
return localizationTable.erasedNoElements;
}
const description = (0, describeComponentList_1.default)(localizationTable, this.toRemove) ?? localizationTable.elements;
return localizationTable.eraseAction(description, this.toRemove.length);
}
serializeToJSON() {
// If applied, the elements can't be fetched from the image because they're
// erased. Serialize and return the elements themselves.
const elems = this.toRemove.map((elem) => elem.serialize());
return elems;
}
}
(() => {
SerializableCommand_1.default.register('erase', (json, editor) => {
if (!Array.isArray(json)) {
throw new Error('seralized erase data must be an array');
}
const elems = json.map((elemData) => {
const componentId = typeof elemData === 'string' ? elemData : `${elemData.id}`;
const component = editor.image.lookupElement(componentId) ?? AbstractComponent_1.default.deserialize(elemData);
return component;
});
return new Erase(elems);
});
})();
exports.default = Erase;
;