From 2ac360e84250f9bea401d2402f46c023274339ba Mon Sep 17 00:00:00 2001 From: RGBCube Date: Tue, 3 Jun 2025 23:31:28 +0300 Subject: [PATCH 1/5] css: fix link hover border removal --- site/assets/css/default.css | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/site/assets/css/default.css b/site/assets/css/default.css index 28ef8e4..9fafbf2 100644 --- a/site/assets/css/default.css +++ b/site/assets/css/default.css @@ -230,10 +230,9 @@ html, body { code:not(pre > code) { @apply border-1 border-dotted px-2 py-0.5 border-black dark:border-white; - &:not(a code) { - a:hover &, a:active & { - @apply border-transparent; - } + a:hover &:not(:is(h1, h2, h3, h4, h5, h6) *), + a:active &:not(:is(h1, h2, h3, h4, h5, h6) *) { + @apply border-transparent; } } From b13bff471fb333d9dbaee238ee6ac4b8afb75efe Mon Sep 17 00:00:00 2001 From: RGBCube Date: Tue, 3 Jun 2025 23:41:43 +0300 Subject: [PATCH 2/5] blog: make test post a draft --- site/blog/{a.md => test.md} | 1 + 1 file changed, 1 insertion(+) rename site/blog/{a.md => test.md} (99%) diff --git a/site/blog/a.md b/site/blog/test.md similarity index 99% rename from site/blog/a.md rename to site/blog/test.md index a744cd4..a2d599b 100644 --- a/site/blog/a.md +++ b/site/blog/test.md @@ -2,6 +2,7 @@ date: 2024-01-01 title: Test description: "Testing" +draft: true --- # Test From a6f7c93d62426db91edf376d94bfc146b365f4a9 Mon Sep 17 00:00:00 2001 From: RGBCube Date: Wed, 4 Jun 2025 01:50:47 +0300 Subject: [PATCH 3/5] cube: preserve state across pages --- .gitignore | 2 +- site/_includes/cube.vto | 61 +++++++++++++++++++++++++++++++++++------ site/_includes/text.vto | 4 +-- site/blog.vto | 6 ++-- 4 files changed, 59 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index 05eef16..8078087 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ !.gitignore !site/ -!site/**/ +!site/**/ !*.nu diff --git a/site/_includes/cube.vto b/site/_includes/cube.vto index d88bc3d..7e9346c 100644 --- a/site/_includes/cube.vto +++ b/site/_includes/cube.vto @@ -120,16 +120,28 @@ // 15 seconds. const screensaverTimeoutMs = 15 * 1000; + // 10 minutes. + const stateDeleteTimeoutMs = 10 * 60 * 1000; + + const lastSave = JSON.parse(localStorage.getItem("lastSave")); + if (!lastSave || Date.now() - lastSave > stateDeleteTimeoutMs) { + localStorage.removeItem("mouseDown"); + localStorage.removeItem("mouseLastMove"); + localStorage.removeItem("mousePrevious"); + localStorage.removeItem("cubeOrient"); + localStorage.removeItem("velocity"); + localStorage.removeItem("impulseThisFrame"); + } const mouse = { - down: false, - lastMove: -screensaverTimeoutMs, - previous: Vec.ZERO, - }; + down: JSON.parse(localStorage.getItem("mouseDown")) ?? false, + lastMove: JSON.parse(localStorage.getItem("mouseLastMove")) ?? -screensaverTimeoutMs, + previous: Vec(...JSON.parse(localStorage.getItem("mousePrevious")) ?? [0, 0, 0, 1]), + }; const orient = { elements: document.querySelectorAll("cube-itself"), - quat: Quat(0, 0, 0, 1), + quat: Quat(...JSON.parse(localStorage.getItem("cubeOrient")) ?? [0, 0, 0, 1]), set(q) { this.quat = q; @@ -145,9 +157,41 @@ }, }; - let velocity = Vec.ZERO; - let impulseThisFrame = Vec.ZERO; - let impulseIdle = Vec(2, 2, -2); + let velocity = Vec(...JSON.parse(localStorage.getItem("velocity")) ?? [0, 0, 0]); + + let impulseThisFrame = Vec(...JSON.parse(localStorage.getItem("impulseThisFrame")) ?? [0, 0, 0]); + + window.addEventListener("beforeunload", () => { + localStorage.setItem("mouseDown", JSON.stringify(mouse.down)); + localStorage.setItem("mouseLastMove", JSON.stringify(-(window.performance.now() - mouse.lastMove))); + localStorage.setItem("mousePrevious", JSON.stringify([ + mouse.previous.x, + mouse.previous.y, + mouse.previous.z, + mouse.previous.w, + ])); + + localStorage.setItem("cubeOrient", JSON.stringify([ + orient.quat.x, + orient.quat.y, + orient.quat.z, + orient.quat.w, + ])); + + localStorage.setItem("velocity", JSON.stringify([ + velocity.x, + velocity.y, + velocity.z, + ])); + + localStorage.setItem("impulseThisFrame", JSON.stringify([ + impulseThisFrame.x, + impulseThisFrame.y, + impulseThisFrame.z, + ])); + + localStorage.setItem("lastSave", JSON.stringify(Date.now())); + }); const handleUp = () => { mouse.down = false; @@ -261,6 +305,7 @@ } if (globalThis.performance.now() - mouse.lastMove > screensaverTimeoutMs) { + const impulseIdle = Vec(2, 2, -2); velocity = velocity.sum(impulseIdle.scale(effectiveDelta)); } diff --git a/site/_includes/text.vto b/site/_includes/text.vto index a8ce842..a88008d 100644 --- a/site/_includes/text.vto +++ b/site/_includes/text.vto @@ -37,9 +37,9 @@ layout: default.vto Copyright © {{ Temporal.Now.plainDateISO().year }} - {{ set cube_size = "0.75rem" }} + {{ set cube_size = "0.75rem" }} {{ set cube_small = true }} - {{ set cube_last = true }} + {{ set cube_last = true }} {{ include "rgbcube.vto" }} diff --git a/site/blog.vto b/site/blog.vto index d524fc1..9aa527f 100644 --- a/site/blog.vto +++ b/site/blog.vto @@ -162,12 +162,12 @@ Blog Articles context.shadowColor = "#94f475"; context.textBaseline = "top"; context.textAlign = "center"; - + for (const strip of strips) { context.font = `${strip.size}px sans`; if (strip.y > canvas.height + (strip.size * 40)) { - Object.assign(strip, randomStrip()) + Object.assign(strip, randomStrip()); } let { y: yCopy } = strip; @@ -192,7 +192,7 @@ Blog Articles strip.y += strip.deltaY; } - + data.animationFrameId = requestAnimationFrame(animate); }; From 876ed6405650cf764c479c7f1accd827e32ab014 Mon Sep 17 00:00:00 2001 From: RGBCube Date: Wed, 4 Jun 2025 01:55:21 +0300 Subject: [PATCH 4/5] cube: decrease screensaver timeout to 10sec --- site/_includes/cube.vto | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/_includes/cube.vto b/site/_includes/cube.vto index 7e9346c..4d9da7f 100644 --- a/site/_includes/cube.vto +++ b/site/_includes/cube.vto @@ -118,8 +118,8 @@ const sensitivityMouse = 0.01; const sensitivityWheel = 0.006; - // 15 seconds. - const screensaverTimeoutMs = 15 * 1000; + // 10 seconds. + const screensaverTimeoutMs = 10 * 1000; // 10 minutes. const stateDeleteTimeoutMs = 10 * 60 * 1000; From 89b9e6fbb8749675cf495835bd92c84fcb242225 Mon Sep 17 00:00:00 2001 From: RGBCube Date: Wed, 4 Jun 2025 02:19:19 +0300 Subject: [PATCH 5/5] cube: add keyboard controls --- site/_includes/cube.vto | 53 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/site/_includes/cube.vto b/site/_includes/cube.vto index 4d9da7f..6437aa3 100644 --- a/site/_includes/cube.vto +++ b/site/_includes/cube.vto @@ -76,6 +76,14 @@ this.z - that.z, ); }, + + mul(that) { + return Vec( + this.x * that.x, + this.y * that.y, + this.z * that.z, + ); + }, }); Vec.ZERO = Vec(0, 0, 0); @@ -163,7 +171,7 @@ window.addEventListener("beforeunload", () => { localStorage.setItem("mouseDown", JSON.stringify(mouse.down)); - localStorage.setItem("mouseLastMove", JSON.stringify(-(window.performance.now() - mouse.lastMove))); + localStorage.setItem("mouseLastMove", JSON.stringify(-(globalThis.performance.now() - mouse.lastMove))); localStorage.setItem("mousePrevious", JSON.stringify([ mouse.previous.x, mouse.previous.y, @@ -193,6 +201,49 @@ localStorage.setItem("lastSave", JSON.stringify(Date.now())); }); + document.addEventListener("keydown", (event) => { + const shift = event.shiftKey ? Vec(-1, -1, -1) : Vec(1, 1, 1); + + let effect; + + switch (event.key) { + case "Enter": + effect = Vec(0, 0, 4).mul(shift); + break; + + case " ": + effect = Vec(4, 0, 0).mul(shift); + break; + + case "h": + case "ArrowLeft": + effect = Vec(0, -4, 0); + break; + + case "j": + case "ArrowDown": + effect = Vec(-4, 0, 0); + break; + + case "k": + case "ArrowUp": + effect = Vec(4, 0, 0); + break; + + case "l": + case "ArrowRight": + effect = Vec(0, 4, 0); + break; + + default: + return; + } + + velocity = velocity.sum(effect); + + mouse.lastMove = globalThis.performance.now(); + }); + const handleUp = () => { mouse.down = false; };