update light effects
This commit is contained in:
parent
401f80f484
commit
da7c67734f
2 changed files with 48 additions and 7 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useRef, type CSSProperties, type MouseEvent } from "react";
|
import { useEffect, useRef, type CSSProperties, type MouseEvent } from "react";
|
||||||
|
|
||||||
import styles from "@/static/hero/flashlight.module.css";
|
import styles from "@/static/hero/flashlight.module.css";
|
||||||
|
|
||||||
|
|
@ -13,6 +13,9 @@ type FlashlightTextProps = {
|
||||||
const FlashlightText = ({ text }: FlashlightTextProps) => {
|
const FlashlightText = ({ text }: FlashlightTextProps) => {
|
||||||
const ref = useRef<HTMLSpanElement>(null);
|
const ref = useRef<HTMLSpanElement>(null);
|
||||||
|
|
||||||
|
const mouseX = useRef(-1);
|
||||||
|
const mouseY = useRef(-1);
|
||||||
|
|
||||||
const setPosition = (x: number, y: number) => {
|
const setPosition = (x: number, y: number) => {
|
||||||
const element = ref.current;
|
const element = ref.current;
|
||||||
if (!element) return;
|
if (!element) return;
|
||||||
|
|
@ -21,10 +24,40 @@ const FlashlightText = ({ text }: FlashlightTextProps) => {
|
||||||
element.style.setProperty("--fy", `${y}px`);
|
element.style.setProperty("--fy", `${y}px`);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const syncWithPointer = () => {
|
||||||
|
const element = ref.current;
|
||||||
|
if (!element) return;
|
||||||
|
|
||||||
|
const point = document.elementFromPoint(mouseX.current, mouseY.current
|
||||||
|
);
|
||||||
|
|
||||||
|
if (point && element.contains(point)) {
|
||||||
|
const rect = element.getBoundingClientRect();
|
||||||
|
setPosition(mouseX.current - rect.left, mouseY.current - rect.top);
|
||||||
|
element.classList.remove(styles.idle);
|
||||||
|
} else {
|
||||||
|
setPosition(OFFSCREEN, OFFSCREEN);
|
||||||
|
element.classList.add(styles.idle);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const onScroll = () => syncWithPointer();
|
||||||
|
|
||||||
|
window.addEventListener("scroll", onScroll, { capture: true, passive: true });
|
||||||
|
|
||||||
|
return () =>
|
||||||
|
window.removeEventListener("scroll", onScroll, { capture: true });
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
const handleMove = (e: MouseEvent<HTMLSpanElement>) => {
|
const handleMove = (e: MouseEvent<HTMLSpanElement>) => {
|
||||||
const element = ref.current;
|
const element = ref.current;
|
||||||
if (!element) return;
|
if (!element) return;
|
||||||
|
|
||||||
|
mouseX.current = e.clientX;
|
||||||
|
mouseY.current = e.clientY;
|
||||||
|
|
||||||
const rect = element.getBoundingClientRect();
|
const rect = element.getBoundingClientRect();
|
||||||
|
|
||||||
setPosition(e.clientX - rect.left, e.clientY - rect.top);
|
setPosition(e.clientX - rect.left, e.clientY - rect.top);
|
||||||
|
|
|
||||||
|
|
@ -36,14 +36,20 @@ const Cursor = () => {
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onPointerOver = (e: PointerEvent) => {
|
const isInteractive = (target: Element | null) =>
|
||||||
const target = e.target as HTMLElement | null;
|
Boolean(
|
||||||
|
target?.closest(
|
||||||
const interactive = target?.closest(
|
"a, button, [role='button'], input, select, textarea, [data-cursor-hover]"
|
||||||
"a, button, [role='button'], input, select, textarea, [data-cursor-hover]"
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
setHovering(Boolean(interactive));
|
const onPointerOver = (e: PointerEvent) => {
|
||||||
|
setHovering(isInteractive(e.target as Element | null));
|
||||||
|
};
|
||||||
|
|
||||||
|
const onScroll = () => {
|
||||||
|
const target = document.elementFromPoint(mouseX, mouseY);
|
||||||
|
setHovering(isInteractive(target));
|
||||||
};
|
};
|
||||||
|
|
||||||
const onPointerDown = () => setPressed(true);
|
const onPointerDown = () => setPressed(true);
|
||||||
|
|
@ -62,6 +68,7 @@ const Cursor = () => {
|
||||||
|
|
||||||
window.addEventListener("pointermove", onPointerMove, { passive: true });
|
window.addEventListener("pointermove", onPointerMove, { passive: true });
|
||||||
window.addEventListener("pointerover", onPointerOver, { passive: true });
|
window.addEventListener("pointerover", onPointerOver, { passive: true });
|
||||||
|
window.addEventListener("scroll", onScroll, { capture: true, passive: true });
|
||||||
window.addEventListener("pointerdown", onPointerDown);
|
window.addEventListener("pointerdown", onPointerDown);
|
||||||
window.addEventListener("pointerup", onPointerUp);
|
window.addEventListener("pointerup", onPointerUp);
|
||||||
|
|
||||||
|
|
@ -71,6 +78,7 @@ const Cursor = () => {
|
||||||
cancelAnimationFrame(raf);
|
cancelAnimationFrame(raf);
|
||||||
window.removeEventListener("pointermove", onPointerMove);
|
window.removeEventListener("pointermove", onPointerMove);
|
||||||
window.removeEventListener("pointerover", onPointerOver);
|
window.removeEventListener("pointerover", onPointerOver);
|
||||||
|
window.removeEventListener("scroll", onScroll, { capture: true });
|
||||||
window.removeEventListener("pointerdown", onPointerDown);
|
window.removeEventListener("pointerdown", onPointerDown);
|
||||||
window.removeEventListener("pointerup", onPointerUp);
|
window.removeEventListener("pointerup", onPointerUp);
|
||||||
document.documentElement.classList.remove("has-cursor");
|
document.documentElement.classList.remove("has-cursor");
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue