This commit is contained in:
암냥 2026-03-06 22:30:35 +09:00
commit 991bc55102
No known key found for this signature in database
4 changed files with 69 additions and 17 deletions

BIN
public/audio.opus Normal file

Binary file not shown.

BIN
public/window-nadae.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View file

@ -6,7 +6,10 @@ import ReadmeWindow from "@/components/ReadmeWindow";
import Contact from "@/components/Contact";
import DDayComponent from "@/components/dday";
export default function Page() {
export default async function Page({ searchParams }: { searchParams: Promise<{ nowindow?: string }> }) {
const params = await searchParams;
const showWindow = params.nowindow === undefined;
return (
<main className="min-h-screen w-screen overflow-y-scroll snap-y snap-mandatory relative">
<div className="max-w-3xl w-full flex flex-row h-auto mx-auto my-8 items-center justify-between lg:px-0 px-8">
@ -28,7 +31,7 @@ export default function Page() {
<Contact />
</div>
<section id="about" className="w-full snap-start snap-always flex flex-col items-center justify-center px-8 lg:px-0">
<DraggableWindow />
{showWindow && <DraggableWindow />}
<div className="max-w-3xl w-full lg:px-0 px-8">
<p><strong> </strong> .</p>
<p><strong> </strong> , .</p>

View file

@ -10,7 +10,10 @@ export default function DraggableWindow() {
const [position, setPosition] = useState({ x: 100, y: 100 });
const [isDragging, setIsDragging] = useState(false);
const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });
const [isNadaeVisible, setIsNadaeVisible] = useState(false);
const windowRef = useRef<HTMLDivElement>(null);
const audioRef = useRef<HTMLAudioElement | null>(null);
const nadaeTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const handleMouseDown = (e: React.MouseEvent) => {
setIsDragging(true);
@ -23,6 +26,26 @@ export default function DraggableWindow() {
}
};
const handleActivate = () => {
if (!audioRef.current) {
audioRef.current = new Audio('/audio.opus');
}
audioRef.current.currentTime = 0;
void audioRef.current.play();
setIsNadaeVisible(true);
if (nadaeTimeoutRef.current) {
clearTimeout(nadaeTimeoutRef.current);
}
nadaeTimeoutRef.current = setTimeout(() => {
setIsNadaeVisible(false);
nadaeTimeoutRef.current = null;
}, 1000);
};
useEffect(() => {
const handleMouseMove = (e: MouseEvent) => {
if (!isDragging) return;
@ -48,12 +71,27 @@ export default function DraggableWindow() {
};
}, [isDragging, dragOffset]);
useEffect(() => {
return () => {
audioRef.current?.pause();
audioRef.current = null;
if (nadaeTimeoutRef.current) {
clearTimeout(nadaeTimeoutRef.current);
}
};
}, []);
return (
isMobile ? (
<figure className="mb-8 w-full h-auto">
<button
type="button"
className="block w-full rounded-xl text-left"
>
<picture className="block bg-gray-100 rounded-xl aspect-3-2 overflow-hidden image-scale object-shadowed">
<Image
src="/full.webp"
src={'/full.webp'}
alt="Banner"
width={1200}
height={400}
@ -61,21 +99,21 @@ export default function DraggableWindow() {
className="object-cover object-center transition-transform duration-300 hover:scale-105"
/>
</picture>
</button>
</figure >
) : (
isVisible && (
<div
ref={windowRef}
className="fixed cursor-move select-none"
className="fixed cursor-pointer select-none"
style={{
left: `${position.x}px`,
top: `${position.y}px`,
}}
onMouseDown={handleMouseDown}
>
<div className="relative w-fit h-fit">
<Image
src="/window.webp"
src={isNadaeVisible ? '/image.png' : '/window.webp'}
alt="Draggable Window"
width={500}
height={400}
@ -83,8 +121,19 @@ export default function DraggableWindow() {
draggable={false}
/>
<button
onClick={() => setIsVisible(false)}
className="absolute top-1 right-2 w-5 h-5 cursor-pointer"
type="button"
onMouseDown={handleMouseDown}
onClick={handleActivate}
className="absolute inset-0 cursor-pointer"
aria-label="Play audio"
/>
<button
type="button"
onClick={(e) => {
e.stopPropagation();
setIsVisible(false);
}}
className="absolute top-1 right-2 z-10 w-5 h-5 cursor-pointer"
aria-label="Close window"
/>
</div>