feat: New collection and view

- Add art collection
- Move views to art
- Add new view
This commit is contained in:
sthag 2026-04-20 20:13:58 +02:00
parent 5cd55ab2bc
commit 0f92174143
4 changed files with 199 additions and 2 deletions

View file

@ -0,0 +1,167 @@
---
title: Matrix
tags:
- demoArt
---
{% layout 'hippie/simple.liquid' %}
{% block style %}
<style>
html, body {
height: 100vh;
box-sizing: border-box;
}
body {
margin: 0;
background-color: grey;
font-family: 'Courier New', Courier, monospace;
}
#canvas {
display: block;
width: 100%;
height: 100%;
}
</style>
{% endblock %}
{% block body %}
<canvas id="canvas"></canvas>
{% endblock %}
{% block script %}
<script>
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
// const observer = new ResizeObserver(() => {
// canvas.width = canvas.clientWidth;
// canvas.height = canvas.clientHeight;
// console.log("resize");
// });
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
// observer.observe(canvas);
ctx.font = "24px 'Courier New', Courier, monospace";
ctx.textBaseline = "top";
let char = characters.charAt(Math.floor(Math.random() * characters.length));
let charMeasure = ctx.measureText(char);
let charW = Math.ceil(Math.max(charMeasure.actualBoundingBoxLeft + charMeasure.actualBoundingBoxRight, charMeasure.width));
let charH = charMeasure.fontBoundingBoxDescent + charMeasure.fontBoundingBoxAscent;
let glyph = {
text: char,
x: 0,
y: 0,
w: charH,
h: charH
}
let lane = [];
let max = Math.floor(canvas.clientHeight / glyph.h);
let newId = undefined;
let holdId = undefined;
let cleanId = undefined;
let newInterval = 300;
let holdInterval = 1000;
let cleanInterval = 400;
let newIndex = 0;
let cleanIndex = randomIntFrom(1, max);
console.log("init", newInterval);
console.log(glyph);
newId = setInterval(newTrail, newInterval);
function newTrail() {
clearInterval(holdId);
glyph.text = characters.charAt(Math.floor(Math.random() * characters.length));
console.log(newIndex, glyph.text);
lane.push([newIndex, glyph.text, glyph.y]);
ctx.fillStyle = "white";
ctx.fillRect(glyph.x, glyph.y, glyph.w, glyph.h);
ctx.fillStyle = "black";
ctx.fillText(glyph.text, Math.floor((charH - charW) / 2), glyph.y);
if (newIndex > 0) {
let prevY = glyph.y - glyph.h;
let alpha = randomBetween(.2, 1);
ctx.clearRect(glyph.x, prevY, glyph.w, glyph.h);
ctx.fillStyle = "rgba(0, 0, 0, " + alpha + ")";
ctx.fillRect(glyph.x, prevY, glyph.w, glyph.h);
ctx.fillStyle = "rgba(255, 255, 255, " + alpha + ")";
// TODO: can not use array lane if it is changed by cleanTrail()
ctx.fillText(lane[newIndex - 1][1], Math.floor((charH - charW) / 2), prevY);
}
if (newIndex === cleanIndex) {
console.log("clean", cleanInterval, cleanIndex);
cleanId = setInterval(cleanTrail, cleanInterval);
}
newIndex++;
glyph.y += glyph.h;
if (newIndex > max) {
// console.log("hold", holdInterval);
console.log("end");
clearInterval(newId);
newIndex = 0;
glyph.y = 0;
newInterval = randomIntFrom(100, 1000, 2);
// holdId = setTimeout(() => {
// console.log("clean", cleanInterval);
// holdInterval = randomIntFrom(1000, 10000, 3);
// cleanId = setInterval(cleanTrail, cleanInterval);
// }, holdInterval);
}
}
function cleanTrail() {
let pos = lane.shift();
console.log(pos);
ctx.clearRect(0, pos[2], glyph.w, glyph.h);
if (!lane.length) {
console.log("hold", holdInterval);
clearInterval(cleanId);
holdId = setTimeout(() => {
console.clear();
console.log("new", newInterval);
cleanIndex = randomIntFrom(1, max);
cleanInterval = randomIntFrom(1000, 10000, 3);
holdInterval = randomIntFrom(1000, 10000, 3);
newId = setInterval(newTrail, newInterval);
}, holdInterval);
}
}
function randomBetween(min, max) {
return (Math.random() * (max - min) + min).toFixed(2);
}
function randomIntFrom(min, max, pos = 0) {
pos = Math.pow(10, pos);
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor((Math.random() * (max - min + 1) + min) / pos) * pos;
}
</script>
{% endblock %}