6bit.ch/html/js/hdr.js
root 39752c845a modified: index.html
new file:   js/art.js
	new file:   js/hdr.js
	new file:   js/hearts.js
	new file:   js/helpers.js
	new file:   js/particles.js
	new file:   js/qlpycon.js
	new file:   js/qlpyconbanner.js
	new file:   js/snek.js
	new file:   js/sparks.js
	new file:   js/stars.js
	modified:   slamp.html
	modified:   style.css
2026-06-14 14:08:52 +02:00

191 lines
5.8 KiB
JavaScript

(function () {
var c = document.getElementById('hdr');
var ctx = c.getContext('2d');
var W, H, mouse = { x: -999, y: -999 };
var glitchX = 0, glitchY = 0;
var glitchXTarget = 0, glitchYTarget = 0;
var COLS = ['#00ffff', '#ff00ff', '#ffffff'];
/*const ARTS = [
{
lines: [
''
]
},
]*/
var validARTS = ARTS.filter(function(a) { return a.lines.length > 0; });
var ART = validARTS[Math.floor(Math.random() * validARTS.length)].lines;
var fontSize, LINE_H, ART_TOP, PAD_BOTTOM;
function resize() {
W = c.width = c.offsetWidth;
var maxChars = ART.reduce(function(max, l) { return Math.max(max, l.length); }, 0);
fontSize = Math.min(16, (W * 0.95) / maxChars * 1.6);
LINE_H = fontSize * 1;
ART_TOP = LINE_H * 2;
PAD_BOTTOM = LINE_H * 2;
H = c.height = Math.ceil(ART_TOP + ART.length * LINE_H + PAD_BOTTOM);
buildScanlines();
}
var scanlines = document.createElement('canvas');
function buildScanlines() {
var headerH = ART_TOP + ART.length * LINE_H + PAD_BOTTOM;
scanlines.width = 1;
scanlines.height = headerH;
var sctx = scanlines.getContext('2d');
sctx.clearRect(0, 0, 1, headerH);
for (var sy = 0; sy < headerH; sy += 3) {
sctx.fillStyle = '#101010';
sctx.fillRect(0, sy, 1, 1);
}
}
window.addEventListener('resize', function () { resize(); });
window.addEventListener('DOMContentLoaded', function() {
resize();
requestAnimationFrame(loop);
});
var moveTimer;
var glitchTarget = 0;
var lastX = 0, lastY = 0;
document.addEventListener('mousemove', function (e) {
var nx = e.clientX;
var ny = e.clientY;
var dx = nx - lastX;
var dy = ny - lastY;
mouse.x = nx;
mouse.y = ny;
lastX = nx;
lastY = ny;
glitchXTarget = Math.min(1, Math.abs(dx) / 16);
glitchYTarget = Math.min(1, Math.abs(dy) / 16);
clearTimeout(moveTimer);
moveTimer = setTimeout(function () { glitchXTarget = 0; glitchYTarget = 0; }, 100);
});
document.addEventListener('mouseleave', function () {
mouse.x = -999;
glitchXTarget = 0;
glitchYTarget = 0;
});
document.addEventListener('touchmove', function (e) {
var touch = e.touches[0];
var nx = touch.clientX;
var ny = touch.clientY;
var dx = nx - lastX;
var dy = ny - lastY;
mouse.x = nx;
mouse.y = ny;
lastX = nx;
lastY = ny;
glitchXTarget = Math.min(1, Math.abs(dx) / 16);
glitchYTarget = Math.min(1, Math.abs(dy) / 16);
clearTimeout(moveTimer);
moveTimer = setTimeout(function () { glitchXTarget = 0; glitchYTarget = 0; }, 100);
}, { passive: true });
document.addEventListener('touchend', function () {
glitchXTarget = 0;
glitchYTarget = 0;
});
/* ── text ── */
function drawText(ox, oy, col, alpha) {
ctx.save();
ctx.globalAlpha = alpha;
ctx.fillStyle = col;
ctx.font = fontSize + 'px deltarune';
ctx.textAlign = 'center';
ctx.textBaseline = 'top';
for (var i = 0; i < ART.length; i++) {
ctx.fillText(ART[i], W / 2 + ox, ART_TOP + i * LINE_H + oy, W * 0.95);
}
ctx.restore();
}
/* ── proximity glow on letters ── */
function drawGlow() {
var cx = W / 2;
var cy = ART_TOP + (ART.length * LINE_H) / 2;
var dx = mouse.x - cx;
var dy = mouse.y - cy;
var dist = Math.sqrt(dx * dx + dy * dy);
var r = Math.max(0, 1 - dist / 220);
var idle = (1 - r) * (Math.sin(t * 0.008) * 0.5 + 0.5) * 0.25;
if (idle > 0) {
ctx.save();
ctx.globalAlpha = idle * 0.15;
ctx.fillStyle = '#00ffff';
ctx.font = fontSize + 'px deltarune';
ctx.textAlign = 'center';
ctx.textBaseline = 'top';
for (var d = 3; d <= 9; d += 3) {
for (var i = 0; i < ART.length; i++) {
ctx.fillText(ART[i], W / 2 + d, ART_TOP + i * LINE_H, W * 0.95);
ctx.fillText(ART[i], W / 2 - d, ART_TOP + i * LINE_H, W * 0.95);
ctx.fillText(ART[i], W / 2, ART_TOP + i * LINE_H + d, W * 0.95);
ctx.fillText(ART[i], W / 2, ART_TOP + i * LINE_H - d, W * 0.95);
}
}
ctx.restore();
}
if (r <= 0) return;
ctx.save();
ctx.globalAlpha = r * 0.3;
ctx.fillStyle = '#ff00ff';
ctx.font = fontSize + 'px deltarune';
ctx.textAlign = 'center';
ctx.textBaseline = 'top';
for (var d = 3; d <= 9; d += 3) {
for (var i = 0; i < ART.length; i++) {
ctx.fillText(ART[i], W / 2 + d, ART_TOP + i * LINE_H, W * 0.95);
ctx.fillText(ART[i], W / 2 - d, ART_TOP + i * LINE_H, W * 0.95);
}
}
ctx.restore();
}
/* ── main loop ── */
var t = 0, lastFrame = 0;
function loop(ts) {
requestAnimationFrame(loop);
if (ts - lastFrame < 42) return;
lastFrame = ts;
t++;
ctx.clearRect(0, 0, W, H);
var headerH = ART_TOP + ART.length * LINE_H + PAD_BOTTOM;
var splitX = glitchX * 16;
var splitY = glitchY * 16;
drawText(-splitX, -splitY, '#00ffff', 0.7);
drawText( splitX, splitY, '#ff00ff', 0.7);
drawText(0, 0, '#ffffff', 0.9);
drawGlow();
/* scanline overlay */
var headerH = ART_TOP + ART.length * LINE_H + PAD_BOTTOM;
ctx.drawImage(scanlines, 0, 0, W, headerH);
glitchX += (glitchXTarget - glitchX) * 0.04;
glitchY += (glitchYTarget - glitchY) * 0.04;
}
window.rerollArt = function() {
ART = validARTS[Math.floor(Math.random() * validARTS.length)].lines;
resize();
};
})();