Skip to content

Commit 322b5ab

Browse files
committed
clockwise direc
1 parent 3175fbf commit 322b5ab

1 file changed

Lines changed: 30 additions & 4 deletions

File tree

src/components/EscherBackground.tsx

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { useEffect, useRef, useState } from "react";
55

66
export default function EscherBackground() {
77
const INITIAL_RADIUS_DESKTOP_PX = 0;
8-
const INITIAL_RADIUS_MOBILE_PX = 150;
8+
const INITIAL_RADIUS_MOBILE_PX = 0;
99

1010
const canvasRef = useRef<HTMLCanvasElement>(null);
1111
const containerRef = useRef<HTMLDivElement>(null);
@@ -159,6 +159,8 @@ export default function EscherBackground() {
159159
let time = 0;
160160
let lastTime = performance.now();
161161
let isVisible = true;
162+
let mouseX = -9999;
163+
let mouseY = -9999;
162164

163165
const targetFps = isMobile ? 24 : 30;
164166
const fpsInterval = 1000 / targetFps;
@@ -183,13 +185,20 @@ export default function EscherBackground() {
183185
uniform float u_gap;
184186
uniform float u_baseRadius;
185187
uniform float u_zoom;
188+
uniform vec2 u_mouse;
186189
187190
void main() {
188191
vec2 pos = vec2(gl_FragCoord.x, u_resolution.y - gl_FragCoord.y);
189192
vec2 cellCenter = floor(pos / u_gap + 0.5) * u_gap;
190193
float dist = distance(pos, cellCenter);
191194
192-
if (dist > u_baseRadius + 0.5) {
195+
// Cursor hover: scale dots near the mouse
196+
float mouseDist = distance(pos, u_mouse);
197+
float hoverRadius = 120.0;
198+
float hoverScale = 1.0 + 1.2 * smoothstep(hoverRadius, 0.0, mouseDist);
199+
float effectiveRadius = u_baseRadius * hoverScale;
200+
201+
if (dist > effectiveRadius + 0.5) {
193202
gl_FragColor = vec4(0.0);
194203
return;
195204
}
@@ -214,7 +223,7 @@ export default function EscherBackground() {
214223
vec2 screenCenter = u_resolution / 2.0;
215224
vec2 diff = cellCenter - screenCenter;
216225
217-
float angle = u_time * 0.002;
226+
float angle = -u_time * 0.002;
218227
float s = sin(angle);
219228
float c = cos(angle);
220229
@@ -224,6 +233,9 @@ export default function EscherBackground() {
224233
);
225234
226235
vec2 rotatedCenter = screenCenter + rotatedDiff;
236+
237+
// Add a gentle hovering effect (bobbing up and down)
238+
rotatedCenter.y += sin(u_time * 0.003) * 20.0;
227239
228240
float u = (rotatedCenter.x - offsetX) / drawWidth;
229241
float v = (rotatedCenter.y - offsetY) / drawHeight;
@@ -238,7 +250,7 @@ export default function EscherBackground() {
238250
}
239251
240252
float sizeFactor = (255.0 - brightness) / 255.0;
241-
float dotSize = sizeFactor * u_baseRadius;
253+
float dotSize = sizeFactor * effectiveRadius;
242254
243255
if (brightness < 240.0 && dotSize > 0.5) {
244256
float alpha = 1.0 - smoothstep(dotSize - 0.5, dotSize + 0.5, dist);
@@ -298,10 +310,12 @@ export default function EscherBackground() {
298310
const uGap = gl.getUniformLocation(program, "u_gap");
299311
const uBaseRadius = gl.getUniformLocation(program, "u_baseRadius");
300312
const uZoom = gl.getUniformLocation(program, "u_zoom");
313+
const uMouse = gl.getUniformLocation(program, "u_mouse");
301314

302315
gl.uniform1f(uGap, gap);
303316
gl.uniform1f(uBaseRadius, baseRadius);
304317
gl.uniform1f(uZoom, iphoneCenterZoom);
318+
gl.uniform2f(uMouse, -9999, -9999);
305319

306320
const texture = gl.createTexture();
307321
let isTextureLoaded = false;
@@ -361,6 +375,10 @@ export default function EscherBackground() {
361375
if (uTime) {
362376
gl.uniform1f(uTime, time);
363377
}
378+
if (uMouse) {
379+
const dpr = Math.min(window.devicePixelRatio || 1, isMobile ? (isIPhone ? 2.25 : 1.6) : 2.0);
380+
gl.uniform2f(uMouse, mouseX * dpr, mouseY * dpr);
381+
}
364382
gl.drawArrays(gl.TRIANGLES, 0, 6);
365383
};
366384

@@ -391,15 +409,23 @@ export default function EscherBackground() {
391409
}
392410
};
393411

412+
const handleMouseMove = (e: MouseEvent) => {
413+
const rect = canvas.getBoundingClientRect();
414+
mouseX = e.clientX - rect.left;
415+
mouseY = e.clientY - rect.top;
416+
};
417+
394418
observer.observe(container);
395419
window.addEventListener("resize", handleResize);
396420
window.visualViewport?.addEventListener("resize", handleResize);
421+
document.addEventListener("mousemove", handleMouseMove);
397422
document.addEventListener("visibilitychange", handleVisibilityChange);
398423

399424
return () => {
400425
observer.disconnect();
401426
window.removeEventListener("resize", handleResize);
402427
window.visualViewport?.removeEventListener("resize", handleResize);
428+
document.removeEventListener("mousemove", handleMouseMove);
403429
document.removeEventListener("visibilitychange", handleVisibilityChange);
404430
cancelAnimationFrame(animationFrameId);
405431
gl.deleteProgram(program);

0 commit comments

Comments
 (0)