From fb0a4f884ed1ea89636e5b6e43ea9be0b5af7f97 Mon Sep 17 00:00:00 2001 From: LLLL Colonq Date: Fri, 20 Feb 2026 22:25:14 -0500 Subject: Update --- assets/charsheet/charsheet.js | 337 ++++++++++++++++++++++++++++-------------- 1 file changed, 223 insertions(+), 114 deletions(-) (limited to 'assets/charsheet/charsheet.js') diff --git a/assets/charsheet/charsheet.js b/assets/charsheet/charsheet.js index d477a68..61d48b0 100644 --- a/assets/charsheet/charsheet.js +++ b/assets/charsheet/charsheet.js @@ -1,12 +1,14 @@ -var GL = null; -var VERTS = null; -var IDXS = null; -var ATTRIB_VERTEX = null; -var ATTRIB_TEXCOORD = null; -var UNIFORM_PROJECTION = null; -var UNIFORM_VIEW = null; -var UNIFORM_POSITION = null; -var CUBE_ROTATION = 0.0; +let GL = null; +let VERTS = null; +let IDXS = null; +let ATTRIB_VERTEX = null; +let ATTRIB_TEXCOORD = null; +let UNIFORM_PROJECTION = null; +let UNIFORM_VIEW = null; +let UNIFORM_POSITION = null; +let CUBE_ROTATION = 0.0; +let TALENTS = {}; +let TALENT_SELECTED = null; function showContents() { let elem = document.getElementById("contents"); @@ -24,7 +26,7 @@ function showContents() { } } -function showError() { +function showError(msg) { let elem = document.getElementById("error"); if (elem) { elem.classList.remove("invisible"); @@ -38,6 +40,8 @@ function showError() { timeout += 200; } } + let em = document.getElementById("error-message"); + if (em) { em.innerText = msg; } } function scaleName() { @@ -59,81 +63,87 @@ function setName(nm) { } function uploadCube(gl) { - const verts = GL.createBuffer(); - GL.bindBuffer(GL.ARRAY_BUFFER, verts); - const vertdata = [ - // front - -0.5, -0.5, -0.5, 0, 0, - +0.5, -0.5, -0.5, 1.0, 0, - +0.5, +0.5, -0.5, 1.0, 1.0, - -0.5, +0.5, -0.5, 0, 1.0, - // right - +0.5, -0.5, -0.5, 0, 0, - +0.5, -0.5, +0.5, 1.0, 0, - +0.5, +0.5, +0.5, 1.0, 1.0, - +0.5, +0.5, -0.5, 0, 1.0, - // left - -0.5, -0.5, +0.5, 0, 0, - -0.5, -0.5, -0.5, 1.0, 0, - -0.5, +0.5, -0.5, 1.0, 1.0, - -0.5, +0.5, +0.5, 0, 1.0, - // top - -0.5, -0.5, +0.5, 0, 0, - +0.5, -0.5, +0.5, 1.0, 0, - +0.5, -0.5, -0.5, 1.0, 1.0, - -0.5, -0.5, -0.5, 0, 1.0, - // bottom - -0.5, +0.5, -0.5, 0, 0, - +0.5, +0.5, -0.5, 1.0, 0, - +0.5, +0.5, +0.5, 1.0, 1.0, - -0.5, +0.5, +0.5, 0, 1.0, - // back - +0.5, -0.5, +0.5, 0, 0, - -0.5, -0.5, +0.5, 1.0, 0, - -0.5, +0.5, +0.5, 1.0, 1.0, - +0.5, +0.5, +0.5, 0, 1.0 - ]; - GL.bufferData(GL.ARRAY_BUFFER, new Float32Array(vertdata), GL.STATIC_DRAW); - const quadidx = (p0, p1, p2, p3) => [p0, p1, p2, p2, p3, p0]; - const idxs = GL.createBuffer(); - GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, idxs); - const idxdata = [ - quadidx(0, 1, 2, 3), // front - quadidx(4, 5, 6, 7), // right - quadidx(8, 9, 10, 11), // left - quadidx(12, 13, 14, 15), // top - quadidx(16, 17, 18, 19), // bottom - quadidx(20, 21, 22, 23) // back - ].flat(); - GL.bufferData(GL.ELEMENT_ARRAY_BUFFER, new Uint16Array(idxdata), GL.STATIC_DRAW); - return { verts: verts, idxs: idxs }; + if (GL) { + const verts = GL.createBuffer(); + GL.bindBuffer(GL.ARRAY_BUFFER, verts); + const vertdata = [ + // front + -0.5, -0.5, -0.5, 0, 0, + +0.5, -0.5, -0.5, 1.0, 0, + +0.5, +0.5, -0.5, 1.0, 1.0, + -0.5, +0.5, -0.5, 0, 1.0, + // right + +0.5, -0.5, -0.5, 0, 0, + +0.5, -0.5, +0.5, 1.0, 0, + +0.5, +0.5, +0.5, 1.0, 1.0, + +0.5, +0.5, -0.5, 0, 1.0, + // left + -0.5, -0.5, +0.5, 0, 0, + -0.5, -0.5, -0.5, 1.0, 0, + -0.5, +0.5, -0.5, 1.0, 1.0, + -0.5, +0.5, +0.5, 0, 1.0, + // top + -0.5, -0.5, +0.5, 0, 0, + +0.5, -0.5, +0.5, 1.0, 0, + +0.5, -0.5, -0.5, 1.0, 1.0, + -0.5, -0.5, -0.5, 0, 1.0, + // bottom + -0.5, +0.5, -0.5, 0, 0, + +0.5, +0.5, -0.5, 1.0, 0, + +0.5, +0.5, +0.5, 1.0, 1.0, + -0.5, +0.5, +0.5, 0, 1.0, + // back + +0.5, -0.5, +0.5, 0, 0, + -0.5, -0.5, +0.5, 1.0, 0, + -0.5, +0.5, +0.5, 1.0, 1.0, + +0.5, +0.5, +0.5, 0, 1.0 + ]; + GL.bufferData(GL.ARRAY_BUFFER, new Float32Array(vertdata), GL.STATIC_DRAW); + const quadidx = (p0, p1, p2, p3) => [p0, p1, p2, p2, p3, p0]; + const idxs = GL.createBuffer(); + GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, idxs); + const idxdata = [ + quadidx(0, 1, 2, 3), // front + quadidx(4, 5, 6, 7), // right + quadidx(8, 9, 10, 11), // left + quadidx(12, 13, 14, 15), // top + quadidx(16, 17, 18, 19), // bottom + quadidx(20, 21, 22, 23) // back + ].flat(); + GL.bufferData(GL.ELEMENT_ARRAY_BUFFER, new Uint16Array(idxdata), GL.STATIC_DRAW); + return { verts: verts, idxs: idxs }; + } } function uploadShader(type, source) { - const shader = GL.createShader(type); - GL.shaderSource(shader, source); - GL.compileShader(shader); - if (!GL.getShaderParameter(shader, GL.COMPILE_STATUS)) { - alert(`shader compilation error: ${GL.getShaderInfoLog(shader)}`); - GL.deleteShader(shader); - return null; + if (GL) { + const shader = GL.createShader(type); + GL.shaderSource(shader, source); + GL.compileShader(shader); + if (!GL.getShaderParameter(shader, GL.COMPILE_STATUS)) { + alert(`shader compilation error: ${GL.getShaderInfoLog(shader)}`); + GL.deleteShader(shader); + return null; + } + return shader; } - return shader; } function uploadImage(url) { - const tex = GL.createTexture(); - GL.bindTexture(GL.TEXTURE_2D, tex); - GL.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, 1, 1, 0, GL.RGBA, GL.UNSIGNED_BYTE, new Uint8Array([0, 0, 0, 1.0])); - const img = new Image(); - img.onload = () => { + if (GL) { + const tex = GL.createTexture(); GL.bindTexture(GL.TEXTURE_2D, tex); - GL.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, img); - GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST); - GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.NEAREST); - GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE); - GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE); - }; - img.src = url; - return tex; + GL.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, 1, 1, 0, GL.RGBA, GL.UNSIGNED_BYTE, new Uint8Array([0, 0, 0, 1.0])); + const img = new Image(); + img.onload = () => { + GL.bindTexture(GL.TEXTURE_2D, tex); + GL.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, img); + GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST); + GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.NEAREST); + GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE); + GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE); + }; + img.src = url; + return tex; + } } function initGL() { @@ -189,27 +199,29 @@ function initGL() { } function render() { - CUBE_ROTATION += 0.01; - CUBE_ROTATION %= 2.0 * Math.PI; - const projection = mat4.create(); - mat4.perspective(projection, Math.PI / 4.0, GL.canvas.clientWidth / GL.canvas.clientHeight, 0.1, 100.0); - const view = mat4.create(); - mat4.lookAt(view, [0.0, 0.0, -5.0], [0.0, 0.0, 0.0], [0.0, 1.0, 0.0]); - const position = mat4.create(); - mat4.rotateX(position, position, Math.PI / 4.0); - mat4.rotateY(position, position, CUBE_ROTATION); - mat4.rotateZ(position, position, CUBE_ROTATION); - GL.bindBuffer(GL.ARRAY_BUFFER, VERTS); - GL.vertexAttribPointer(ATTRIB_VERTEX, 3, GL.FLOAT, false, 20, 0); - GL.enableVertexAttribArray(ATTRIB_VERTEX); - GL.vertexAttribPointer(ATTRIB_TEXCOORD, 2, GL.FLOAT, false, 20, 12); - GL.enableVertexAttribArray(ATTRIB_TEXCOORD); - GL.uniformMatrix4fv(UNIFORM_PROJECTION, false, projection); - GL.uniformMatrix4fv(UNIFORM_VIEW, false, view); - GL.uniformMatrix4fv(UNIFORM_POSITION, false, position); - GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, IDXS); - GL.drawElements(GL.TRIANGLES, 36, GL.UNSIGNED_SHORT, 0); - requestAnimationFrame(render); + if (GL) { + CUBE_ROTATION += 0.01; + CUBE_ROTATION %= 2.0 * Math.PI; + const projection = mat4.create(); + mat4.perspective(projection, Math.PI / 4.0, GL.canvas.clientWidth / GL.canvas.clientHeight, 0.1, 100.0); + const view = mat4.create(); + mat4.lookAt(view, [0.0, 0.0, -5.0], [0.0, 0.0, 0.0], [0.0, 1.0, 0.0]); + const position = mat4.create(); + mat4.rotateX(position, position, Math.PI / 4.0); + mat4.rotateY(position, position, CUBE_ROTATION); + mat4.rotateZ(position, position, CUBE_ROTATION); + GL.bindBuffer(GL.ARRAY_BUFFER, VERTS); + GL.vertexAttribPointer(ATTRIB_VERTEX, 3, GL.FLOAT, false, 20, 0); + GL.enableVertexAttribArray(ATTRIB_VERTEX); + GL.vertexAttribPointer(ATTRIB_TEXCOORD, 2, GL.FLOAT, false, 20, 12); + GL.enableVertexAttribArray(ATTRIB_TEXCOORD); + GL.uniformMatrix4fv(UNIFORM_PROJECTION, false, projection); + GL.uniformMatrix4fv(UNIFORM_VIEW, false, view); + GL.uniformMatrix4fv(UNIFORM_POSITION, false, position); + GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, IDXS); + GL.drawElements(GL.TRIANGLES, 36, GL.UNSIGNED_SHORT, 0); + requestAnimationFrame(render); + } } function setField(nm, v) { @@ -219,21 +231,118 @@ function setField(nm, v) { } } -initGL(); +async function displayUser(uid) { + initGL(); + const resp = await fetch(`${globalThis.apiServer}/user/info/${uid}`); + if (!resp.ok) { + showError("user not found"); + } else { + uploadImage(`${globalThis.apiServer}/user/avatar/${uid}.png`); + const info = await resp.json() + setName(info.properties["name"]); + for (let nm in info.stats) { + setField(nm, info.stats[nm]); + } + for (let nm in info.properties) { + setField(nm, info.properties[nm]); + } + showContents(); + } +} + +globalThis.mainPublic = async () => { + const uid = location.hash.slice(1); + displayUser(uid); +} + +async function getAuthedUser() { + const resp = await fetch(`${globalThis.secureApiServer}/info`); + const s = await resp.text(); + const [_nm, uid] = s.split(" "); + return uid; +} + +function showContentsSecure() { + let elem = document.getElementById("edit-contents"); + if (elem) { + let timeout = 500; + for (let c of elem.children) { + if (!c.dataset.skipfade) { + setTimeout( + () => c.classList.add("opaque"), + timeout + ); + timeout += 200; + } + } + } +} + +async function fetchTalents() { + const resp = await fetch(`${globalThis.apiServer}/talents`); + return await resp.json(); +} + +async function renderTalent(tid, x, y) { + const p = document.getElementById("edit-talentarea"); + const elem = document.createElement("div"); + elem.id = `edit-talent-${tid}`; + elem.dataset.tid = tid; + elem.classList.add("edit-talent"); + elem.style = `top: ${y}px; left: ${x}px;`; + elem.addEventListener("click", () => selectTalent(elem)); + const img = document.createElement("img"); + img.src = `${globalThis.apiServer}/talent/icon/${tid}.png`; + elem.appendChild(img); + p.appendChild(elem); +} -const uid = location.hash.slice(1); -const resp = await fetch(`${globalThis.apiServer}/user/info/${uid}`); -if (!resp.ok) { - showError(); -} else { - uploadImage(`${globalThis.apiServer}/user/avatar/${uid}.png`); - const info = await resp.json() - setName(info.properties["name"]); - for (let nm in info.stats) { - setField(nm, info.stats[nm]); +function selectTalent(elem) { + const p = document.getElementById("edit-talentarea"); + for (let c of p.children) { + c.classList.remove("edit-talent-selected"); + } + if (elem.dataset.tid == TALENT_SELECTED) { + TALENT_SELECTED = null; + const box = document.getElementById("edit-selected-tooltip-box"); + box.classList.remove("opaque"); + } else { + elem.classList.add("edit-talent-selected"); + TALENT_SELECTED = elem.dataset.tid; + const box = document.getElementById("edit-selected-tooltip-box"); + box.classList.add("opaque"); + const name = document.getElementById("edit-selected-tooltip-name"); + name.innerText = TALENTS[TALENT_SELECTED].name; + const tooltip = document.getElementById("edit-selected-tooltip"); + tooltip.innerText = TALENTS[TALENT_SELECTED].desc; } - for (let nm in info.properties) { - setField(nm, info.properties[nm]); +} + +async function displayUserSecure(uid) { + const resp = await fetch(`${globalThis.apiServer}/user/info/${uid}`); + if (!resp.ok) { + showError("user not found"); + } else { + const info = await resp.json() + setName(info.properties["name"]); + for (let nm in info.stats) { + setField(nm, info.stats[nm]); + } + for (let nm in info.properties) { + setField(nm, info.properties[nm]); + } + showContentsSecure(); } - showContents(); +} + +globalThis.mainSecure = async () => { + const scrollable = document.getElementById("edit-scrollable"); + const basex = window.innerWidth + window.innerWidth / 2 + 20; + const basey = window.innerHeight + 20; + scrollable.scroll(window.innerWidth, window.innerHeight); + const uid = await getAuthedUser(); + displayUserSecure(uid); + TALENTS = await fetchTalents(); + renderTalent("bigjoel", basex + 0, basey + 0); + renderTalent("shaderopacity", basex + 100, basey + 0); } -- cgit v1.2.3