11"use client"
22
33import { useRef , useState } from "react"
4- import { motion , useMotionTemplate , useSpring } from "motion/react"
54import { clsx } from "clsx"
65import Image from "next-image-export-optimizer"
76import type { StaticImageData } from "next/image"
87
98import { Marquee } from "@/app/conf/_design-system/marquee"
10- import ZoomInIcon from "../../pixelarticons/zoom-in.svg?svgr"
11- import ZoomOutIcon from "../../pixelarticons/zoom-out.svg?svgr"
129
1310import { imagesByYear } from "./images"
1411
@@ -20,8 +17,6 @@ export interface GalleryStripProps extends React.HTMLAttributes<HTMLElement> {}
2017export function GalleryStrip ( { className, ...rest } : GalleryStripProps ) {
2118 const [ selectedYear , setSelectedYear ] = useState < Year > ( "2024" )
2219
23- const previousZoomedImage = useRef < HTMLElement | null > ( null )
24-
2520 return (
2621 < section
2722 role = "presentation"
@@ -52,73 +47,22 @@ export function GalleryStrip({ className, ...rest }: GalleryStripProps) {
5247 speedOnHover = { 15 }
5348 drag
5449 reverse
55- className = "!overflow-visible"
50+ className = "cursor-[var(--cursor-grabbing,grab)] !overflow-visible"
5651 >
5752 { imagesByYear [ selectedYear ] . map ( ( image , i ) => {
5853 const key = `${ selectedYear } -${ i } `
5954
60- return (
61- < GalleryStripImage
62- key = { key }
63- image = { image }
64- previousZoomedImage = { previousZoomedImage }
65- />
66- )
55+ return < GalleryStripImage key = { key } image = { image } />
6756 } ) }
6857 </ Marquee >
6958 </ div >
7059 </ section >
7160 )
7261}
7362
74- function GalleryStripImage ( {
75- image,
76- previousZoomedImage,
77- } : {
78- image : StaticImageData
79- previousZoomedImage : React . MutableRefObject < HTMLElement | null >
80- } ) {
81- const [ isZoomed , setIsZoomed ] = useState ( false )
82- const scale = useSpring ( 1 )
83- const transform = useMotionTemplate `translate3d(0,0,var(--translate-z,-16px)) scale(${ scale } )`
84-
85- // if we set scale in useEffect the UI glitches
86- const zoomIn = ( current : HTMLElement | null ) => {
87- if ( previousZoomedImage . current ) {
88- previousZoomedImage . current . style . zIndex = "0"
89- previousZoomedImage . current . style . setProperty ( "--translate-z" , "0px" )
90- }
91-
92- if ( current ) {
93- current . style . zIndex = "2"
94- current . style . setProperty ( "--translate-z" , "16px" )
95- }
96-
97- previousZoomedImage . current = current
98-
99- scale . set ( 1.665625 )
100- setIsZoomed ( true )
101- }
102-
103- const zoomOut = ( ) => {
104- scale . set ( 1 )
105- setIsZoomed ( false )
106- }
107-
63+ function GalleryStripImage ( { image } : { image : StaticImageData } ) {
10864 return (
109- < motion . div
110- role = "presentation"
111- className = "relative md:px-2"
112- style = { { transform } }
113- onPointerOut = { event => {
114- const target = event . currentTarget
115- const relatedTarget = event . relatedTarget as Node | null
116-
117- if ( ! relatedTarget || ! target . contains ( relatedTarget ) ) {
118- zoomOut ( )
119- }
120- } }
121- >
65+ < div role = "presentation" className = "relative md:px-2" >
12266 < Image
12367 src = { image }
12468 alt = ""
@@ -127,19 +71,6 @@ function GalleryStripImage({
12771 height = { 533 }
12872 className = "pointer-events-none aspect-[799/533] h-[320px] w-auto object-cover"
12973 />
130- < button
131- type = "button"
132- className = "absolute right-2 top-0 z-[1] bg-neu-50/10 p-4"
133- onClick = { event => {
134- isZoomed ? zoomOut ( ) : zoomIn ( event . currentTarget . parentElement )
135- } }
136- >
137- { isZoomed ? (
138- < ZoomOutIcon className = "size-12" />
139- ) : (
140- < ZoomInIcon className = "size-12" />
141- ) }
142- </ button >
143- </ motion . div >
74+ </ div >
14475 )
14576}
0 commit comments