UNPKG

@thi.ng/rdom-canvas

Version:

@thi.ng/rdom component wrapper for @thi.ng/hiccup-canvas and declarative canvas drawing

70 lines (69 loc) 2.16 kB
import { adaptDPI } from "@thi.ng/canvas"; import { implementsFunction } from "@thi.ng/checks/implements-function"; import { isArray } from "@thi.ng/checks/is-array"; import { draw } from "@thi.ng/hiccup-canvas/draw"; import { withoutKeysObj } from "@thi.ng/object-utils/without-keys"; import { Component } from "@thi.ng/rdom/component"; import { __nextID } from "@thi.ng/rdom/idgen"; import { $subWithID } from "@thi.ng/rdom/sub"; import { isSubscribable } from "@thi.ng/rstream/checks"; import { reactive } from "@thi.ng/rstream/stream"; const $canvas = (body, size, attribs) => $subWithID(body, new $Canvas(size, attribs), __nextID("canvas", body)); class $Canvas extends Component { constructor(size, attribs = {}) { super(); this.attribs = attribs; this.size = isSubscribable(size) ? size : reactive(size); this.sizeSub = this.size.subscribe( { next: this.resize.bind(this) }, { id: __nextID("canvas-resize") } ); } ctx; inner; size; sizeSub; async mount(parent, index, shapes) { this.inner = this.$compile([ "canvas", withoutKeysObj(this.attribs, [ "onmount", "onunmount", "onresize", "ctx" ]) ]); this.el = await this.inner.mount(parent, index); this.ctx = this.el.getContext("2d", this.attribs.ctx); this.resize(this.size.deref() || [1, 1]); this.attribs.onmount?.(this.el, this.ctx); this.update(shapes); return this.el; } async unmount() { this.el && this.attribs.onunmount?.(this.el); await this.inner.unmount(); this.sizeSub.unsubscribe(); this.inner = void 0; this.el = void 0; this.ctx = void 0; } resize(size) { if (this.el) { adaptDPI(this.el, size[0], size[1], 1); this.attribs.onresize && this.attribs.onresize(this.el, this.ctx, size); } } update(tree) { if (tree == null) return; let shapes = implementsFunction(tree, "toHiccup") ? tree.toHiccup() : tree; if (!(isArray(shapes) && shapes[1]?.__dpr)) { shapes = ["g", { __dpr: window.devicePixelRatio ?? 1 }, shapes]; } draw(this.ctx, shapes); } } export { $Canvas, $canvas };