这是一款用 React 19 + Motion + Tailwind CSS 打造的垂直画廊:八张风景图片被叠加了 `grayscale-80 contrast-170 brightness-80` 灰调滤镜和一层 `#f1a1a3` 的浅粉混合层,视觉像旧胶片;上下箭头切换当前图,居中项正常显示,上方图沿 X 轴 +30° 后仰、下方图 -30° 前倾,非当前项透明度 30% 且缩放至 85%。整段过渡由 Motion 的 spring `bounce: 0.3` 驱动,一按一顿的 3D 感明显。到达首尾会自动灰显箭头,边界干净不出错。
这款垂直画廊的四个亮点
3D 倾斜靠 Tailwind 的 `rotate-x-30` / `-rotate-x-30` 直接写,无需自己算 transform——搭配 `perspective-distant transform-3d` 让画面有可信的透视深度。
轮播位移是 spring 动画:`animate: { y: activeIndex * -HEIGHT + EDGE }`,配合 `type: "spring", bounce: 0.3` 得到一段带弹性的自然过渡,比 linear/ease 有生命力。
灰调滤镜叠混合层做出统一色调:`grayscale-80 contrast-170 brightness-80` 把图片彻底压成黑白高对比,再用 `bg-[#f1a1a3] mix-blend-screen` 覆一层浅粉,整个画廊自带调色板。
响应式:桌面端图片长宽比 `aspect-[3]`(超宽横条),移动端 `aspect-[16/9]` 更方形,同一个组件在不同设备上视觉都成立。
Motion 3D + 滤镜的三个门道
其一,Motion 的 spring 动画默认时长依赖 stiffness 和 damping;本模板只写了 `bounce: 0.3`,Motion 会自动推导合理的 stiffness/damping,避免手工调参。其二,`perspective-distant transform-3d` 必须挂在 rotate-x 元素的父容器上,否则子元素的 3D 变换会 flatten——这是 Tailwind 3D 类的常见坑,源码中均有注释。其三,浅粉混合层用 `mix-blend-screen` 而非 `overlay`,可以让暗部保留深灰不被冲淡;换成 `multiply` 则会让整体更暗更接近棕褐。
换图片或调节奏
八张图片路径在 `data` 数组(约第 5 行),换成自己的图片即可;数量任意增减不影响布局,`HEIGHT = 200`(每项高度)与 `EDGE = 40`(首尾余量)决定动画位移。想去掉灰调滤镜,删掉 `.grayscale-80 contrast-170 brightness-80` 和覆盖层 div。想让 3D 倾斜更夸张,把 `rotate-x-30` 改成 `rotate-x-45`;想改成横向轮播,把 `flex-col` 换成 `flex-row`,animate 改成 x 位移,倾斜改为 rotate-y。
浏览器兼容性:需支持 ES Modules 与 CSS 3D transforms;React 19 与 Motion 从 esm.sh CDN 加载,Tailwind CSS 4 通过浏览器版即时编译。生产环境建议本地打包。详细运行方法请参见压缩包内的帮助文档。
常见问题
不加灰调滤镜可以吗
可以。把 `img` 的 className 里 `grayscale-80 contrast-170 brightness-80` 删掉、把覆盖层 div 一起删掉即可恢复原图色彩。
能自动播放而不用点箭头
能。加 useEffect + setInterval,`setActiveIndex(prev => (prev + 1) % data.length)`,到最后一张自动回到第一张;清理函数记得 clearInterval。
怎么让当前图放大而不是原尺寸
去掉 `activeIndex !== index ? "scale-85 opacity-30" : ""` 里的 scale-85,改成当前项 scale-105、其他项 scale-90,即可让高亮项凸起。
移动端图片比例不合适
Tailwind 用 `md:aspect-[3]` 区分了桌面移动比例,自己按需改 `aspect-[16/9]` 到别的(如 `aspect-square`)即可。
适合放在哪些页面
适合摄影作品集、艺术展览页、复古主题页、时装品牌 Landing Page、任何需要「灰调统一色调 + 3D 感切换」的画廊。下载源码后可作为独立组件嵌入 React 项目。