Communitygithub.com

Scroll Zoom Reveal - 滚动变焦揭示特效

为网站添加电影级滚动效果:滚动时固定全屏场景,然后镜头拉远,显示场景在笔记本电脑/设备屏幕中运行的效果。包含OLED像素场光标交互背景。

Scroll Zoom Reveal - 滚动变焦揭示特效 是什么?

该技能提供了一个即插即用、无需依赖的滚动特效库,包含两个核心效果:(1) 滚动变焦揭示 - 固定全屏场景触发拉远镜头,将场景嵌入设备屏幕(笔记本电脑、显示器或平板),随后文字淡入,并支持标签切换的淡入淡出画廊;(2) OLED像素场 - 鼠标反应式RGB子像素背景,产生发光、流动、变色轨迹,点击可产生涟漪。 此技能在无依赖的Vanilla JS + CSS + WebGL基础上实现,兼容纯HTML、React、Next.js、Vue、Astro等主流框架。通过固定的HTML结构(section.zr[data-zoom-reveal])控制滚动长度,利用CSS自定义属性主题化(--zr-bg、--zr-fg、--zr-accent等)。用法简单:复制assets目录中的文件,在HTML中引入CSS和JS,按指定class结构构建场景即可。支持图片、视频(逐帧关键帧编码以实现平滑搜索)作为场景媒体。 核心价值在于无需任何第三方库即可实现Apple风格的产品展示效果,适用于着陆页、产品页、作品集、游戏/3D/硬件网站等场景。代码精心优化了性能:动画仅在元素可见时运行,背景标签页暂停,支持prefers-reduced-motion,并在React/Next.js中提供useEffect集成示例。

兼容平台~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/MaybeIceloveU2/scroll-zoom-reveal/tree/HEAD

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

预览

来自技能 README

Scroll Zoom Reveal - 滚动变焦揭示特效 preview

文档

Scroll Zoom Reveal - 滚动变焦揭示特效 是做什么的?

一个即插即用、无依赖的滚动效果:

  1. 固定全屏场景:标题覆盖在全屏暗化场景上。
  2. 推拉镜头:场景轻微稳定后,“摄像机”向后拉远。场景显示在笔记本电脑屏幕上(边框和底座随之出现)。
  3. 应用揭示:编辑器面板(工具栏、大纲、属性、时间轴)滑入,场景缩小到其视口面板中。
  4. 下方文字淡入(data-zr-fade),然后是带滑动药丸切换的标签淡入淡出画廊。

所有即用文件位于本文件旁的assets/目录中:

文件用途
assets/zoom-reveal.css所有样式(.zr上的主题令牌)
assets/zoom-reveal.js组件 + 淡入 + 画廊。暴露window.ZoomReveal,自动初始化[data-zoom-reveal] / [data-zr-gallery] / [data-zr-fade]
assets/oled-field.js可选。光标反应式OLED子像素场(window.OledField,自动初始化[data-zr-oled])。样式在zoom-reveal.css中
assets/placeholder-scenes.js可选。在canvas上程序化绘制原始占位艺术(ZRScenes.drawCity,ZRScenes.drawCanyon),直到有真实图像
assets/demo.html完整可用页面。从此标记开始。

如何在网站上使用

  1. 将assets复制到项目中(例如public/zoom-reveal/或src/vendor/zoom-reveal/)。仅在没有真实作品时复制placeholder-scenes.js。
  2. **阅读assets/demo.html**并复制<section class="zr" data-zoom-reveal>…</section>块(如果需要画廊块也一并复制)。保持类结构完全一致:
section.zr[data-zoom-reveal]          ← 滚动长度在此定义 (--zr-length)
  .zr-sticky                          ← 固定100vh舞台
    .zr-glow                          (可选环境光晕)
    .zr-device                        ← 由JS缩放
      .zr-lid > .zr-display
        .zr-viewport > .zr-media > img | video | canvas   ← 您的场景
        .zr-chrome > .zr-panel.zr-toolbar / .zr-left / .zr-right / .zr-bottom  (可选应用UI)
      .zr-base                        (笔记本电脑底座;如果是显示器/平板则删除)
    .zr-scrim + header.zr-intro       ← 场景上的标题,先淡出
    .zr-caption                       ← 小字说明,最后淡入
  1. 在<head>中加载zoom-reveal.css,在<body>末尾加载zoom-reveal.js。
  2. 替换媒体:将演示canvas替换为真实场景:
    • 图片:<img src="scene.avif" alt="" decoding="async">。导出时至少为视口大小 × DPR(2560–3200像素宽)。效果从图片铺满整个屏幕开始。
    • 滚动擦洗视频:<video data-zr-scrub muted playsinline preload="auto" src="scene.mp4"></video>。JS将滚动进度映射到currentTime。编码时每帧设为关键帧以确保平滑搜索:ffmpeg -i in.mov -c:v libx264 -g 1 -crf 22 -an -movflags +faststart scene.mp4。
  3. 重写所有文字(简介语、标题、说明、面板标签、文件名、画廊标签)以匹配网站。切勿使用演示的虚构文本“Orbit / Forge”。
  4. 通过.zr上的令牌进行主题化:--zr-bg、--zr-fg、--zr-muted、--zr-accent、--zr-length(滚动距离,默认360vh)。

选项

