@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
JavaScript
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
};