Compare commits

..

2 commits

Author SHA1 Message Date
6161920612 prune projects, rework nav and contact
- homepage: replace Projects nav link with Code (-> Forgejo profile)
- about: drop Projects section, fix dangling CTA
- contact: add Email (mailto) + GitHub, remove broken direct-message link
2026-08-12 21:23:34 +04:00
74471a21d2 Smooth fractal background animation 2026-07-24 13:06:42 +04:00
9 changed files with 53 additions and 41 deletions

View file

@ -113,7 +113,7 @@
}
</style>
<link rel="preload" href="/routes/root/dist-strips.bin?v=1" as="fetch" crossorigin />
<script defer src="/routes/root/fractal-gl.js?v=12"></script>
<script defer src="/routes/root/fractal-gl.js?v=13"></script>
</head>
<body>
<canvas id="fractal-canvas"></canvas>
@ -123,23 +123,7 @@
<p>Software engineer cum neural network wrangler.</p>
<p>Technical interests include systems engineering, distributed compute, physical simulation, and applied machine learning infrastructure.</p>
<h2>Projects</h2>
<ul class="project-list">
<li>
<strong><a href="/projects/swactor">swactor</a></strong>
Toolkit for orchestrating somewhat-unreliable heterogeneous GPU nodes over WAN links.
</li>
<li>
<strong><a href="/projects/airfrans-neural-cfd-surrogate">AirfRANS / neural CFD surrogate</a></strong>
Machine learning as simulation: neural CFD surrogates, model scaling, and solver-grounded validation.
</li>
<li>
<strong><a href="/projects/cstat-yoke">cstat and yoke</a></strong>
Code as data: statistical structure, LLM coding behavior, and agent harnesses.
</li>
</ul>
<p>If any of these interest you, please <a href="/contact">contact me</a>. I love to talk shop.</p>
<p>If any of this interests you, please <a href="/contact">contact me</a>. I love to talk shop.</p>
</article>
<nav class="back-link">

View file

@ -118,7 +118,7 @@
}
</style>
<link rel="preload" href="/routes/root/dist-strips.bin?v=1" as="fetch" crossorigin />
<script defer src="/routes/root/fractal-gl.js?v=12"></script>
<script defer src="/routes/root/fractal-gl.js?v=13"></script>
</head>
<body>
<canvas id="fractal-canvas"></canvas>
@ -127,8 +127,8 @@
<div class="glass-card">
<h2>Contact</h2>
<ul class="contact-list">
<li><a href="mailto:">Email me</a></li>
<li><a href="/contact/message">Direct message</a></li>
<li><a href="mailto:zachery.a.shores.chmielewksi@gmail.com">Email</a></li>
<li><a href="https://github.com/zacheryasc">GitHub</a></li>
</ul>
</div>

View file

@ -280,7 +280,7 @@
}
</script>
<link rel="preload" href="/routes/root/dist-strips.bin?v=1" as="fetch" crossorigin />
<script defer src="/routes/root/fractal-gl.js?v=12"></script>
<script defer src="/routes/root/fractal-gl.js?v=13"></script>
</head>
<body>
<canvas id="fractal-canvas"></canvas>

View file

@ -25,7 +25,7 @@
.back-link a:hover { color: rgba(255, 255, 255, 0.7); }
</style>
<link rel="preload" href="/routes/root/dist-strips.bin?v=1" as="fetch" crossorigin />
<script defer src="/routes/root/fractal-gl.js?v=12"></script>
<script defer src="/routes/root/fractal-gl.js?v=13"></script>
</head>
<body>
<canvas id="fractal-canvas"></canvas>

View file

@ -19,7 +19,7 @@
.back-link a:hover { color: rgba(255, 255, 255, 0.7); }
</style>
<link rel="preload" href="/routes/root/dist-strips.bin?v=1" as="fetch" crossorigin />
<script defer src="/routes/root/fractal-gl.js?v=12"></script>
<script defer src="/routes/root/fractal-gl.js?v=13"></script>
</head>
<body>
<canvas id="fractal-canvas"></canvas>