在属性中传递JSON,例如data-zoom-reveal='{"maxWidth":1000,"viewport":{"top":0,"right":0,"bottom":0,"left":0}}',或在JS中构造:new ZoomReveal(el, options)。

选项默认值含义
maxWidth1180最终显示最大宽度(px)
widthRatio / heightRatio0.82 / 0.64最终显示大小相对于视口
aspect0.625显示高度÷宽度(16:10)。手机≈2.16,超宽屏≈0.42
overscan1.04显示起始处超出视口的距离(隐藏边框)
dolly1.14媒体的初始内部缩放;稳定到1
lift0.035设备在结束时抬升的量
timeline见JSintro、dolly、zoom、chrome、caption的[start,end]进度窗口
viewport{top:6.5,right:21,bottom:22,left:15}应用UI内场景面板的最终内边距(显示区域的百分比)。**全部设为0并删除.zr-chrome**可实现纯“场景→设备屏幕”拉远,无应用UI
onProgress—fn(p)回调,进度0..1

事件:section会派发zr:resize,包含{width, height, finalWidth},即媒体实际布局的像素大小。可用于调整canvas大小或选择图片源。

React / Next.js

全局导入CSS。从标记中移除data-zoom-reveal,手动构造以绑定组件生命周期(Next.js中需使用'use client'):

useEffect(() => {
  import('./zoom-reveal/zoom-reveal.js').then(() => {  // 注册 window.ZoomReveal
    const zr = new window.ZoomReveal(ref.current, { maxWidth: 1100 });
    const gal = galRef.current && new window.ZoomReveal.Gallery(galRef.current);
    window.ZoomReveal.initFades();
    cleanup = () => zr.destroy();
  });
  let cleanup = () => {};
  return () => cleanup();
}, []);

将class转换为className,style="--v:78%"转换为style={{'--v':'78%'}}。

OLED像素场(光标悬停效果)

一个铺满全屏的微小RGB子像素条背景,暗淡发光。移动鼠标会扰动一个小型流体模拟。沿路径的像素亮起、生长并从紫色过渡到青色再到石灰绿再到暖白色,然后光晕沿鼠标方向漂移、扩散并淡出。点击或触摸产生涟漪。鼠标空闲时(以及触摸屏上),缓慢的“幽灵光标”维持效果。渲染使用WebGL1片段着色器,模拟使用小型CPU网格,仅在section可见时运行。没有WebGL时回退为CSS聚光灯。

放在规格/数据块、英雄区或CTA条后面。任何元素均可:添加class="zr-oled" data-zr-oled,内部放置内容,加载zoom-reveal.css + oled-field.js。组件会自动插入canvas。参见assets/demo.html中的“OLED像素场”块。

<section class="zr-oled" data-zr-oled='{"cell":7}'>
  <div class="your-content">…数据 / 标题…</div>
</section>
<script src="oled-field.js"></script>
选项默认值含义
cell6每个像素的CSS px(3个子像素条)。5–9合适;移动端可用更大值提升性能
radius2.4画笔半径(以cell为单位)
strength0.55光标增加的光量。默认值故意低调;1更醒目
decay0.94每帧衰减;越高则拖尾越长(0.92短…0.97长)
flow0.55光晕沿光标方向漂移的距离
diffusion0.35光晕扩散速度
base0.09未点亮网格的亮度
palette['#5a3cff','#1fd6ff','#b6ff4a','#fff4d8']4种颜色,低→高能量。匹配品牌,例如暖色['#ff3c5a','#ff9a1f','#ffe14a','#fff8e8']
ambient / ripplestrue空闲时幽灵光标 / 点击涟漪

如需更醒目的效果(接近展示效果),使用{"radius":3.2,"strength":1,"decay":0.962,"flow":0.9}。在文字密集的section后保持默认的微妙值。

API:const f = new OledField(el, opts),f.pulse(clientX, clientY)(从代码触发涟漪),f.destroy()(在React清理中调用)。为场上的文本添加柔和的深色text-shadow,以便在明亮轨迹上保持可读。

注意事项(在完成前检查)

  • 粘性定位失效:如果.zr的任何祖先元素具有overflow: hidden/auto/clip或transform,粘性定位会失效。如果必须隐藏水平溢出,请在body上使用overflow-x: clip。
  • 不要将.zr包裹在会转换页面的平滑滚动库中(如Locomotive v4等)。Lenis可以。
  • 设备布局时放大然后缩小,因此媒体保持清晰。不要在.zr-device内使用固定px大小:请使用em(1em = 显示宽度的1%)。
  • 减少动画处理:section取消固定并显示最终状态;画廊停止自动播放;OLED场保持对光标反应,但移除幽灵光标和涟漪。
  • 背景标签页中动画暂停(requestAnimationFrame停止)。在浏览器面板中测试OLED场时,请保持页面可见,否则看起来会冻结。
  • 在约500px宽度以下,笔记本电脑显得很小。考虑使用{"widthRatio":0.92}或将aspect匹配手机框架的宽高比。
  • 在桌面端和移动端宽度下,从顶部到底部缓慢滚动测试。确认标题在拉远前淡出,开始时没有边框显示,且说明不与底座重叠。
  • 使用原创或授权作品和文字。此技能重现的是运动技术;不要复制其他品牌的图片、产品渲染或文字。

相关技能