mcpField
S
shaders-cursor-ripples

shaders-cursor-ripples

github.com/boraoztunc设计与 UI43495 次安装11 周前更新
代码仓库

关于 shaders-cursor-ripples

shaders-cursor-ripples 是一套将 CursorRipples 着色器效果应用于页面图像的开发技能,面向在现有网页中实现指针驱动图像扭曲的开发者。它强调懒加载、静态图像回退、WebGPU 检查和减少动态效果支持。

主要功能

  1. 01在图像上应用指针涟漪扭曲
  2. 02支持 React、Vue、Svelte 和 Solid
  3. 03懒加载着色器模块
  4. 04保留可访问的静态图像回退
  5. 05处理 WebGPU 与减少动态效果

适用场景

  1. 01为页面媒体添加指针交互扭曲
  2. 02在 WebGPU 不可用时保留图像显示
  3. 03替换旧的聚光灯式图像揭示效果

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/boraoztunc/skills --skill shaders-cursor-ripples

安装后在 Claude Code 中输入/shaders-cursor-ripples确认已加载。

附带文件REFERENCES.md

详细介绍

Shaders 游标涟漪

核心约定

  1. 保留现有页面、内容和语义图像。
  2. 安装 shaders,并从当前框架的子路径导入。
  3. 通过一个 Shader 画布渲染源图像。
  4. 将 CursorRipples 放在 ImageTexture 之后,使其对该图像进行后期处理。
  5. 在根元素上保留 toneMapping="aces"。
  6. 让 Shaders 跟踪游标。移除自定义聚光坐标、径向蒙版、重复的揭示图像和指针动画循环。
  7. 在画布下方保留一张真实图像,作为无障碍加载内容和 WebGPU 回退。
  8. 在减少动态效果或不支持 WebGPU 时禁用着色器。
  9. 延迟加载着色器代码,避免增大页面的初始打包体积。

当用户只要求着色器效果时,不要照搬参考作品中的丝带、斑块、辉光、排版、布局、文案、颜色或标识。不要用 Shaders 的 Water 组件替代:CursorRipples 才是交互式图像位移效果。

编辑前检查

  • 找到真实的媒体容器、图像 URL、裁剪方式、叠加层、z-index 和现有动态效果。
  • 确认容器渲染后的宽度和高度均非零。
  • 搜索旧的揭示代码,例如 data-reveal-hover、mask-image: radial-gradient、重复图像、requestAnimationFrame 和手动指针监听器。
  • 保留无关的视差或入场动态效果,除非它们与着色器画布冲突。
  • 如果软件包可能已变更,请检查已安装的 shaders 版本和当前框架 API。

安装

npm install shaders

从 shaders/react、shaders/vue、shaders/svelte 或 shaders/solid 导入。对于 Vite 项目,绝不要将 shaders 添加到 optimizeDeps.exclude;其 CommonJS 依赖需要 Vite 预打包。通常无需添加 optimizeDeps 配置项。

这是一个付费的非 OSS 依赖。 shaders 软件包附带专有的 “Shader Effects License Agreement”,且 npm 显示 license: None——只有付费后 才能获得授权。它不是 MIT/Apache 许可证,不能视为免费的传递依赖。任何商业发布前 都必须确认许可;如果项目无法引入付费依赖,应优先选择 webgl-laser 或手动编写着色器。

必需的组件组合

保留以下组件顺序和值:

<Shader toneMapping="aces">
  <ImageTexture url={imageUrl} objectFit="cover" />
  <CursorRipples decay={7.3} radius={0.6} />
</Shader>

请先以此作为基线,再调整 intensity、chromaticSplit 或 edges。除非用户明确要求生成参考作品中的艺术效果,否则不要添加 SolidColor、Blob、Form3D、GaborNoise、Glow 或其他生成器。

对于 React,请复制并改造 assets/react/cursor-ripple-shader.tsx 和 assets/react/cursor-ripple-media.css。

客户端与回退模式

仅在浏览器确认支持 WebGPU 且允许动态效果后挂载着色器:

const CursorRippleShader = lazy(() => import("./cursor-ripple-shader"));

const [shaderEnabled, setShaderEnabled] = useState(false);
const [shaderReady, setShaderReady] = useState(false);

useEffect(() => {
  const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)");

  const sync = () => {
    const enabled = "gpu" in navigator && !reduceMotion.matches;
    setShaderEnabled(enabled);
    if (!enabled) setShaderReady(false);
  };

  sync();
  reduceMotion.addEventListener("change", sync);
  return () => reduceMotion.removeEventListener("change", sync);
}, []);

