import { Pixmap } from "rkgk/haku.js"; export class BrushPreview extends HTMLElement { constructor(width, height) { super(); this.width = width; this.height = height; } connectedCallback() { this.canvas = this.appendChild(document.createElement("canvas")); this.ctx = this.canvas.getContext("2d"); this.#resizeCanvas(); if (this.width == null || this.height == null) { new ResizeObserver(() => this.#resizeCanvas()).observe(this); } } #resizeCanvas() { this.canvas.width = this.width ?? this.clientWidth; this.canvas.height = this.height ?? this.clientHeight; // This can happen if the element's `display: none`. if (this.canvas.width == 0 || this.canvas.height == 0) return; if (this.pixmap != null) { this.pixmap.destroy(); } this.pixmap = new Pixmap(this.canvas.width, this.canvas.height); this.dispatchEvent(new Event(".pixmapLost")); } async #renderBrushInner(haku) { this.pixmap.clear(); let evalResult = await haku.evalBrush({ runDotter: async () => { return { fromX: this.canvas.width / 2, fromY: this.canvas.height / 2, toX: this.canvas.width / 2, toY: this.canvas.height / 2, num: 0, }; }, runScribble: async (renderToPixmap) => { return renderToPixmap(this.pixmap, 0, 0); }, }); if (evalResult.status != "ok") { return { status: "error", phase: "eval", result: evalResult }; } this.ctx.putImageData(this.pixmap.getImageData(), 0, 0); return { status: "ok" }; } async renderBrush(haku) { this.unsetErrorFlag(); let result = await this.#renderBrushInner(haku); if (result.status == "error") { console.error(result); this.setErrorFlag(); } return result; } unsetErrorFlag() { this.classList.remove("error"); } setErrorFlag() { this.classList.add("error"); } } customElements.define("rkgk-brush-preview", BrushPreview);