View file

@ -120,7 +120,7 @@
}
</style>
<link rel="preload" href="/routes/root/dist-strips.bin?v=1" as="fetch" crossorigin />
<script defer src="/routes/root/fractal-gl.js?v=12"></script>
<script defer src="/routes/root/fractal-gl.js?v=13"></script>
</head>
<body>
<canvas id="fractal-canvas"></canvas>

View file

@ -51,7 +51,7 @@
.back-link a:hover { color: rgba(255, 255, 255, 0.7); }
</style>
<link rel="preload" href="/routes/root/dist-strips.bin?v=1" as="fetch" crossorigin />
<script defer src="/routes/root/fractal-gl.js?v=12"></script>
<script defer src="/routes/root/fractal-gl.js?v=13"></script>
</head>
<body>
<canvas id="fractal-canvas"></canvas>

View file

@ -16,6 +16,21 @@ var FIELD_URL = '/routes/root/dist-strips.bin?v=1'; // streamed WebP bands (bump
var DIST_URL = '/routes/root/dist.png'; // monolithic source (Canvas2D fallback)
var DARK_HEX = '#060a10'; // backdrop / unloaded tone
// The old palette cycle advanced quickly enough to look shimmery on some displays.
// Keep the camera drift slow, cap redraws below display refresh, and pause real work
// while the tab is hidden. The field still streams at full speed; only presentation
// frames are rate-limited.
var MOTION_SPEED = 0.045;
var COLOR_CYCLE_SPEED = 4.2;
var WEBGL_TARGET_FPS = 30;
var CANVAS_TARGET_FPS = 24;
var DITHER_STRENGTH = 0.45;
function _prefersReducedMotion() {
return window.matchMedia &&
window.matchMedia('(prefers-reduced-motion: reduce)').matches;
}
function initFractal(canvasId) {
console.log('[fractal-gl] initFractal:', canvasId);
@ -190,7 +205,7 @@ var FIELD_FRAG_GLSL = [
'void main() {',
' vec2 uv = gl_FragCoord.xy / u_resolution;',
' float aspect = u_resolution.x / u_resolution.y;',
' float t = u_time * 0.12;',
' float t = u_time * 0.045;',
' float maxH = 1.0 / max(aspect, 1.0);',
' float zoomFrac = 0.65 + 0.15 * sin(t * 0.4);',
' float halfH = maxH * zoomFrac * 0.5;',
@ -210,8 +225,8 @@ var FIELD_FRAG_GLSL = [
' float v = texture2D(u_dist, vec2(sx, fv)).r * 255.0;',
' float ditherMix = clamp((v - 180.0) / 60.0, 0.0, 1.0);',
' float noise = fract(sin(dot(gl_FragCoord.xy, vec2(12.9898, 78.233))) * 43758.5453) - 0.5;',
' v += noise * 1.2 * ditherMix;',
' float offset = u_time * 10.8;',
' v += noise * 0.45 * ditherMix;',
' float offset = u_time * 4.2;',
' vec3 color = calmBand(v - offset);',
' gl_FragColor = vec4(mix(DARK, color, m), 1.0);',
'}'
@ -341,8 +356,16 @@ function initWebGL(canvas, gl) {
window.addEventListener('resize', resize);
var startTime = performance.now();
function frame() {
var t = (performance.now() - startTime) * 0.001;
var reducedMotion = _prefersReducedMotion();
var targetFrameMs = 1000 / WEBGL_TARGET_FPS;
var lastFrameTime = 0;
function frame(now) {
requestAnimationFrame(frame);
if (document.hidden) return;
if (now - lastFrameTime < targetFrameMs) return;
lastFrameTime = now;
var t = reducedMotion ? 0 : (now - startTime) * 0.001;
// Ease the displayed extent toward the loaded extent for a smooth bloom.
// On a repeat visit (cached field) snap instead of replaying the intro.
var ease = revealed ? 1.0 : 0.12;
@ -353,7 +376,6 @@ function initWebGL(canvas, gl) {
gl.uniform1f(uV0, dispV0);
gl.uniform1f(uV1, dispV1);
gl.drawArrays(gl.TRIANGLES, 0, 3);
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
console.log('[fractal-gl] WebGL loop started');
@ -409,6 +431,9 @@ function initCanvas2D(canvas) {
var out32 = new Uint32Array(imgOut.data.buffer);
var lastW = canvas.width, lastH = canvas.height;
var startTime = performance.now();
var reducedMotion = _prefersReducedMotion();
var targetFrameMs = 1000 / CANVAS_TARGET_FPS;
var lastFrameTime = 0;
var faded = false;
// 4x4 Bayer matrix, recentered to ±0.6 source units. Only applied where
@ -416,15 +441,19 @@ function initCanvas2D(canvas) {
var BAYER = new Float32Array([0,8,2,10, 12,4,14,6, 3,11,1,9, 15,7,13,5]);
for (var bi = 0; bi < 16; bi++) BAYER[bi] = (BAYER[bi] - 7.5) * 0.6 / 7.5;
function frame() {
function frame(now) {
requestAnimationFrame(frame);
if (document.hidden) return;
if (now - lastFrameTime < targetFrameMs) return;
lastFrameTime = now;
var W = canvas.width, H = canvas.height;
if (W !== lastW || H !== lastH) {
imgOut = ctx2d.createImageData(W, H);
out32 = new Uint32Array(imgOut.data.buffer);
lastW = W; lastH = H;
}
var elapsed = (performance.now() - startTime) * 0.001;
var t = elapsed * 0.12;
var elapsed = reducedMotion ? 0 : (now - startTime) * 0.001;
var t = elapsed * MOTION_SPEED;
var aspect = W / H;
var maxH = 1.0 / Math.max(aspect, 1.0);
var zoomFrac = 0.65 + 0.15 * Math.sin(t * 0.4);
@ -437,8 +466,8 @@ function initCanvas2D(canvas) {
var y0 = (cy - halfH) * SH;
var dxs = (2 * halfW) / W * SW;
var dys = (2 * halfH) / H * SH;
// offset in 1024-entry space (4x granularity) — same cycle period (~24 s) as before
var offsetHD = (elapsed * 10.8 * 4) | 0;
// offset in 1024-entry space (4x granularity), deliberately slow to avoid shimmer.
var offsetHD = (elapsed * COLOR_CYCLE_SPEED * 4) | 0;
var SW1 = SW - 1, SH1 = SH - 1;
var idx = 0;
@ -470,7 +499,7 @@ function initCanvas2D(canvas) {
// Selective dither: only the outer smooth region (v 180→240 ramps in).
if (v > 180) {
var mix = v >= 240 ? 1 : (v - 180) / 60;
v += BAYER[(y & 3) * 4 + (x & 3)] * 1.6 * mix;
v += BAYER[(y & 3) * 4 + (x & 3)] * DITHER_STRENGTH * mix;
}
// Multiply by 4 to index into 1024-entry palette, then wrap.
out32[idx++] = palette32[(((v * 4) | 0) - offsetHD) & 1023];
@ -481,7 +510,6 @@ function initCanvas2D(canvas) {
}
ctx2d.putImageData(imgOut, 0, 0);
if (!faded) { faded = true; canvas.style.opacity = '1'; }
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
console.log('[fractal-gl] Canvas2D loop started; internal',

View file

@ -101,7 +101,7 @@
}
</style>
<link rel="preload" href="/routes/root/dist-strips.bin?v=1" as="fetch" crossorigin />
<script defer src="/routes/root/fractal-gl.js?v=12"></script>
<script defer src="/routes/root/fractal-gl.js?v=13"></script>
</head>
<body>
<canvas id="fractal-canvas"></canvas>
@ -115,7 +115,7 @@
<nav>
<div class="nav-links">
<a href="./about">About</a>
<a href="./projects">Projects</a>
<a href="./code/zacheryasc">Code</a>
<a href="./contact">Contact</a>
</div>
</nav>