在容器中保留语义图像,然后叠加延迟加载的着色器:

<figure className="cursor-ripple-media">
  <img
    className="cursor-ripple-media__fallback"
    src={imageUrl}
    alt={meaningfulAlt}
    width={width}
    height={height}
  />

  {shaderEnabled ? (
    <Suspense fallback={null}>
      <CursorRippleShader
        imageUrl={imageUrl}
        ready={shaderReady}
        onReady={() => setShaderReady(true)}
      />
    </Suspense>
  ) : null}
</figure>

对于 Next.js,也可以使用 ssr: false 的动态导入。不要在着色器调用 onReady 前隐藏回退内容;如果 WebGPU 初始化失败,页面必须保持清晰易读且内容完整。

图层规则

  • 为媒体容器设置 position: relative、明确的尺寸、overflow: hidden 和 isolation: isolate。
  • 将回退内容的 z-index 设为 0,将画布的 z-index 设为 1。
  • 使用 position: absolute; inset: 0; width: 100%; height: 100% 填满容器。
  • 将着色器图层设为 pointer-events: none;Shaders 会进行全局监听,并使用画布边界换算指针坐标。
  • 将着色器容器标记为 aria-hidden="true";无障碍名称由回退图像提供。
  • 将文案、链接和控件置于画布上方,确保效果不会拦截交互。
  • 保持回退内容与 ImageTexture 使用相同的裁剪方式。对于全幅媒体,使用 objectFit="cover"。

移除失效的聚光灯模式

删除旧实现,不要将其隐藏:

  • 第二张揭示图片;
  • 径向 mask-image 和自定义揭示变量;
  • 与指针位置相关的烟雾或模糊叠加层;
  • 组件本地的 requestAnimationFrame 指针缓动;
  • 仅为手电筒效果添加的 pointerenter、pointermove、pointerleave 和尺寸调整记录逻辑;
  • 引用已弃用揭示层的粗略指针规则。

同时保留两套系统会导致坐标漂移、增加 GPU 负载,并使回退行为变得混乱。

性能与动态效果

  • 仅在 WebGPU 检查通过后,延迟加载着色器模块。
  • 媒体面板中只保留一个着色器画布。
  • 使用库的 onReady 回调实现短暂的不透明度切换。
  • 不需要遥测时使用 disableTelemetry。
  • 不要为画布尺寸添加动画;如需视差效果,应为稳定的父级元素添加动画。
  • 在 prefers-reduced-motion: reduce 时禁用或卸载着色器。
  • 确保触控布局在使用静态图片时仍可用;不要将关键信息放在效果内部。

验证

运行项目的 lint、生产构建、渲染测试和 git diff --check。然后在真实浏览器中验证:

  1. 确认恰好存在一个 canvas[data-renderer="shaders"]。
  2. 确认着色器进入就绪类,且回退图片仍然存在。
  3. 在媒体区域的多个位置扫动指针。扭曲效果必须沿指针路径移动,不得出现脱离的圆圈。
  4. 确认链接和控件仍可点击。
  5. 确认没有控制台错误或警告。
  6. 确认 WebGPU 不可用或启用减少动态效果时,静态图片仍然显示。
  7. 确认旧的 data-reveal-hover 或径向遮罩层不存在。
  8. 画布初始化后,检查移动端和桌面端的裁切效果。

故障诊断

  • **画布存在但内容空白:**确认包装元素的尺寸非零,且图片 URL 同源或可通过 CORS 读取。
  • **图片已渲染但没有波纹:**将 CursorRipples 保留在 ImageTexture 之后;它需要子元素/输入表面。
  • **波纹位置偏移:**移除手动指针变换,并检查经过变换的祖先元素是否改变了画布边界。
  • **页面在 SSR 期间崩溃:**将着色器移入仅客户端运行的延迟加载组件。
  • **图片加载时闪烁:**保留回退图片,并且仅通过 onReady 淡入着色器。
  • **初始包体积变大:**确认 Shaders 导入仅位于延迟加载模块中。
  • **效果挡住按钮:**确保画布对指针事件透明,并将控件放在更高的堆叠层级。

交接

报告受影响的媒体、Shaders 包版本、回退行为、减少动态效果时的行为、构建/测试结果,以及实时交互验证情况。明确区分本地已就绪的效果与已发布的部署。

评论

支持 Markdown