UNPKG

@infinite-canvas-tutorial/webcomponents

Version:
211 lines 8.69 kB
"use strict"; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var _API_canvasEntity, _API_idEntityMap, _API_history, _API_store; Object.defineProperty(exports, "__esModule", { value: true }); exports.API = exports.pendingCanvases = void 0; const ecs_1 = require("@infinite-canvas-tutorial/ecs"); const event_1 = require("./event"); const components_1 = require("./components"); const history_1 = require("./history"); const context_1 = require("./context"); const utils_1 = require("./utils"); /** * Since the canvas is created in the system, we need to store them here for later use. */ exports.pendingCanvases = []; /** * Expose the API to the outside world. * * @see https://docs.excalidraw.com/docs/@excalidraw/excalidraw/api/props/excalidraw-api */ class API { constructor(element, commands) { this.element = element; this.commands = commands; _API_canvasEntity.set(this, void 0); _API_idEntityMap.set(this, void 0); _API_history.set(this, new history_1.History()); _API_store.set(this, new history_1.Store()); this.appState = (0, context_1.getDefaultAppState)(); __classPrivateFieldGet(this, _API_store, "f").onStoreIncrementEmitter.on(history_1.StoreIncrementEvent, (event) => { __classPrivateFieldGet(this, _API_history, "f").record(event.elementsChange, event.appStateChange); }); } /** * Create a new canvas. */ createCanvas(canvasProps) { const canvas = this.commands.spawn(new ecs_1.Canvas(canvasProps)).id(); canvas.add(components_1.Container, { element: this.element }); __classPrivateFieldSet(this, _API_canvasEntity, canvas.hold(), "f"); } /** * Create a new camera. */ createCamera(cameraProps) { const { zoom } = cameraProps; this.commands.spawn(new ecs_1.Camera({ canvas: __classPrivateFieldGet(this, _API_canvasEntity, "f"), }), new ecs_1.Transform({ scale: { x: 1 / zoom, y: 1 / zoom, }, })); } /** * Create a new landmark. */ createLandmark() { } /** * Go to a landmark. */ gotoLandmark() { } /** * ZoomLevel system will handle the zoom level. */ zoomTo(zoom) { this.element.dispatchEvent(new CustomEvent(event_1.Event.ZOOM_TO, { detail: { zoom, }, })); } resizeCanvas(width, height) { Object.assign(__classPrivateFieldGet(this, _API_canvasEntity, "f").write(ecs_1.Canvas), { width, height, }); this.element.dispatchEvent(new CustomEvent(event_1.Event.RESIZED, { detail: { width, height }, })); } setPen(pen) { Object.assign(__classPrivateFieldGet(this, _API_canvasEntity, "f").write(ecs_1.Canvas), { pen, }); const prevAppState = this.getAppState(); this.setAppState(Object.assign(Object.assign({}, prevAppState), { penbarSelected: [pen] })); this.element.dispatchEvent(new CustomEvent(event_1.Event.PEN_CHANGED, { detail: { selected: [pen] }, })); } setTaskbars(selected) { const prevAppState = this.getAppState(); this.setAppState(Object.assign(Object.assign({}, prevAppState), { taskbarSelected: selected })); this.element.dispatchEvent(new CustomEvent(event_1.Event.TASK_CHANGED, { detail: { selected }, })); } /** * @see https://docs.excalidraw.com/docs/@excalidraw/excalidraw/api/props/excalidraw-api#setcursor */ setCursor(cursor) { if (!__classPrivateFieldGet(this, _API_canvasEntity, "f").has(ecs_1.Cursor)) { __classPrivateFieldGet(this, _API_canvasEntity, "f").add(ecs_1.Cursor); } Object.assign(__classPrivateFieldGet(this, _API_canvasEntity, "f").write(ecs_1.Cursor), { value: cursor, }); } /** * Delete Canvas component */ destroy() { __classPrivateFieldGet(this, _API_canvasEntity, "f").delete(); this.element.dispatchEvent(new CustomEvent(event_1.Event.DESTROY)); } /** * Select nodes. */ selectNodes(selected, preserveSelection = false) { // TODO: select nodes in the canvas. const prevAppState = this.getAppState(); this.setAppState(Object.assign(Object.assign({}, prevAppState), { layersSelected: preserveSelection ? [...prevAppState.layersSelected, ...selected] : selected })); this.element.dispatchEvent(new CustomEvent(event_1.Event.SELECTED_NODES_CHANGED, { detail: { selected, preserveSelection }, })); } /** * If diff is provided, no need to calculate diffs. */ updateNode(node, diff) { const entity = __classPrivateFieldGet(this, _API_idEntityMap, "f").get(node.id).id(); let updated = node; if (diff) { const { name, visibility } = diff; if (name) { entity.write(ecs_1.Name).value = name; } if (visibility) { entity.write(ecs_1.Visibility).value = visibility; } updated = Object.assign(Object.assign({}, node), diff); } const nodes = this.getNodes(); const index = nodes.findIndex((n) => n.id === updated.id); if (index !== -1) { nodes[index] = updated; this.setNodes(nodes); } this.element.dispatchEvent(new CustomEvent(event_1.Event.NODE_UPDATED, { detail: { node: updated, }, })); } /** * Update the scene with new nodes. * It will calculate diffs and only update the changed nodes. * * @see https://docs.excalidraw.com/docs/@excalidraw/excalidraw/api/props/excalidraw-api#updatescene */ updateNodes(nodes) { this.nodes = nodes; const { cameras } = __classPrivateFieldGet(this, _API_canvasEntity, "f").read(ecs_1.Canvas); if (cameras.length === 0) { throw new Error('No camera found'); } // TODO: Support multiple cameras. const camera = cameras[0]; const cameraEntityCommands = this.commands.entity(camera); // TODO: Calculate diffs and only update the changed nodes. const { entities, idEntityMap } = (0, ecs_1.serializedNodesToEntities)(nodes, this.commands); __classPrivateFieldSet(this, _API_idEntityMap, idEntityMap, "f"); this.commands.execute(); entities.forEach((entity) => { // Append roots to the camera. if (!entity.has(ecs_1.Children)) { cameraEntityCommands.appendChild(this.commands.entity(entity)); } }); this.commands.execute(); this.setNodes(nodes); this.element.dispatchEvent(new CustomEvent(event_1.Event.NODES_UPDATED, { detail: { nodes, }, })); } undo() { __classPrivateFieldGet(this, _API_history, "f").undo((0, utils_1.arrayToMap)(this.getNodes()), this.getAppState(), __classPrivateFieldGet(this, _API_store, "f").snapshot); } redo() { __classPrivateFieldGet(this, _API_history, "f").redo((0, utils_1.arrayToMap)(this.getNodes()), this.getAppState(), __classPrivateFieldGet(this, _API_store, "f").snapshot); } } exports.API = API; _API_canvasEntity = new WeakMap(), _API_idEntityMap = new WeakMap(), _API_history = new WeakMap(), _API_store = new WeakMap(); //# sourceMappingURL=API.js.map