UNPKG

vue-konva

Version:

Vue binding to canvas element via Konva framework

243 lines (242 loc) 6.4 kB
import { defineComponent as S, getCurrentInstance as P, reactive as A, ref as h, onMounted as C, onUpdated as E, onBeforeUnmount as K, watch as N, h as T, onUnmounted as R, computed as I, toValue as y } from "vue"; import i from "konva"; function p(o) { if (!i.autoDrawEnabled) { const t = o.getLayer() || o.getStage(); t && t.batchDraw(); } } const w = { key: !0, style: !0, elm: !0, isRootInsert: !0 }, _ = ".vue-konva-event"; function L(o, t, a, c) { const e = o.__konvaNode, d = {}; let r = !1; for (let n in a) { if (w.hasOwnProperty(n)) continue; const u = n.slice(0, 2) === "on", f = a[n] !== t[n]; if (u && f) { let l = n.slice(2).toLowerCase(); l.slice(0, 7) === "content" && (l = "content" + l.slice(7, 1).toUpperCase() + l.slice(8)), e?.off(l + _, a[n]); } !t.hasOwnProperty(n) && e?.setAttr(n, void 0); } for (let n in t) { if (w.hasOwnProperty(n)) continue; let u = n.slice(0, 2) === "on"; const f = a[n] !== t[n]; if (u && f) { let s = n.slice(2).toLowerCase(); s.slice(0, 7) === "content" && (s = "content" + s.slice(7, 1).toUpperCase() + s.slice(8)), t[n] && (e?.off(s + _), e?.on(s + _, t[n])); } !u && (t[n] !== a[n] || c && t[n] !== e?.getAttr(n)) && (r = !0, d[n] = t[n]); } r && e && (e.setAttrs(d), p(e)); } const M = "v"; function U(o) { function t(a) { return a?.__konvaNode ? a : a?.parent ? t(a.parent) : (console.error("vue-konva error: Can not find parent node"), null); } return t(o.parent); } function b(o) { return o.component ? o.component.__konvaNode || b(o.component.subTree) : null; } function V(o) { const { el: t, component: a } = o, c = b(o); if (t?.tagName && a && !c) { const e = t.tagName.toLowerCase(); return console.error( `vue-konva error: You are trying to render "${e}" inside your component tree. Looks like it is not a Konva node. You can render only Konva components inside the Stage.` ), null; } return c; } function j(o) { const t = (e) => !!e?.hasOwnProperty("component"), a = (e) => Array.isArray(e), c = (e) => t(e) ? [e, ...c(e.children)] : a(e) ? e.flatMap(c) : []; return c(o.children); } function O(o, t) { const a = j(o), c = []; a.forEach((d) => { const r = V(d); r && c.push(r); }); let e = !1; c.forEach((d, r) => { d.getZIndex() !== r && (d.setZIndex(r), e = !0); }), e && p(t); } const F = S({ name: "Stage", props: { config: { type: Object, default: function() { return {}; } }, __useStrictMode: { type: Boolean } }, inheritAttrs: !1, setup(o, { attrs: t, slots: a, expose: c }) { const e = P(); if (!e) return; const d = A({}), r = h(null), n = new i.Stage({ width: o.config.width, height: o.config.height, container: document.createElement("div") // Fake container. Will be replaced }); e.__konvaNode = n, s(); function u() { return e?.__konvaNode; } function f() { return e?.__konvaNode; } function s() { if (!e) return; const l = d || {}, g = { ...t, ...o.config }; L(e, g, l, o.__useStrictMode), Object.assign(d, g); } return C(() => { r.value && (r.value.innerHTML = "", n.container(r.value)), s(); }), E(() => { s(), O(e.subTree, n); }), K(() => { n.destroy(); }), N(() => o.config, s, { deep: !0 }), c({ getStage: f, getNode: u }), () => T("div", { ref: r, style: t?.style }, a.default?.()); } }), G = ".vue-konva-event", $ = { Group: !0, Layer: !0, FastLayer: !0, Label: !0 }; function B(o, t) { return S({ name: o, props: { config: { type: Object, default: function() { return {}; } }, __useStrictMode: { type: Boolean } }, setup(a, { attrs: c, slots: e, expose: d }) { const r = P(); if (!r) return; const n = A({}), u = new t(); r.__konvaNode = u, r.vnode.__konvaNode = u, l(); function f() { return r?.__konvaNode; } function s() { return r?.__konvaNode; } function l() { if (!r) return; const v = {}; for (const m in r?.vnode.props) m.slice(0, 2) === "on" && (v[m] = r.vnode.props[m]); const x = n || {}, k = { ...c, ...a.config, ...v }; L(r, k, x, a.__useStrictMode), Object.assign(n, k); } C(() => { const v = U(r)?.__konvaNode; v && "add" in v && v.add(u), p(u); }), R(() => { p(u), u.destroy(), u.off(G); }), E(() => { l(), O(r.subTree, u); }), N(() => a.config, l, { deep: !0 }), d({ getStage: s, getNode: f }); const g = $.hasOwnProperty(o); return () => g ? T("template", {}, e.default?.()) : null; } }); } function Y(o, t, a) { const c = h(null), e = h("loading"), d = (n, u, f) => { e.value = "loading"; const s = new Image(); u && (s.crossOrigin = u), f && (s.referrerPolicy = f), s.onload = () => { c.value = s, e.value = "loaded"; }, s.onerror = () => { c.value = null, e.value = "error"; }, s.src = n; }, r = I(() => ({ url: y(o), crossorigin: y(t), referrerPolicy: y(a) })); return N( r, ({ url: n, crossorigin: u, referrerPolicy: f }) => { n && d(n, u, f); }, { immediate: !0 } ), [c, e]; } typeof window < "u" && !window.Konva && require("konva"); const Z = { install: (o, t) => { const a = t?.prefix || M, c = { Arc: i.Arc, Arrow: i.Arrow, Circle: i.Circle, Ellipse: i.Ellipse, FastLayer: i.FastLayer, Group: i.Group, Image: i.Image, Label: i.Label, Layer: i.Layer, Line: i.Line, Path: i.Path, Rect: i.Rect, RegularPolygon: i.RegularPolygon, Ring: i.Ring, Shape: i.Shape, Sprite: i.Sprite, Star: i.Star, Tag: i.Tag, Text: i.Text, TextPath: i.TextPath, Transformer: i.Transformer, Wedge: i.Wedge, ...t?.customNodes }; [ F, ...Object.entries(c).map( ([d, r]) => B(d, r) ) ].forEach((d) => { o.component(`${a}${d.name}`, d); }); } }; export { Z as default, Y as useImage };