kaplay-plugin-text
Version:
KAPLAY plugin for styled text
98 lines (97 loc) • 3.4 kB
JavaScript
//#region src/plugin.ts
function e(e) {
return `rgb(${String(e.r)}, ${String(e.g)}, ${String(e.b)})`;
}
function t(e, t) {
return t || e._k?.globalOpt?.font || "monospace";
}
function n(n) {
return { styledText: (r = "", i = {}) => {
let a = r, o = { ...i }, s = null, c = null, l = null, u = 0, d = 0, f = 0, p = 0, m = 0, h = () => t(n, o.font), g = () => {
if (!s || !c) return;
let t = h(), r = o.size ?? 48, i = o.align ?? "left", g = o.lineSpacing ?? 0, v = o.outline?.width ?? 0, y = o.shadow?.offsetX ?? 0, b = o.shadow?.offsetY ?? 0, x = o.shadow?.blur ?? 0, S = Math.max(v, x) + Math.abs(y) + Math.abs(b) + 2;
m = S, c.font = `${String(r)}px ${t}`, c.textAlign = i, c.textBaseline = "top";
let C = o.width, w = _(c, a, C), T = r + g, E = 0;
for (let e of w) {
let t = c.measureText(e);
E = Math.max(E, t.width);
}
let D = Math.ceil(E + S * 2), O = Math.ceil(w.length * T + S * 2);
(s.width !== D || s.height !== O) && (s.width = D, s.height = O, c.font = `${String(r)}px ${t}`, c.textAlign = i, c.textBaseline = "top"), c.clearRect(0, 0, s.width, s.height);
for (let t = 0; t < w.length; t++) {
let n = w[t], r = S, i = S + t * T;
if (o.shadow && (c.shadowColor = e(o.shadow.color), c.shadowOffsetX = o.shadow.offsetX, c.shadowOffsetY = o.shadow.offsetY, c.shadowBlur = o.shadow.blur), o.outline && (c.strokeStyle = o.outline.color ? e(o.outline.color) : "black", c.lineWidth = o.outline.width ?? 1, c.lineJoin = "round", c.strokeText(n, r, i), c.shadowColor = "transparent", c.shadowOffsetX = 0, c.shadowOffsetY = 0, c.shadowBlur = 0), o.gradient) {
let t = o.gradient.direction === "vertical" ? c.createLinearGradient(0, S, 0, O - S) : c.createLinearGradient(S, 0, D - S, 0);
t.addColorStop(0, e(o.gradient.from)), t.addColorStop(1, e(o.gradient.to)), c.fillStyle = t;
} else o.fill ? c.fillStyle = e(o.fill) : c.fillStyle = "white";
c.fillText(n, r, i);
}
if (u = D, d = O, l && f === D && p === O) {
let e = l.frames[0], t = Math.round(e.x * l.tex.width), n = Math.round(e.y * l.tex.height);
l.tex.update(s, t, n);
} else l && l.tex.free(), l = n.SpriteData.fromImage(s, { singular: !0 }), f = D, p = O;
}, _ = (e, t, n) => {
if (!n) return t.split("\n");
let r = [];
for (let i of t.split("\n")) {
let t = i.split(" "), a = "";
for (let i of t) {
let t = a ? `${a} ${i}` : i;
e.measureText(t).width > n && a ? (r.push(a), a = i) : a = t;
}
r.push(a);
}
return r;
};
return {
id: "styledText",
get text() {
return a;
},
set text(e) {
a = e, g();
},
get width() {
return u;
},
get height() {
return d;
},
renderArea() {
return new n.Rect(n.vec2(0), u, d);
},
setStyle(e) {
o = {
...o,
...e
}, g();
},
add() {
s = document.createElement("canvas"), c = s.getContext("2d"), c && g();
},
draw() {
if (l) {
let e = this;
n.drawSprite({
sprite: l,
pos: n.vec2(-m, -m),
anchor: e.anchor,
color: e.color,
opacity: e.opacity,
outline: e.outline,
shader: e.shader,
uniform: e.uniform,
flipX: e.flipX,
flipY: e.flipY
});
}
},
destroy() {
l &&= (l.tex.free(), null), s = null, c = null;
}
};
} };
}
//#endregion
export { n as styledTextPlugin };
//# sourceMappingURL=plugin.mjs.map