vue-konva
Version:
Vue binding to canvas element via Konva framework
243 lines (242 loc) • 6.4 kB
JavaScript
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
};