q5-react
Version:
> Minimal React wrapper for [q5.js](https://github.com/q5js/q5.js)
245 lines (244 loc) • 7.53 kB
JavaScript
import { jsx as b } from "react/jsx-runtime";
import { useState as q, useEffect as h, useRef as F, useMemo as w } from "react";
import v from "q5";
const g = [
[
"requestFullscreen",
"exitFullscreen",
"fullscreenElement",
"fullscreenEnabled",
"fullscreenchange",
"fullscreenerror"
],
// New WebKit
[
"webkitRequestFullscreen",
"webkitExitFullscreen",
"webkitFullscreenElement",
"webkitFullscreenEnabled",
"webkitfullscreenchange",
"webkitfullscreenerror"
],
// Old WebKit
[
"webkitRequestFullScreen",
"webkitCancelFullScreen",
"webkitCurrentFullScreenElement",
"webkitCancelFullScreen",
"webkitfullscreenchange",
"webkitfullscreenerror"
],
[
"mozRequestFullScreen",
"mozCancelFullScreen",
"mozFullScreenElement",
"mozFullScreenEnabled",
"mozfullscreenchange",
"mozfullscreenerror"
],
[
"msRequestFullscreen",
"msExitFullscreen",
"msFullscreenElement",
"msFullscreenEnabled",
"MSFullscreenChange",
"MSFullscreenError"
]
], d = (() => {
if (typeof document > "u")
return !1;
const e = g[0], t = {};
for (const n of g)
if ((n == null ? void 0 : n[1]) in document) {
for (const [l, u] of n.entries())
t[e[l]] = u;
return t;
}
return !1;
})(), E = {
change: d.fullscreenchange,
error: d.fullscreenerror
};
let f = {
// eslint-disable-next-line default-param-last
request(e = document.documentElement, t) {
return new Promise((n, o) => {
const l = () => {
f.off("change", l), n();
};
f.on("change", l);
const u = e[d.requestFullscreen](t);
u instanceof Promise && u.then(l).catch(o);
});
},
exit() {
return new Promise((e, t) => {
if (!f.isFullscreen) {
e();
return;
}
const n = () => {
f.off("change", n), e();
};
f.on("change", n);
const o = document[d.exitFullscreen]();
o instanceof Promise && o.then(n).catch(t);
});
},
toggle(e, t) {
return f.isFullscreen ? f.exit() : f.request(e, t);
},
onchange(e) {
f.on("change", e);
},
onerror(e) {
f.on("error", e);
},
on(e, t) {
const n = E[e];
n && document.addEventListener(n, t, !1);
},
off(e, t) {
const n = E[e];
n && document.removeEventListener(n, t, !1);
},
raw: d
};
Object.defineProperties(f, {
isFullscreen: {
get: () => !!document[d.fullscreenElement]
},
element: {
enumerable: !0,
get: () => document[d.fullscreenElement] ?? void 0
},
isEnabled: {
enumerable: !0,
// Coerce to boolean in case of old WebKit.
get: () => !!document[d.fullscreenEnabled]
}
});
d || (f = { isEnabled: !1 });
const S = f, x = ({ size: e }) => {
const [t, n] = q(e), o = () => {
S.toggle(), n((l) => l === "fullscreen" ? e : "fullscreen");
};
return h(() => {
n(e);
}, [e]), { sizeInternal: t, toggleFullscreen: o };
}, y = 500, k = ({ canvas: e, sizeInternal: t }) => {
const n = F(null), o = F(null), l = F(e == null ? void 0 : e.draw);
return h(() => {
l.current = e == null ? void 0 : e.draw;
}, [e]), h(() => {
if (o.current && (o.current.remove(), o.current = null), !n.current) return;
const u = setTimeout(() => {
if (o.current || !n.current) return;
const c = (s) => {
const m = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set();
s.setup = () => {
const r = t === "fullscreen" ? [s.windowWidth, s.windowHeight] : typeof t == "number" ? [t, t] : t;
s.createCanvas(
(r == null ? void 0 : r[0]) ?? y,
(r == null ? void 0 : r[1]) ?? y
);
}, s.draw = () => {
var r;
(r = l.current) == null || r.call(l, s, e.state, {
pressedKeys: m,
pressedMouseButtons: a
});
}, s.windowResized = () => {
t === "fullscreen" && s.resizeCanvas(s.windowWidth, s.windowHeight);
}, s.keyPressed = () => {
var r, i;
m.add(s.key), (i = (r = e == null ? void 0 : e.events) == null ? void 0 : r.keyPressed) == null || i.call(r, s.key);
}, s.keyReleased = () => {
var r, i;
m.delete(s.key), (i = (r = e == null ? void 0 : e.events) == null ? void 0 : r.keyReleased) == null || i.call(r, s.key);
}, s.mousePressed = () => {
var r, i;
a.add(s.mouseButton), (i = (r = e == null ? void 0 : e.events) == null ? void 0 : r.mousePressed) == null || i.call(r, s.mouseButton, {
x: s.mouseX,
y: s.mouseY
});
}, s.mouseReleased = () => {
var r, i;
a.delete(s.mouseButton), (i = (r = e == null ? void 0 : e.events) == null ? void 0 : r.mouseReleased) == null || i.call(r, s.mouseButton, {
x: s.mouseX,
y: s.mouseY
});
};
};
o.current = new v(c, n.current);
}, 0);
return () => {
clearTimeout(u), o.current && (o.current.remove(), o.current = null);
};
}, [n, t]), h(() => {
var s, m;
const u = (a) => a.preventDefault();
(s = n.current) == null || s.addEventListener("contextmenu", u);
const c = (m = n.current) == null ? void 0 : m.querySelector("canvas");
return c && c.addEventListener("contextmenu", u), () => {
var a, r, i;
(a = n.current) == null || a.removeEventListener(
"contextmenu",
u
), (i = (r = n.current) == null ? void 0 : r.querySelector("canvas")) == null || i.removeEventListener("contextmenu", u);
};
}, [n]), { sketchInstanceRef: o, containerRef: n };
}, N = ({
size: e = 500,
canvas: t,
children: n
}) => {
const { sizeInternal: o, toggleFullscreen: l } = x({ size: e }), { containerRef: u } = k({
canvas: t,
sizeInternal: o
});
return h(() => {
const c = document.createElement("style");
return c.textContent = ".q5-canvas-fullscreen{width:100vw;height:100vh;position:fixed;inset:0;z-index:100;overflow:hidden}.q5-canvas{position:relative}.q5-canvas canvas,.q5-canvas-fullscreen canvas{display:block}.q5-canvas .q5-canvas-overlay,.q5-canvas-fullscreen .q5-canvas-overlay{position:absolute;inset:0;z-index:101;pointer-events:none}.q5-canvas .q5-canvas-overlay *,.q5-canvas-fullscreen .q5-canvas-overlay *{pointer-events:initial}", document.head.appendChild(c), () => c.remove();
}, []), /* @__PURE__ */ b(
"div",
{
ref: u,
className: o === "fullscreen" ? "q5-canvas-fullscreen" : "q5-canvas",
children: n && /* @__PURE__ */ b("div", { className: "q5-canvas-overlay", children: typeof n == "function" ? n({ toggleFullscreen: l }) : n })
}
);
};
function C(e) {
let t = structuredClone(e);
const n = /* @__PURE__ */ new Set();
return { get: () => t, set: (c) => {
const s = typeof c == "function" ? c(t) : c;
t = { ...t, ...s }, n.forEach((m) => m(t));
}, subscribe: (c) => (n.add(c), () => n.delete(c)) };
}
const P = (e, t) => w(() => C(t), []);
function R(e) {
return typeof e == "function" && e.length === 0;
}
const _ = (e, t, n) => {
const o = w(() => crypto.randomUUID(), []), l = w(
() => R(e) ? e() : e,
[]
), u = P(o, l);
return w(
() => ({
draw: t,
state: u,
events: n
}),
[t, u, n]
);
}, j = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
__proto__: null
}, Symbol.toStringTag, { value: "Module" }));
export {
N as default,
j as types,
_ as useCreateCanvas
};