summaryrefslogtreecommitdiff
path: root/assets
diff options
context:
space:
mode:
Diffstat (limited to 'assets')
-rw-r--r--assets/charsheet/charsheet.css85
-rw-r--r--assets/charsheet/charsheet.js337
2 files changed, 307 insertions, 115 deletions
diff --git a/assets/charsheet/charsheet.css b/assets/charsheet/charsheet.css
index ca2bcf7..c8116ce 100644
--- a/assets/charsheet/charsheet.css
+++ b/assets/charsheet/charsheet.css
@@ -108,7 +108,7 @@ body {
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(2, 1fr);
gap: 0.5rem;
- overflow: scroll;
+ overflow: auto;
}
.contents-anim-unfold {
animation-duration: 0.5s;
@@ -142,6 +142,12 @@ body {
margin: 0px;
font-size: 100rem;
}
+#login {
+ position: absolute;
+ z-index: 5;
+ color: black;
+ text-decoration: none;
+}
#visualization {
position: relative;
grid-column-end: span 2;
@@ -200,3 +206,80 @@ table {
table tr td:first-child {
font-weight: bold;
}
+
+#edit-mode {
+ position: absolute;
+ z-index: 5;
+}
+
+#edit-scrollable {
+ overflow: scroll;
+ width: 100vw;
+ height: 100vh;
+}
+#edit-talentarea {
+ position: relative;
+ left: 0px;
+ top: 0px;
+ width: 300vw;
+ height: 300vh;
+ background-color: white;
+ background-image: radial-gradient(lightgrey 1px, transparent 0);
+ background-size: 0.25rem 0.25rem;
+}
+.edit-talent {
+ position: absolute;
+ width: 64px;
+ height: 64px;
+ background-color: black;
+ border-radius: 2px;
+ margin-top: 8px;
+ margin-left: 8px;
+}
+.edit-talent:hover {
+ border: 4px solid lightgrey;
+ margin-top: 4px;
+ margin-left: 4px;
+}
+.edit-talent.edit-talent-selected {
+ border: 8px solid grey;
+ margin-top: 0px;
+ margin-left: 0px;
+}
+.edit-talent > img {
+ width: 64px;
+ height: 64px;
+ image-rendering: pixelated;
+}
+#edit-contents {
+ position: fixed;
+ left: 10vw;
+ top: 10vh;
+ width: 80vw;
+ height: 80vh;
+ display: grid;
+ grid-auto-columns: 0;
+ grid-auto-flow: row;
+ grid-template-columns: repeat(4, 1fr);
+ grid-template-rows: repeat(2, 1fr);
+ gap: 2rem;
+ overflow: hidden;
+ pointer-events: none;
+}
+#edit-contents > div {
+ border: 1px solid lightgrey;
+ background-color: white;
+ opacity: 0.0;
+ transition: opacity 2s;
+ pointer-events: auto;
+}
+#edit-infobox {
+ grid-column: 1;
+ grid-row: 2;
+}
+#edit-selected-tooltip-box {
+ grid-column: 2;
+ grid-row: 2;
+ transition: opacity 0.5s !important;
+ overflow: auto;
+}
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);
}