mirror of
https://github.com/RGBCube/Site
synced 2025-08-03 06:27:46 +00:00
Compare commits
No commits in common. "e22ca700eeb227e9f49794a5b9947751d927d59e" and "585e17141563c8a55f5c08312c3aaf6b2bb1389c" have entirely different histories.
e22ca700ee
...
585e171415
11 changed files with 167 additions and 453 deletions
2
deno.lock
generated
2
deno.lock
generated
|
@ -666,6 +666,7 @@
|
||||||
"https://deno.land/x/lume@v3.0.2/deps/hex.ts": "828718f24a780ff3ade8d0a8a5b57497cb31c257560ef12af99b6eb1a31e3bbd",
|
"https://deno.land/x/lume@v3.0.2/deps/hex.ts": "828718f24a780ff3ade8d0a8a5b57497cb31c257560ef12af99b6eb1a31e3bbd",
|
||||||
"https://deno.land/x/lume@v3.0.2/deps/highlight.ts": "e8f830a1137ff7e8246ce21518452b8cbf8089db409458c6d9c31040c11d8428",
|
"https://deno.land/x/lume@v3.0.2/deps/highlight.ts": "e8f830a1137ff7e8246ce21518452b8cbf8089db409458c6d9c31040c11d8428",
|
||||||
"https://deno.land/x/lume@v3.0.2/deps/http.ts": "6d9add7c6fe0c0381050aa773ae8590166ccc84c5115d2cde271320c315a110d",
|
"https://deno.land/x/lume@v3.0.2/deps/http.ts": "6d9add7c6fe0c0381050aa773ae8590166ccc84c5115d2cde271320c315a110d",
|
||||||
|
"https://deno.land/x/lume@v3.0.2/deps/icons.ts": "4379e1443d982ab4f85237342d165ae54c981cdb7e06480c222d208999e21f15",
|
||||||
"https://deno.land/x/lume@v3.0.2/deps/init.ts": "05d45af66ebdfe63e43540618f51ece8f99d98dc49de890f10eeb43abe9ed0f3",
|
"https://deno.land/x/lume@v3.0.2/deps/init.ts": "05d45af66ebdfe63e43540618f51ece8f99d98dc49de890f10eeb43abe9ed0f3",
|
||||||
"https://deno.land/x/lume@v3.0.2/deps/jsonc.ts": "79f0eddc3c9e593310eb8e5918eb1506b1c7d7816e4ecb96894f634ecbe626ff",
|
"https://deno.land/x/lume@v3.0.2/deps/jsonc.ts": "79f0eddc3c9e593310eb8e5918eb1506b1c7d7816e4ecb96894f634ecbe626ff",
|
||||||
"https://deno.land/x/lume@v3.0.2/deps/lightningcss.ts": "5f5167c6eb306ef759f0043f8f33f2eaf63c69210aa1aa837505e990ee619c46",
|
"https://deno.land/x/lume@v3.0.2/deps/lightningcss.ts": "5f5167c6eb306ef759f0043f8f33f2eaf63c69210aa1aa837505e990ee619c46",
|
||||||
|
@ -691,6 +692,7 @@
|
||||||
"https://deno.land/x/lume@v3.0.2/plugins/code_highlight.ts": "ac6327e688e9e8fbd7798bdcc5f76b46d27db3e22ea3b74f545dc3296e8a1261",
|
"https://deno.land/x/lume@v3.0.2/plugins/code_highlight.ts": "ac6327e688e9e8fbd7798bdcc5f76b46d27db3e22ea3b74f545dc3296e8a1261",
|
||||||
"https://deno.land/x/lume@v3.0.2/plugins/extract_date.ts": "38af8e5960d66a74a72977eb19521da4353ab32d3941e97c1526aa3b91175a9e",
|
"https://deno.land/x/lume@v3.0.2/plugins/extract_date.ts": "38af8e5960d66a74a72977eb19521da4353ab32d3941e97c1526aa3b91175a9e",
|
||||||
"https://deno.land/x/lume@v3.0.2/plugins/feed.ts": "b07aed4cda270cfaacb26f9974dbb962f936dbfde4d770c53e478e4682c791e1",
|
"https://deno.land/x/lume@v3.0.2/plugins/feed.ts": "b07aed4cda270cfaacb26f9974dbb962f936dbfde4d770c53e478e4682c791e1",
|
||||||
|
"https://deno.land/x/lume@v3.0.2/plugins/icons.ts": "c69428254024d694eca34f9b5c4888aedf83d2d9b38f860533952c28cc814333",
|
||||||
"https://deno.land/x/lume@v3.0.2/plugins/inline.ts": "737d7de09d196476b55ecbe7ddb0e651ba2d5d39ca5a418cb15ff48e124907c1",
|
"https://deno.land/x/lume@v3.0.2/plugins/inline.ts": "737d7de09d196476b55ecbe7ddb0e651ba2d5d39ca5a418cb15ff48e124907c1",
|
||||||
"https://deno.land/x/lume@v3.0.2/plugins/json.ts": "5c49499e56b919ec848d4118ec97dd4fe0a323a6cc4c648dc45ab55297614c12",
|
"https://deno.land/x/lume@v3.0.2/plugins/json.ts": "5c49499e56b919ec848d4118ec97dd4fe0a323a6cc4c648dc45ab55297614c12",
|
||||||
"https://deno.land/x/lume@v3.0.2/plugins/lightningcss.ts": "6b5236cc78c1ae4af5b4a0037a0345797381f5043c667ae1ddeb4f67e445c7c4",
|
"https://deno.land/x/lume@v3.0.2/plugins/lightningcss.ts": "6b5236cc78c1ae4af5b4a0037a0345797381f5043c667ae1ddeb4f67e445c7c4",
|
||||||
|
|
76
site.ts
76
site.ts
|
@ -1,25 +1,25 @@
|
||||||
import lume from "lume/mod.ts";
|
import lume from "lume/mod.ts";
|
||||||
import extractDate from "lume/plugins/extract_date.ts";
|
import extract_date from "lume/plugins/extract_date.ts";
|
||||||
import codeHighlight from "lume/plugins/code_highlight.ts";
|
import code_highlight from "lume/plugins/code_highlight.ts";
|
||||||
import redirects from "lume/plugins/redirects.ts";
|
import redirects from "lume/plugins/redirects.ts";
|
||||||
import tailwindcss from "lume/plugins/tailwindcss.ts";
|
import tailwindcss from "lume/plugins/tailwindcss.ts";
|
||||||
import lightningcss from "lume/plugins/lightningcss.ts";
|
import lightningcss from "lume/plugins/lightningcss.ts";
|
||||||
import resolveUrls from "lume/plugins/resolve_urls.ts";
|
import resolve_urls from "lume/plugins/resolve_urls.ts";
|
||||||
import slugifyUrls from "lume/plugins/slugify_urls.ts";
|
import slugify_urls from "lume/plugins/slugify_urls.ts";
|
||||||
import checkUrls from "lume/plugins/check_urls.ts";
|
import check_urls from "lume/plugins/check_urls.ts";
|
||||||
import inline from "lume/plugins/inline.ts";
|
import inline from "lume/plugins/inline.ts";
|
||||||
import feed from "lume/plugins/feed.ts";
|
import feed from "lume/plugins/feed.ts";
|
||||||
import sitemap from "lume/plugins/sitemap.ts";
|
import sitemap from "lume/plugins/sitemap.ts";
|
||||||
import minifyHtml from "lume/plugins/minify_html.ts";
|
import minify_html from "lume/plugins/minify_html.ts";
|
||||||
|
|
||||||
const siteName = "RGBCube";
|
const site_name = "RGBCube";
|
||||||
const siteDescription =
|
const site_description =
|
||||||
"The home directory and journal of RGBCube and his work.";
|
"The home directory and journal of RGBCube and his work.";
|
||||||
|
|
||||||
const author = "RGBCube";
|
const author = "RGBCube";
|
||||||
const color = "#00FFFF";
|
const color = "#00FFFF";
|
||||||
|
|
||||||
const pathAssets = "/assets";
|
const path_assets = "/assets";
|
||||||
|
|
||||||
const site = lume({
|
const site = lume({
|
||||||
src: "./site",
|
src: "./site",
|
||||||
|
@ -31,9 +31,9 @@ const site = lume({
|
||||||
|
|
||||||
site.data("layout", "default.vto");
|
site.data("layout", "default.vto");
|
||||||
|
|
||||||
site.data("site_name", siteName);
|
site.data("site_name", site_name);
|
||||||
site.data("title", siteName);
|
site.data("title", site_name);
|
||||||
site.data("description", siteDescription);
|
site.data("description", site_description);
|
||||||
site.data("author", author);
|
site.data("author", author);
|
||||||
site.data("color", color);
|
site.data("color", color);
|
||||||
|
|
||||||
|
@ -69,52 +69,20 @@ site.process([".html"], (pages) => {
|
||||||
element.parentNode!.insertBefore(wrapper, element);
|
element.parentNode!.insertBefore(wrapper, element);
|
||||||
wrapper.appendChild(element);
|
wrapper.appendChild(element);
|
||||||
});
|
});
|
||||||
|
|
||||||
document
|
|
||||||
.querySelectorAll(".text-content :where(h1, h2, h3, h4, h5, h6)")
|
|
||||||
.forEach((header) => {
|
|
||||||
if (header.id || header.closest("a") || header.querySelector("a")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const textNormalized = header
|
|
||||||
.textContent!
|
|
||||||
.toLowerCase()
|
|
||||||
.replace(/[^a-z0-9\s-]/g, "")
|
|
||||||
.replace(/\s+/g, "-")
|
|
||||||
.replace(/-+/g, "-")
|
|
||||||
.trim();
|
|
||||||
|
|
||||||
let textUnique = textNormalized;
|
|
||||||
let counter = 1;
|
|
||||||
|
|
||||||
while (document.getElementById(textUnique)) {
|
|
||||||
counter++;
|
|
||||||
textUnique = `${textNormalized}-${counter}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
header.id = textUnique;
|
|
||||||
|
|
||||||
const link = document.createElement("a");
|
|
||||||
link.setAttribute("href", "#" + textUnique);
|
|
||||||
|
|
||||||
header.parentNode!.insertBefore(link, header);
|
|
||||||
link.appendChild(header);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
site.use(extractDate());
|
site.use(extract_date());
|
||||||
site.use(redirects());
|
site.use(redirects());
|
||||||
|
|
||||||
site.use(tailwindcss());
|
site.use(tailwindcss());
|
||||||
site.use(codeHighlight());
|
site.use(code_highlight());
|
||||||
|
|
||||||
site.use(resolveUrls());
|
site.use(resolve_urls());
|
||||||
site.use(slugifyUrls({
|
site.use(slugify_urls({
|
||||||
extensions: "*",
|
extensions: "*",
|
||||||
}));
|
}));
|
||||||
site.use(checkUrls({
|
site.use(check_urls({
|
||||||
strict: true,
|
strict: true,
|
||||||
throw: true,
|
throw: true,
|
||||||
}));
|
}));
|
||||||
|
@ -127,12 +95,12 @@ site.use(feed({
|
||||||
limit: Infinity,
|
limit: Infinity,
|
||||||
|
|
||||||
info: {
|
info: {
|
||||||
title: siteName,
|
title: site_name,
|
||||||
description: siteDescription,
|
description: site_description,
|
||||||
authorName: author,
|
authorName: author,
|
||||||
|
|
||||||
image: `${pathAssets}/icons/icon.webp`,
|
image: `${path_assets}/icons/icon.webp`,
|
||||||
icon: `${pathAssets}/icons/icon.webp`,
|
icon: `${path_assets}/icons/icon.webp`,
|
||||||
|
|
||||||
color,
|
color,
|
||||||
|
|
||||||
|
@ -154,7 +122,7 @@ site.use(sitemap({
|
||||||
site.use(lightningcss()); // TODO: LightningCSS doesn't handle inline styles.
|
site.use(lightningcss()); // TODO: LightningCSS doesn't handle inline styles.
|
||||||
site.use(inline());
|
site.use(inline());
|
||||||
|
|
||||||
site.use(minifyHtml({
|
site.use(minify_html({
|
||||||
options: {
|
options: {
|
||||||
// TODO: This breaks tailwind.
|
// TODO: This breaks tailwind.
|
||||||
// minify_css: true,
|
// minify_css: true,
|
||||||
|
|
12
site/404.vto
12
site/404.vto
|
@ -4,20 +4,10 @@ prevent_zoom: true
|
||||||
---
|
---
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
html {
|
|
||||||
font-size: min(9svw, 9svh, 4.5rem);
|
|
||||||
overscroll-behavior: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
cube-scene {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
cube-face {
|
cube-face {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, 1fr);
|
grid-template-columns: repeat(2, 1fr);
|
||||||
grid-template-rows: repeat(2, 1fr);
|
grid-template-rows: repeat(2, 1fr);
|
||||||
|
|
||||||
box-shadow: 0 0 10px var(--foreground);
|
box-shadow: 0 0 10px var(--foreground);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -38,6 +28,4 @@ prevent_zoom: true
|
||||||
{{ set cube_face_top = cube_face }}
|
{{ set cube_face_top = cube_face }}
|
||||||
{{ set cube_face_bottom = cube_face }}
|
{{ set cube_face_bottom = cube_face }}
|
||||||
|
|
||||||
{{ set cube_size = "5rem" }}
|
|
||||||
{{ set cube_last = true }}
|
|
||||||
{{ include "cube.vto" }}
|
{{ include "cube.vto" }}
|
||||||
|
|
|
@ -1,43 +1,44 @@
|
||||||
{{ set cube_minus_px = cube_small ? "" : "- 1px" }}
|
|
||||||
|
|
||||||
{{ if cube_last }}
|
|
||||||
<style>
|
<style>
|
||||||
cube-face {
|
:root {
|
||||||
height: {{ cube_size }};
|
--cube-width: 5rem;
|
||||||
width: {{ cube_size }};
|
}
|
||||||
|
|
||||||
position: absolute;
|
html {
|
||||||
|
font-size: min(9svw, 9svh, 4.5rem);
|
||||||
|
overscroll-behavior: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Guess what? Yeah, you guessed right. Safari can't render shit. */
|
/* Guess what? Yeah, you guessed right. Safari can't render shit. */
|
||||||
.cube-face-front { transform: rotateY(0deg) translateZ(calc({{ cube_size }} / 2 {{ cube_minus_px }})); }
|
.cube-face-front { transform: rotateY(0deg) translateZ(calc(var(--cube-width) / 2 - 1px)); }
|
||||||
.cube-face-top { transform: rotateX( 89.99999999999999deg) translateZ(calc({{ cube_size }} / 2 {{ cube_minus_px }})); }
|
.cube-face-top { transform: rotateX( 89.99999999999999deg) translateZ(calc(var(--cube-width) / 2 - 1px)); }
|
||||||
.cube-face-back { transform: rotateY(180deg) translateZ(calc({{ cube_size }} / 2 {{ cube_minus_px }})); }
|
.cube-face-back { transform: rotateY(180deg) translateZ(calc(var(--cube-width) / 2 - 1px)); }
|
||||||
.cube-face-bottom { transform: rotateX(-89.99999999999999deg) translateZ(calc({{ cube_size }} / 2 {{ cube_minus_px }})); }
|
.cube-face-bottom { transform: rotateX(-89.99999999999999deg) translateZ(calc(var(--cube-width) / 2 - 1px)); }
|
||||||
.cube-face-right { transform: rotateY( 89.99999999999999deg) translateZ(calc({{ cube_size }} / 2 {{ cube_minus_px }})); }
|
.cube-face-right { transform: rotateY( 89.99999999999999deg) translateZ(calc(var(--cube-width) / 2 - 1px)); }
|
||||||
.cube-face-left { transform: rotateY(-89.99999999999999deg) translateZ(calc({{ cube_size }} / 2 {{ cube_minus_px }})); }
|
.cube-face-left { transform: rotateY(-89.99999999999999deg) translateZ(calc(var(--cube-width) / 2 - 1px)); }
|
||||||
</style>
|
</style>
|
||||||
{{ /if }}
|
|
||||||
|
|
||||||
<cube-scene class="
|
<cube-scene class="
|
||||||
|
h-dvh w-dvw
|
||||||
flex items-center justify-center
|
flex items-center justify-center
|
||||||
perspective-[calc({{ cube_size.replaceAll(" ", "_") }}*3)]
|
perspective-[calc(var(--cube-width)*3)]
|
||||||
overscroll-none
|
|
||||||
">
|
">
|
||||||
<cube-itself class="
|
<cube-itself class="
|
||||||
size-[{{ cube_size }}]
|
size-(--cube-width)
|
||||||
transform-3d transform-[translateZ(calc({{ cube_size.replaceAll(" ", "_") }}_/_-2))]
|
transform-3d transform-[translateZ(-calc(var(--cube-width)/2-1px))]
|
||||||
">
|
">
|
||||||
<cube-face draggable="false" class="cube-face-front"> {{ cube_face_front }} </cube-face>
|
{{> const style = `
|
||||||
<cube-face draggable="false" class="cube-face-back"> {{ cube_face_back }} </cube-face>
|
size-(--cube-width) absolute
|
||||||
<cube-face draggable="false" class="cube-face-left"> {{ cube_face_left }} </cube-face>
|
flex items-center justify-center
|
||||||
<cube-face draggable="false" class="cube-face-right"> {{ cube_face_right }} </cube-face>
|
` }}
|
||||||
<cube-face draggable="false" class="cube-face-top"> {{ cube_face_top }} </cube-face>
|
<cube-face draggable="false" class="{{ style }} cube-face-front"> {{ cube_face_front }} </cube-face>
|
||||||
<cube-face draggable="false" class="cube-face-bottom"> {{ cube_face_bottom }} </cube-face>
|
<cube-face draggable="false" class="{{ style }} cube-face-back"> {{ cube_face_back }} </cube-face>
|
||||||
|
<cube-face draggable="false" class="{{ style }} cube-face-left"> {{ cube_face_left }} </cube-face>
|
||||||
|
<cube-face draggable="false" class="{{ style }} cube-face-right"> {{ cube_face_right }} </cube-face>
|
||||||
|
<cube-face draggable="false" class="{{ style }} cube-face-top"> {{ cube_face_top }} </cube-face>
|
||||||
|
<cube-face draggable="false" class="{{ style }} cube-face-bottom"> {{ cube_face_bottom }} </cube-face>
|
||||||
</cube-itself>
|
</cube-itself>
|
||||||
</cube-scene>
|
</cube-scene>
|
||||||
|
|
||||||
{{ if cube_last }}
|
|
||||||
<script>
|
<script>
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
@ -60,40 +61,27 @@
|
||||||
|
|
||||||
return Vec(this.x / length, this.y / length, this.z / length);
|
return Vec(this.x / length, this.y / length, this.z / length);
|
||||||
},
|
},
|
||||||
|
|
||||||
sum(that) {
|
|
||||||
return Vec(
|
|
||||||
this.x + that.x,
|
|
||||||
this.y + that.y,
|
|
||||||
this.z + that.z,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
sub(that) {
|
|
||||||
return Vec(
|
|
||||||
this.x - that.x,
|
|
||||||
this.y - that.y,
|
|
||||||
this.z - that.z,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Vec.ZERO = Vec(0, 0, 0);
|
Vec.ZERO = Vec(0, 0, 0);
|
||||||
|
|
||||||
|
Vec.sum = (a, b) => Vec(
|
||||||
|
a.x + b.x,
|
||||||
|
a.y + b.y,
|
||||||
|
a.z + b.z,
|
||||||
|
);
|
||||||
|
|
||||||
|
Vec.sub = (a, b) => Vec(
|
||||||
|
a.x - b.x,
|
||||||
|
a.y - b.y,
|
||||||
|
a.z - b.z,
|
||||||
|
);
|
||||||
|
|
||||||
const Quat = (x, y, z, w) => ({
|
const Quat = (x, y, z, w) => ({
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
z,
|
z,
|
||||||
w,
|
w,
|
||||||
|
|
||||||
mul(that) {
|
|
||||||
return Quat(
|
|
||||||
this.w * that.x + this.x * that.w + this.y * that.z - this.z * that.y,
|
|
||||||
this.w * that.y - this.x * that.z + this.y * that.w + this.z * that.x,
|
|
||||||
this.w * that.z + this.x * that.y - this.y * that.x + this.z * that.w,
|
|
||||||
this.w * that.w - this.x * that.x - this.y * that.y - this.z * that.z,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Quat.fromAxis = (axis) => {
|
Quat.fromAxis = (axis) => {
|
||||||
|
@ -114,12 +102,19 @@
|
||||||
return Quat(x, y, z, w);
|
return Quat(x, y, z, w);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Quat.mul = (a, b) => Quat(
|
||||||
|
a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y,
|
||||||
|
a.w * b.y - a.x * b.z + a.y * b.w + a.z * b.x,
|
||||||
|
a.w * b.z + a.x * b.y - a.y * b.x + a.z * b.w,
|
||||||
|
a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z,
|
||||||
|
);
|
||||||
|
|
||||||
const friction = 3;
|
const friction = 3;
|
||||||
const sensitivityMouse = 0.01;
|
const sensitivityMouse = 0.01;
|
||||||
const sensitivityWheel = 0.006;
|
const sensitivityWheel = 0.006;
|
||||||
|
|
||||||
// 15 seconds.
|
// One minute.
|
||||||
const screensaverTimeoutMs = 15 * 1000;
|
const screensaverTimeoutMs = 1 * 60 * 1000;
|
||||||
|
|
||||||
const mouse = {
|
const mouse = {
|
||||||
down: false,
|
down: false,
|
||||||
|
@ -128,16 +123,15 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
const orient = {
|
const orient = {
|
||||||
elements: document.querySelectorAll("cube-itself"),
|
element: document.querySelector("cube-itself"),
|
||||||
quat: Quat(0, 0, 0, 1),
|
quat: Quat(0, 0, 0, 1),
|
||||||
|
|
||||||
set(q) {
|
set(q) {
|
||||||
this.quat = q;
|
this.quat = q;
|
||||||
|
|
||||||
for (const element of this.elements) {
|
this.element.style.transform = `rotate3d(${q.x}, ${q.y}, ${q.z}, ${
|
||||||
element.style.transform =
|
Math.acos(q.w) * 2
|
||||||
`rotate3d(${q.x}, ${q.y}, ${q.z}, ${Math.acos(q.w) * 2}rad)`;
|
}rad)`;
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
get() {
|
get() {
|
||||||
|
@ -147,7 +141,6 @@
|
||||||
|
|
||||||
let velocity = Vec.ZERO;
|
let velocity = Vec.ZERO;
|
||||||
let impulseThisFrame = Vec.ZERO;
|
let impulseThisFrame = Vec.ZERO;
|
||||||
let impulseIdle = Vec(2, 2, -2);
|
|
||||||
|
|
||||||
const handleUp = () => {
|
const handleUp = () => {
|
||||||
mouse.down = false;
|
mouse.down = false;
|
||||||
|
@ -178,7 +171,7 @@
|
||||||
mouse.previous = newMouse;
|
mouse.previous = newMouse;
|
||||||
}
|
}
|
||||||
|
|
||||||
const delta = newMouse.sub(mouse.previous);
|
const delta = Vec.sub(newMouse, mouse.previous);
|
||||||
|
|
||||||
mouse.previous = newMouse;
|
mouse.previous = newMouse;
|
||||||
mouse.lastMove = globalThis.performance.now();
|
mouse.lastMove = globalThis.performance.now();
|
||||||
|
@ -188,10 +181,10 @@
|
||||||
.scale(delta.length())
|
.scale(delta.length())
|
||||||
.scale(sensitivityMouse);
|
.scale(sensitivityMouse);
|
||||||
|
|
||||||
impulseThisFrame = impulseThisFrame.sum(axis);
|
impulseThisFrame = Vec.sum(impulseThisFrame, axis);
|
||||||
|
|
||||||
const rotation = Quat.fromAxis(axis);
|
const rotation = Quat.fromAxis(axis);
|
||||||
orient.set(rotation.mul(orient.get()));
|
orient.set(Quat.mul(rotation, orient.get()));
|
||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener("mousemove", handleMove);
|
document.addEventListener("mousemove", handleMove);
|
||||||
|
@ -218,10 +211,10 @@
|
||||||
const axis = Vec(event.deltaY, -event.deltaX, 0)
|
const axis = Vec(event.deltaY, -event.deltaX, 0)
|
||||||
.scale(sensitivityWheel);
|
.scale(sensitivityWheel);
|
||||||
|
|
||||||
impulseThisFrame = impulseThisFrame.sum(axis);
|
impulseThisFrame = Vec.sum(impulseThisFrame, axis);
|
||||||
|
|
||||||
const rotation = Quat.fromAxis(axis);
|
const rotation = Quat.fromAxis(axis);
|
||||||
orient.set(rotation.mul(orient.get()));
|
orient.set(Quat.mul(rotation, orient.get()));
|
||||||
};
|
};
|
||||||
|
|
||||||
document.addEventListener("wheel", handleWheel, { passive: false });
|
document.addEventListener("wheel", handleWheel, { passive: false });
|
||||||
|
@ -261,7 +254,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (globalThis.performance.now() - mouse.lastMove > screensaverTimeoutMs) {
|
if (globalThis.performance.now() - mouse.lastMove > screensaverTimeoutMs) {
|
||||||
velocity = velocity.sum(impulseIdle.scale(effectiveDelta));
|
const impulse = Vec(0.7, 0.7, -0.7);
|
||||||
|
velocity = Vec.sum(impulse.scale(effectiveDelta * 3), velocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
const axis = Vec(velocity.x, velocity.y, velocity.z)
|
const axis = Vec(velocity.x, velocity.y, velocity.z)
|
||||||
|
@ -270,11 +264,10 @@
|
||||||
|
|
||||||
const rotation = Quat.fromAxis(axis);
|
const rotation = Quat.fromAxis(axis);
|
||||||
|
|
||||||
orient.set(rotation.mul(orient.get()));
|
orient.set(Quat.mul(rotation, orient.get()));
|
||||||
|
|
||||||
requestAnimationFrame(updateFrame);
|
requestAnimationFrame(updateFrame);
|
||||||
};
|
};
|
||||||
|
|
||||||
updateFrame(0);
|
updateFrame(0);
|
||||||
</script>
|
</script>
|
||||||
{{ /if }}
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ layout: null
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
|
||||||
<!-- VIEWPORT -->
|
<!-- VIEWPORT -->
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0{{ if prevent_zoom }}, maximum-scale=1.0, user-scalable=0{{ /if }}">
|
<meta name="viewport" content="width=device-width,initial-scale=1.0{{ if prevent_zoom }},maximum-scale=1.0,user-scalable=0{{ /if }}">
|
||||||
|
|
||||||
<!-- NUKE DARKREADER -->
|
<!-- NUKE DARKREADER -->
|
||||||
<meta name="darkreader-lock">
|
<meta name="darkreader-lock">
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
<style>
|
|
||||||
cube-face {
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
z-index: -1;
|
|
||||||
content: "";
|
|
||||||
|
|
||||||
height: inherit;
|
|
||||||
width: inherit;
|
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cube-face-front {
|
|
||||||
background: linear-gradient(to bottom, cyan, blue);
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
background: linear-gradient(to bottom, white, magenta);
|
|
||||||
mask-image: linear-gradient(to left, magenta, transparent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cube-face-top {
|
|
||||||
background: linear-gradient(to bottom, lime, cyan);
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
background: linear-gradient(to bottom, yellow, white);
|
|
||||||
mask-image: linear-gradient(to left, white, transparent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cube-face-back {
|
|
||||||
background: linear-gradient(to bottom, yellow, red);
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
background: linear-gradient(to bottom, lime, black);
|
|
||||||
mask-image: linear-gradient(to left, black, transparent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cube-face-bottom {
|
|
||||||
background: linear-gradient(to bottom, blue, black);
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
background: linear-gradient(to bottom, magenta, red);
|
|
||||||
mask-image: linear-gradient(to left, red, transparent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cube-face-right {
|
|
||||||
background: linear-gradient(to bottom, white, magenta);
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
background: linear-gradient(to bottom, yellow, red);
|
|
||||||
mask-image: linear-gradient(to left, red, transparent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cube-face-left {
|
|
||||||
background: linear-gradient(to bottom, lime, black);
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
background: linear-gradient(to bottom, cyan, blue);
|
|
||||||
mask-image: linear-gradient(to left, blue, transparent);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
{{ include "cube.vto" }}
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
layout: default.vto
|
layout: default.vto
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="flex justify-center h-[inherit]">
|
<div class="flex justify-center">
|
||||||
<div class="flex flex-col h-[inherit] w-[min(100dvw,50rem)]">
|
<div class="block text-xl w-[min(100vw,50rem)]">
|
||||||
|
|
||||||
<nav class="
|
<nav class="
|
||||||
transform-[rotateX(180deg)]
|
transform-[rotateX(180deg)]
|
||||||
|
@ -28,20 +28,16 @@ layout: default.vto
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
{{> const padding = 4 }}
|
{{> const padding = 4 }} <!-- Keep in sync with -mx-N in default.css. -->
|
||||||
<div class="text-content text-xl p-{{ padding }} pt-{{ padding + 12 }}">
|
<div class="text-content p-{{ padding }} pt-{{ padding + 12 }}">
|
||||||
{{ content }}
|
{{ content }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer class="flex justify-center text-sm wrap-anywhere mt-auto p-1.5 pb-2 border-t-4 border-x-4">
|
<hr class="border-2 border-black dark:border-white">
|
||||||
Copyright {{ Temporal.Now.plainDateISO().year }} ©
|
|
||||||
|
|
||||||
<a draggable="false" class="flex items-center pl-2" href="/">
|
<footer class="flex justify-center text-sm pt-1 pb-2 wrap-anywhere">
|
||||||
{{ set cube_size = "0.75rem" }}
|
Copyright {{ Temporal.Now.plainDateISO().year }} ©
|
||||||
{{ set cube_small = true }}
|
<a href="/"><img class="pl-0.5 pt-0.25 size-5" src="/assets/icons/icon.gif" alt="RGBCube"></a>
|
||||||
{{ set cube_last = true }}
|
|
||||||
{{ include "rgbcube.vto" }}
|
|
||||||
</a>
|
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -125,11 +125,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html, body {
|
|
||||||
height: 100dvh;
|
|
||||||
width: 100dvw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-content {
|
.text-content {
|
||||||
@apply space-y-3;
|
@apply space-y-3;
|
||||||
|
|
||||||
|
@ -165,47 +160,19 @@ html, body {
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@apply m-0;
|
@apply inline-block wrap-anywhere text-[red] dark:text-[yellow] px-1 pb-0.75
|
||||||
|
border-2 border-[transparent] border-dashed;
|
||||||
|
|
||||||
* {
|
* {
|
||||||
@apply wrap-anywhere;
|
@apply wrap-anywhere;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(:has(> code:only-child)) {
|
&:hover {
|
||||||
@apply px-1;
|
@apply border-[red] dark:border-[yellow];
|
||||||
|
|
||||||
&:not(.font-mono) {
|
|
||||||
@apply pb-0.75;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(:has(h1, h2, h3, h4, h5, h6)) {
|
&:active {
|
||||||
@apply inline-block wrap-anywhere text-[red] dark:text-[yellow] border-2
|
@apply border-[fuchsia] dark:border-[springgreen] animate-to-the-future;
|
||||||
border-[transparent] border-dashed;
|
|
||||||
|
|
||||||
&:has(> code:only-child) {
|
|
||||||
@apply border-dotted;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
@apply border-[red] dark:border-[yellow];
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
@apply border-[fuchsia] dark:border-[springgreen] animate-to-the-future;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& :where(h1, h2, h3, h4, h5, h6) {
|
|
||||||
@apply before:underline before:underline-offset-4;
|
|
||||||
|
|
||||||
* {
|
|
||||||
@apply inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover::before {
|
|
||||||
@apply italic text-[red] dark:text-[yellow];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,20 +194,12 @@ html, body {
|
||||||
@apply border-black dark:border-white;
|
@apply border-black dark:border-white;
|
||||||
}
|
}
|
||||||
|
|
||||||
code:not(pre > code) {
|
|
||||||
@apply border-1 border-dotted px-2 py-0.5 border-black dark:border-white;
|
|
||||||
|
|
||||||
a:hover &, a:active & {
|
|
||||||
@apply border-transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pre code, pre code * {
|
pre code, pre code * {
|
||||||
@apply whitespace-pre;
|
@apply whitespace-pre;
|
||||||
}
|
}
|
||||||
|
|
||||||
div:has(> pre code) {
|
div:has(> pre code) {
|
||||||
@apply outline outline-dotted outline-offset-1 outline-[#444] border-1
|
@apply outline-1 outline-dotted outline-offset-1 outline-[#444] border-1
|
||||||
border-black p-2 bg-[#eee] dark:outline-[#bbb] dark:border-white
|
border-black p-2 bg-[#eee] dark:outline-[#bbb] dark:border-white
|
||||||
dark:bg-[#111];
|
dark:bg-[#111];
|
||||||
}
|
}
|
||||||
|
@ -261,7 +220,8 @@ html, body {
|
||||||
}
|
}
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
@apply border-1 border-black dark:border-white;
|
@apply border-1 border-black dark:border-white
|
||||||
|
-mx-4; /* Keep in sync with p-N in text.vto. */
|
||||||
}
|
}
|
||||||
|
|
||||||
blockquote {
|
blockquote {
|
||||||
|
|
181
site/blog.vto
181
site/blog.vto
|
@ -9,8 +9,8 @@ title: about:blog
|
||||||
Blog Articles
|
Blog Articles
|
||||||
|
|
||||||
<span class="whitespace-nowrap overflow-hidden text-sm font-[ecrou]">
|
<span class="whitespace-nowrap overflow-hidden text-sm font-[ecrou]">
|
||||||
<a id="matrix" href="/blog.rss">rss</a>
|
<a href="/blog.rss">rss</a>
|
||||||
<a id="matrix" href="/blog.json">json</a>
|
<a href="/blog.json">json</a>
|
||||||
</span>
|
</span>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
|
@ -20,183 +20,14 @@ Blog Articles
|
||||||
<ul>
|
<ul>
|
||||||
{{ for article of search.pages("type=article", "order=asc date=desc")}}
|
{{ for article of search.pages("type=article", "order=asc date=desc")}}
|
||||||
<li class="flex">
|
<li class="flex">
|
||||||
<a id="matrix" class="text-right font-mono" style="margin-right:calc(var(--spacing)*2)" href="{{ article.url }}">
|
<!-- Nope, m-0 doesn't work! -->
|
||||||
|
<code style="margin:0" class="pr-1.25">
|
||||||
|
<a class="text-right" href="{{ article.url }}">
|
||||||
{{ article.date.toISOString().slice(2, 10).replaceAll("-", " ") }}
|
{{ article.date.toISOString().slice(2, 10).replaceAll("-", " ") }}
|
||||||
</a>
|
</a>
|
||||||
|
</code>
|
||||||
|
|
||||||
{{ article.title |> md }}
|
{{ article.title |> md }}
|
||||||
</li>
|
</li>
|
||||||
{{ /for }}
|
{{ /for }}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<script>
|
|
||||||
{
|
|
||||||
let typed = "";
|
|
||||||
const target = "mat";
|
|
||||||
|
|
||||||
document.addEventListener("keydown", (event) => {
|
|
||||||
typed += event.key.toLowerCase();
|
|
||||||
|
|
||||||
if (typed.length > target.length) typed = typed.slice(-target.length);
|
|
||||||
|
|
||||||
if (typed === target) {
|
|
||||||
toggle();
|
|
||||||
typed = "";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let data = null;
|
|
||||||
|
|
||||||
const toggle = () => {
|
|
||||||
if (data) {
|
|
||||||
Object.values(data).forEach(({ interval, element, original }) => {
|
|
||||||
clearInterval(interval);
|
|
||||||
|
|
||||||
element.innerHTML = original;
|
|
||||||
|
|
||||||
element.style.color = "";
|
|
||||||
element.style.textShadow = "";
|
|
||||||
element.style.filter = "";
|
|
||||||
});
|
|
||||||
|
|
||||||
data = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
data = {};
|
|
||||||
|
|
||||||
document.querySelectorAll("#matrix").forEach((element, index) => {
|
|
||||||
const original = element.textContent;
|
|
||||||
|
|
||||||
const randomize = () => {
|
|
||||||
const dark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
||||||
|
|
||||||
const color = dark ? "#00ff00" : "#00cc00";
|
|
||||||
const glowColor = dark ? "#00ff00" : "#00ff00";
|
|
||||||
|
|
||||||
element.style.color = color;
|
|
||||||
element.style.filter = `drop-shadow(0 0 5px ${glowColor})`;
|
|
||||||
|
|
||||||
element.innerHTML = original.replace(/\d/g, () => `<span${Math.random() > 0.5 ? "" : ` style="text-shadow: 0 0 2px ${glowColor}"`}>${Math.floor(Math.random() * 10)}</span>`);
|
|
||||||
};
|
|
||||||
|
|
||||||
randomize();
|
|
||||||
const interval = setInterval(randomize, 100);
|
|
||||||
|
|
||||||
data[index] = { interval, element, original };
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
{
|
|
||||||
let typed = "";
|
|
||||||
const target = "rix";
|
|
||||||
|
|
||||||
document.addEventListener("keydown", (event) => {
|
|
||||||
typed += event.key.toLowerCase();
|
|
||||||
|
|
||||||
if (typed.length > target.length) typed = typed.slice(-target.length);
|
|
||||||
|
|
||||||
if (typed === target) {
|
|
||||||
toggle();
|
|
||||||
typed = "";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const randomStrip = () => ({
|
|
||||||
xFactor: Math.random() * 0.90 + (1 - 0.90) / 2,
|
|
||||||
y: Math.random() * -window.innerHeight - 100,
|
|
||||||
deltaY: Math.random() * 1.7 + 1,
|
|
||||||
size: Math.floor(Math.random() * 16) + 8,
|
|
||||||
});
|
|
||||||
|
|
||||||
const strips = Array.from({ length: 60 }, () => randomStrip());
|
|
||||||
|
|
||||||
let data = null;
|
|
||||||
|
|
||||||
const toggle = () => {
|
|
||||||
if (data) {
|
|
||||||
cancelAnimationFrame(data.animationFrameId);
|
|
||||||
data.canvas.remove();
|
|
||||||
|
|
||||||
window.removeEventListener("resize", data.handleResize);
|
|
||||||
|
|
||||||
data = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
data = {};
|
|
||||||
|
|
||||||
data.canvas = document.body.appendChild(document.createElement("canvas"));
|
|
||||||
const { canvas } = data;
|
|
||||||
canvas.style.position = "fixed";
|
|
||||||
canvas.style.top = "0";
|
|
||||||
canvas.style.left = "0";
|
|
||||||
canvas.style.width = "100%";
|
|
||||||
canvas.style.height = "100%";
|
|
||||||
canvas.style.zIndex = "999999999";
|
|
||||||
canvas.style.pointerEvents = "none";
|
|
||||||
|
|
||||||
data.context = canvas.getContext("2d");
|
|
||||||
const { context } = data;
|
|
||||||
context.globalCompositeOperation = "lighter";
|
|
||||||
|
|
||||||
const handleResize = () => {
|
|
||||||
canvas.width = window.innerWidth;
|
|
||||||
canvas.height = window.innerHeight;
|
|
||||||
};
|
|
||||||
|
|
||||||
handleResize();
|
|
||||||
window.addEventListener("resize", handleResize);
|
|
||||||
data.handleResize = handleResize;
|
|
||||||
|
|
||||||
const animate = () => {
|
|
||||||
const { canvas, context } = data;
|
|
||||||
|
|
||||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
|
||||||
context.shadowOffsetX = 0;
|
|
||||||
context.shadowOffsetY = 0;
|
|
||||||
context.shadowBlur = 8;
|
|
||||||
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())
|
|
||||||
}
|
|
||||||
|
|
||||||
let { y: yCopy } = strip;
|
|
||||||
for (let i = 0; i < 20; i++) {
|
|
||||||
switch (true) {
|
|
||||||
case i < 1: context.fillStyle = "#cefbe4"; break;
|
|
||||||
case i < 2: context.fillStyle = "#81ec72"; break;
|
|
||||||
case i < 4: context.fillStyle = "#5cd646"; break;
|
|
||||||
case i < 8: context.fillStyle = "#54d13c"; break;
|
|
||||||
case i < 14: context.fillStyle = "#4ccc32"; break;
|
|
||||||
case i < 18: context.fillStyle = "#43c728"; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const characters = ["诶", "比", "西", "迪", "伊", "吉", "艾", "杰", "开", "哦", "屁", "提", "维"];
|
|
||||||
const character = characters[Math.floor(Math.random() * characters.length)];
|
|
||||||
|
|
||||||
context.fillText(character, strip.xFactor * canvas.width, yCopy);
|
|
||||||
|
|
||||||
// Deterministic but still random.
|
|
||||||
yCopy -= strips[i].size;
|
|
||||||
}
|
|
||||||
|
|
||||||
strip.y += strip.deltaY;
|
|
||||||
}
|
|
||||||
|
|
||||||
data.animationFrameId = requestAnimationFrame(animate);
|
|
||||||
};
|
|
||||||
|
|
||||||
animate();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -35,5 +35,5 @@ Here are some other useful links as well:
|
||||||
|
|
||||||
const element = document.getElementById("bot-block");
|
const element = document.getElementById("bot-block");
|
||||||
element.href = real;
|
element.href = real;
|
||||||
element.children[0].textContent = real.substring(7);
|
element.children[0].innerHTML = real.substring(7);
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -3,18 +3,68 @@ prevent_zoom: true
|
||||||
---
|
---
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
html {
|
cube-face::after {
|
||||||
font-size: min(9svw, 9svh, 4.5rem);
|
z-index: -1;
|
||||||
overscroll-behavior: none;
|
content: "";
|
||||||
|
|
||||||
|
height: inherit;
|
||||||
|
width: inherit;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
cube-scene {
|
.cube-face-front {
|
||||||
height: 100%;
|
background: linear-gradient(to bottom, cyan, blue);
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
background: linear-gradient(to bottom, white, magenta);
|
||||||
|
mask-image: linear-gradient(to left, magenta, transparent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cube-face {
|
.cube-face-top {
|
||||||
align-items: center;
|
background: linear-gradient(to bottom, lime, cyan);
|
||||||
justify-content: center;
|
|
||||||
|
&::after {
|
||||||
|
background: linear-gradient(to bottom, yellow, white);
|
||||||
|
mask-image: linear-gradient(to left, white, transparent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cube-face-back {
|
||||||
|
background: linear-gradient(to bottom, yellow, red);
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
background: linear-gradient(to bottom, lime, black);
|
||||||
|
mask-image: linear-gradient(to left, black, transparent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cube-face-bottom {
|
||||||
|
background: linear-gradient(to bottom, blue, black);
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
background: linear-gradient(to bottom, magenta, red);
|
||||||
|
mask-image: linear-gradient(to left, red, transparent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cube-face-right {
|
||||||
|
background: linear-gradient(to bottom, white, magenta);
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
background: linear-gradient(to bottom, yellow, red);
|
||||||
|
mask-image: linear-gradient(to left, red, transparent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cube-face-left {
|
||||||
|
background: linear-gradient(to bottom, lime, black);
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
background: linear-gradient(to bottom, cyan, blue);
|
||||||
|
mask-image: linear-gradient(to left, blue, transparent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
@ -41,6 +91,4 @@ prevent_zoom: true
|
||||||
<a draggable="false" class="{{ style }}" href="/blog/">blog</a>
|
<a draggable="false" class="{{ style }}" href="/blog/">blog</a>
|
||||||
{{ /set }}
|
{{ /set }}
|
||||||
|
|
||||||
{{ set cube_size = "5rem" }}
|
{{ include "cube.vto" }}
|
||||||
{{ set cube_last = true }}
|
|
||||||
{{ include "rgbcube.vto" }}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue