@tolokoban/tgd
Version:
ToloGameDev library for WebGL2
256 lines • 27 kB
JavaScript
import { TgdDataset } from "./../../dataset/index.js";
import { TgdEvent } from "./../../event/index.js";
import { TgdProgram } from "./../../program/index.js";
import { TgdShaderFragment, TgdShaderVertex } from "./../../shader/index.js";
import { TgdVertexArray } from "./../../vao/index.js";
import { TgdPainter } from "../painter.js";
export class TgdPainterOverlay extends TgdPainter {
constructor(context, { alignX = +1, alignY = +1, scaleX = 1, scaleY = 1, width, height, margin = 0, z = 0, texture, } = {}) {
super();
this.context = context;
this.eventResize = new TgdEvent();
this.eventTap = new TgdEvent();
this.eventTapMultiple = new TgdEvent();
this.eventMoveStart = new TgdEvent();
this.eventMove = new TgdEvent();
this.eventHover = new TgdEvent();
this.eventMoveEnd = new TgdEvent();
this.eventZoom = new TgdEvent();
this.lastWidth = 0;
this.lastHeight = 0;
this.handleZoom = (evtScreen) => {
const x = this.xScreenToLayout(evtScreen.current.x);
const y = this.yScreenToLayout(evtScreen.current.y);
if (Math.abs(x) > 1 || Math.abs(y) > 1)
return;
const evtOverlay = { ...evtScreen, x, y };
this.eventZoom.dispatch(evtOverlay);
};
this.handleTap = (evtScreen) => {
const x = this.xScreenToLayout(evtScreen.x);
const y = this.yScreenToLayout(evtScreen.y);
if (Math.abs(x) > 1 || Math.abs(y) > 1)
return;
const evtOverlay = { ...evtScreen, x, y };
this.eventTap.dispatch(evtOverlay);
};
this.handleTapMultiple = (evtScreen) => {
const x = this.xScreenToLayout(evtScreen.x);
const y = this.yScreenToLayout(evtScreen.y);
if (Math.abs(x) > 1 || Math.abs(y) > 1)
return;
const evtOverlay = {
...evtScreen,
x,
y,
};
this.eventTapMultiple.dispatch(evtOverlay);
};
this.handleHover = (evtScreen) => {
const x = this.xScreenToLayout(evtScreen.current.x);
const y = this.yScreenToLayout(evtScreen.current.y);
if (Math.abs(x) > 1 || Math.abs(y) > 1)
return;
const evtOverlay = structuredClone(evtScreen);
evtOverlay.current.x = x;
evtOverlay.current.y = y;
return this.eventHover.dispatch(evtOverlay);
};
this.handleMove = (evtScreen) => {
const x = this.xScreenToLayout(evtScreen.current.x);
const y = this.yScreenToLayout(evtScreen.current.y);
if (Math.abs(x) > 1 || Math.abs(y) > 1)
return;
const evtOverlay = structuredClone(evtScreen);
evtOverlay.current.x = x;
evtOverlay.current.y = y;
return this.eventMove.dispatch(evtOverlay);
};
this.handleMoveStart = (evtScreen) => {
const x = this.xScreenToLayout(evtScreen.current.x);
const y = this.yScreenToLayout(evtScreen.current.y);
if (Math.abs(x) > 1 || Math.abs(y) > 1)
return;
const evtOverlay = structuredClone(evtScreen);
evtOverlay.current.x = x;
evtOverlay.current.y = y;
return this.eventMoveStart.dispatch(evtOverlay);
};
this.handleMoveEnd = (evtScreen) => {
const x = this.xScreenToLayout(evtScreen.current.x);
const y = this.yScreenToLayout(evtScreen.current.y);
if (Math.abs(x) > 1 || Math.abs(y) > 1)
return;
const evtOverlay = structuredClone(evtScreen);
evtOverlay.current.x = x;
evtOverlay.current.y = y;
return this.eventMoveEnd.dispatch(evtOverlay);
};
this.xScreenToLayout = (xScreen) => {
const { context, alignX, marginLeft, marginRight } = this;
const marginPx = marginLeft + marginRight;
const widthPx = this.width ?? context.width - marginPx;
const frameWidthPx = context.width - widthPx - marginPx;
const screenPerPixel = 2 / context.width;
const center = marginLeft + (widthPx + (1 + alignX) * frameWidthPx - context.width) / 2;
const factor = context.width / widthPx;
return (xScreen - center * screenPerPixel) * factor;
};
this.xLayoutToScreen = (xLayout) => {
const { context, alignX, marginLeft, marginRight } = this;
const marginPx = marginLeft + marginRight;
const widthPx = this.width ?? context.width - marginPx;
const frameWidthPx = context.width - widthPx - marginPx;
const screenPerPixel = 2 / context.width;
const center = marginLeft + (widthPx + (1 + alignX) * frameWidthPx - context.width) / 2;
const factor = widthPx / context.width;
return xLayout * factor + center * screenPerPixel;
};
this.yScreenToLayout = (yScreen) => {
const { context, alignY, marginTop, marginBottom } = this;
const marginPx = marginTop + marginBottom;
const heightPx = this.height ?? context.height - marginPx;
const frameHeightPx = context.height - heightPx - marginPx;
const screenPerPixel = 2 / context.height;
const center = marginBottom + (heightPx + (1 + alignY) * frameHeightPx - context.height) / 2;
const factor = context.height / heightPx;
return (yScreen - center * screenPerPixel) * factor;
};
this.yLayoutToScreen = (yLayout) => {
const { context, alignY, marginTop, marginBottom } = this;
const marginPx = marginTop + marginBottom;
const heightPx = this.height ?? context.height - marginPx;
const frameHeightPx = context.height - heightPx - marginPx;
const screenPerPixel = 2 / context.height;
const center = marginBottom + (heightPx + (1 + alignY) * frameHeightPx - context.height) / 2;
const factor = heightPx / context.height;
return yLayout * factor + center * screenPerPixel;
};
this.name = `Overlay/${this.name}`;
this.alignX = alignX;
this.alignY = alignY;
this.scaleX = scaleX;
this.scaleY = scaleY;
this.width = width;
this.height = height;
if (typeof margin === "number") {
this.marginTop = margin;
this.marginRight = margin;
this.marginBottom = margin;
this.marginLeft = margin;
}
else if (margin.length === 2) {
const [vertical, horizontal] = margin;
this.marginTop = vertical;
this.marginRight = horizontal;
this.marginBottom = vertical;
this.marginLeft = horizontal;
}
else {
const [top, right, bottom, left] = margin;
this.marginTop = top;
this.marginRight = right;
this.marginBottom = bottom;
this.marginLeft = left;
}
this.z = z;
this.texture = texture;
const dataset = new TgdDataset({
attPos: "vec2",
attUV: "vec2",
});
dataset.set("attPos", new Float32Array([+1, -1, +1, +1, -1, -1, -1, +1]));
dataset.set("attUV", new Float32Array([1, 1, 1, 0, 0, 1, 0, 0]));
const prg = new TgdProgram(context.gl, {
vert: new TgdShaderVertex({
uniforms: {
uniCenter: "vec2",
uniScale: "vec2",
uniScaleUV: "vec2",
uniZ: "float",
},
varying: {
varUV: "vec2",
},
attributes: {
attPos: "vec2",
attUV: "vec2",
},
mainCode: [
"varUV = (attUV - vec2(.5)) * uniScaleUV + vec2(.5);",
"gl_Position = vec4(attPos * uniScale + uniCenter, uniZ, 1);",
],
}).code,
frag: new TgdShaderFragment({
uniforms: {
uniTexture: "sampler2D",
},
varying: {
varUV: "vec2",
},
mainCode: ["FragColor = texture(uniTexture, varUV);"],
}).code,
});
const vao = new TgdVertexArray(context.gl, prg, [dataset]);
this.prg = prg;
this.vao = vao;
const { pointer } = context.inputs;
pointer.eventTap.addListener(this.handleTap, 1);
pointer.eventTapMultiple.addListener(this.handleTapMultiple, 1);
pointer.eventMoveStart.addListener(this.handleMoveStart, 1);
pointer.eventMove.addListener(this.handleMove, 1);
pointer.eventHover.addListener(this.handleHover, 1);
pointer.eventMoveEnd.addListener(this.handleMoveEnd, 1);
pointer.eventZoom.addListener(this.handleZoom, 1);
}
delete() {
const { context } = this;
if (context) {
const { pointer } = context.inputs;
pointer.eventTap.removeListener(this.handleTap);
pointer.eventTapMultiple.removeListener(this.handleTapMultiple);
pointer.eventMoveStart.removeListener(this.handleMoveStart);
pointer.eventMove.removeListener(this.handleMove);
pointer.eventHover.removeListener(this.handleHover);
pointer.eventMoveEnd.removeListener(this.handleMoveEnd);
pointer.eventZoom.removeListener(this.handleZoom);
}
this.prg.delete();
this.vao.delete();
}
paint(time, delta) {
this.checkForResizeEvent();
const { context, prg, vao, z, scaleX, scaleY, xLayoutToScreen, yLayoutToScreen, texture } = this;
const { gl } = context;
prg.use();
prg.uniform1f("uniZ", z);
const x0 = xLayoutToScreen(0);
const y0 = yLayoutToScreen(0);
prg.uniform2f("uniCenter", x0, y0);
const x1 = xLayoutToScreen(1);
const y1 = yLayoutToScreen(1);
prg.uniform2f("uniScale", x1 - x0, y1 - y0);
prg.uniform2f("uniScaleUV", scaleX, scaleY);
if (!texture) {
throw new Error("[TgdPainterOverlay] texture has not been set!");
}
texture.activate(0, prg, "uniTexture");
vao.bind();
const cull = context.webglParams.cullFace;
context.webglParams.cullFace = false;
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
context.webglParams.cullFace = cull;
vao.unbind();
}
checkForResizeEvent() {
const { context, lastWidth, lastHeight, marginLeft, marginRight, marginTop, marginBottom } = this;
const width = Math.max(0, this.width ?? context.width - marginLeft - marginRight);
const height = Math.max(0, this.height ?? context.height - marginTop - marginBottom);
if (width !== lastWidth || height !== lastHeight) {
this.lastWidth = width;
this.lastHeight = height;
this.eventResize.dispatch({ width, height });
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3ZlcmxheS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9wYWludGVyL292ZXJsYXkvb3ZlcmxheS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sY0FBYyxDQUFBO0FBQ3pDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFPckMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGNBQWMsQ0FBQTtBQUN6QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsZUFBZSxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBRWhFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxVQUFVLENBQUE7QUFDekMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQXVDdkMsTUFBTSxPQUFPLGlCQUFrQixTQUFRLFVBQVU7SUE0QjdDLFlBQ29CLE9BQW1CLEVBQ25DLEVBQ0ksTUFBTSxHQUFHLENBQUMsQ0FBQyxFQUNYLE1BQU0sR0FBRyxDQUFDLENBQUMsRUFDWCxNQUFNLEdBQUcsQ0FBQyxFQUNWLE1BQU0sR0FBRyxDQUFDLEVBQ1YsS0FBSyxFQUNMLE1BQU0sRUFDTixNQUFNLEdBQUcsQ0FBQyxFQUNWLENBQUMsR0FBRyxDQUFDLEVBQ0wsT0FBTyxNQUM0QixFQUFFO1FBRXpDLEtBQUssRUFBRSxDQUFBO1FBYlMsWUFBTyxHQUFQLE9BQU8sQ0FBWTtRQTVCdkIsZ0JBQVcsR0FBRyxJQUFJLFFBQVEsRUFBcUMsQ0FBQTtRQUMvRCxhQUFRLEdBQUcsSUFBSSxRQUFRLEVBQXFDLENBQUE7UUFDNUQscUJBQWdCLEdBQUcsSUFBSSxRQUFRLEVBQTZDLENBQUE7UUFDNUUsbUJBQWMsR0FBRyxJQUFJLFFBQVEsRUFBc0MsQ0FBQTtRQUNuRSxjQUFTLEdBQUcsSUFBSSxRQUFRLEVBQXNDLENBQUE7UUFDOUQsZUFBVSxHQUFHLElBQUksUUFBUSxFQUFzQyxDQUFBO1FBQy9ELGlCQUFZLEdB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