UNPKG

@tolokoban/tgd

Version:

ToloGameDev library for WebGL2

256 lines 27 kB
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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