如何利用 Alpine.js 准确获取鼠标像素位置并实现实时动态径向模糊特效?

2026-04-29 08:362阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1035个文字,预计阅读时间需要5分钟。

如何利用 Alpine.js 准确获取鼠标像素位置并实现实时动态径向模糊特效?

原文:

在 Alpine.js 项目中实现“以鼠标为原点的径向模糊”(如 bg-[radial-gradient(circle_at_#{$mouseX}_#{$mouseY},...)])的关键,是让模板能直接消费形如 '127px' 的字符串值——这要求我们不仅捕获整数坐标,还需实时拼接单位,并确保跨浏览器兼容(尤其需兼容旧版 IE 对 pageX/pageY 的缺失支持)。

✅ 推荐实现方案:Alpine 数据函数 + 兼容性增强的 mousemove 监听

以下是一个生产就绪的 Alpine 数据定义(建议保存为 blur.js):

export default () => ({ mouseX: 0, mouseY: 0, mouseXAsPx: '0px', mouseYAsPx: '0px', init() { // 自动同步数值 → 带单位字符串 this.$watch('mouseX', (val) => (this.mouseXAsPx = `${val}px`)); this.$watch('mouseY', (val) => (this.mouseYAsPx = `${val}px`)); // 高兼容性 mousemove 处理器(支持 IE9+) const handleMouseMove = (e) => { const event = e || window.event; let { pageX, pageY } = event; // 兜底计算:当 pageX/pageY 不可用时,手动推导(参考 jQuery 源码逻辑) if (pageX == null) { const doc = document.documentElement; const body = document.body; const clientX = event.clientX; const clientY = event.clientY; const scrollLeft = window.pageXOffset || doc.scrollLeft || body.scrollLeft; const scrollTop = window.pageYOffset || doc.scrollTop || body.scrollTop; const clientLeft = doc.clientLeft || body.clientLeft || 0; const clientTop = doc.clientTop || body.clientTop || 0; pageX = clientX + scrollLeft - clientLeft; pageY = clientY + scrollTop - clientTop; } this.mouseX = Math.round(pageX); this.mouseY = Math.round(pageY); this.applyBlur(); }; // 绑定全局监听(注意:若仅需限定于某 div 内,应改用该元素的 addEventListener) document.addEventListener('mousemove', handleMouseMove); // 清理:避免内存泄漏(Alpine v3.13+ 支持自动 cleanup,但显式解绑更稳妥) this.$nextTick(() => { this.$el.addEventListener('mouseleave', () => { // 可选:鼠标离开时重置或暂停更新 }); }); }, applyBlur() { // 此处可触发自定义逻辑,例如: // - 触发 $dispatch('mouse-move', { x: this.mouseX, y: this.mouseY }) // - 更新 CSS 自定义属性:document.documentElement.style.setProperty('--mouse-x', this.mouseXAsPx) // - 或直接用于内联样式(见下方模板示例) } });

? 在 HTML 中使用(配合 Tailwind 动态类)

<!-- 引入 Alpine & 数据 --> <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script> <script type="module"> import Blur from './blur.js'; window.Alpine = await import('https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.esm.min.js'); window.Alpine.data('blur', Blur); window.Alpine.start(); </script> <!-- 应用容器:使用 x-bind 动态生成 radial-gradient --> <div x-data="blur" class="relative w-full h-96 bg-gray-100 overflow-hidden rounded-xl" :style="`background-image: radial-gradient(circle at ${mouseXAsPx} ${mouseYAsPx}, rgba(255,255,255,0.8) 0%, transparent 70%)`" > <!-- 可选:显示坐标调试信息 --> <div class="absolute top-4 left-4 bg-black/70 text-white px-3 py-1 text-sm rounded"> X: <span x-text="mouseX"></span>px, Y: <span x-text="mouseY"></span>px </div> </div>

⚠️ 注意事项与最佳实践

  • 作用域控制:上述代码监听 document 全局移动。若只需在特定 <div> 内生效,请将 document.addEventListener(...) 替换为 this.$el.addEventListener('mousemove', ...),并确保该元素设置了 position: relative(以支撑绝对定位子元素或 radial-gradient 坐标基准)。
  • 性能优化:高频 mousemove 可能触发重绘压力。如遇卡顿,可在 handleMouseMove 内添加 requestAnimationFrame 节流:

    let isQueued = false; const rafHandler = () => { this.mouseX = ...; this.mouseY = ...; this.applyBlur(); isQueued = false; }; const throttled = () => { if (!isQueued) { requestAnimationFrame(rafHandler); isQueued = true; } }; // 然后在事件中调用 throttled()

  • Tailwind 动态类限制:radial-gradient 中的 at 位置不支持直接插值(如 bg-[radial-gradient(circle_at_{{mouseXAsPx}}_{{mouseYAsPx}},...)])。因此推荐使用 :style 绑定 CSS background-image,这是最可靠的方式。
  • 移动端适配:mousemove 在触摸设备上不触发。如需全平台支持,应补充 touchmove 事件处理(获取 touches[0].clientX/clientY 并转换为 page 坐标)。

通过以上实现,你即可获得稳定、兼容、响应式的鼠标坐标数据流,并无缝驱动视觉反馈——无论是径向模糊、悬停高亮,还是交互式粒子效果,都拥有了精准的空间锚点。

标签:JS

本文共计1035个文字,预计阅读时间需要5分钟。

如何利用 Alpine.js 准确获取鼠标像素位置并实现实时动态径向模糊特效?

原文:

在 Alpine.js 项目中实现“以鼠标为原点的径向模糊”(如 bg-[radial-gradient(circle_at_#{$mouseX}_#{$mouseY},...)])的关键,是让模板能直接消费形如 '127px' 的字符串值——这要求我们不仅捕获整数坐标,还需实时拼接单位,并确保跨浏览器兼容(尤其需兼容旧版 IE 对 pageX/pageY 的缺失支持)。

✅ 推荐实现方案:Alpine 数据函数 + 兼容性增强的 mousemove 监听

以下是一个生产就绪的 Alpine 数据定义(建议保存为 blur.js):

export default () => ({ mouseX: 0, mouseY: 0, mouseXAsPx: '0px', mouseYAsPx: '0px', init() { // 自动同步数值 → 带单位字符串 this.$watch('mouseX', (val) => (this.mouseXAsPx = `${val}px`)); this.$watch('mouseY', (val) => (this.mouseYAsPx = `${val}px`)); // 高兼容性 mousemove 处理器(支持 IE9+) const handleMouseMove = (e) => { const event = e || window.event; let { pageX, pageY } = event; // 兜底计算:当 pageX/pageY 不可用时,手动推导(参考 jQuery 源码逻辑) if (pageX == null) { const doc = document.documentElement; const body = document.body; const clientX = event.clientX; const clientY = event.clientY; const scrollLeft = window.pageXOffset || doc.scrollLeft || body.scrollLeft; const scrollTop = window.pageYOffset || doc.scrollTop || body.scrollTop; const clientLeft = doc.clientLeft || body.clientLeft || 0; const clientTop = doc.clientTop || body.clientTop || 0; pageX = clientX + scrollLeft - clientLeft; pageY = clientY + scrollTop - clientTop; } this.mouseX = Math.round(pageX); this.mouseY = Math.round(pageY); this.applyBlur(); }; // 绑定全局监听(注意:若仅需限定于某 div 内,应改用该元素的 addEventListener) document.addEventListener('mousemove', handleMouseMove); // 清理:避免内存泄漏(Alpine v3.13+ 支持自动 cleanup,但显式解绑更稳妥) this.$nextTick(() => { this.$el.addEventListener('mouseleave', () => { // 可选:鼠标离开时重置或暂停更新 }); }); }, applyBlur() { // 此处可触发自定义逻辑,例如: // - 触发 $dispatch('mouse-move', { x: this.mouseX, y: this.mouseY }) // - 更新 CSS 自定义属性:document.documentElement.style.setProperty('--mouse-x', this.mouseXAsPx) // - 或直接用于内联样式(见下方模板示例) } });

? 在 HTML 中使用(配合 Tailwind 动态类)

<!-- 引入 Alpine & 数据 --> <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script> <script type="module"> import Blur from './blur.js'; window.Alpine = await import('https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.esm.min.js'); window.Alpine.data('blur', Blur); window.Alpine.start(); </script> <!-- 应用容器:使用 x-bind 动态生成 radial-gradient --> <div x-data="blur" class="relative w-full h-96 bg-gray-100 overflow-hidden rounded-xl" :style="`background-image: radial-gradient(circle at ${mouseXAsPx} ${mouseYAsPx}, rgba(255,255,255,0.8) 0%, transparent 70%)`" > <!-- 可选:显示坐标调试信息 --> <div class="absolute top-4 left-4 bg-black/70 text-white px-3 py-1 text-sm rounded"> X: <span x-text="mouseX"></span>px, Y: <span x-text="mouseY"></span>px </div> </div>

⚠️ 注意事项与最佳实践

  • 作用域控制:上述代码监听 document 全局移动。若只需在特定 <div> 内生效,请将 document.addEventListener(...) 替换为 this.$el.addEventListener('mousemove', ...),并确保该元素设置了 position: relative(以支撑绝对定位子元素或 radial-gradient 坐标基准)。
  • 性能优化:高频 mousemove 可能触发重绘压力。如遇卡顿,可在 handleMouseMove 内添加 requestAnimationFrame 节流:

    let isQueued = false; const rafHandler = () => { this.mouseX = ...; this.mouseY = ...; this.applyBlur(); isQueued = false; }; const throttled = () => { if (!isQueued) { requestAnimationFrame(rafHandler); isQueued = true; } }; // 然后在事件中调用 throttled()

  • Tailwind 动态类限制:radial-gradient 中的 at 位置不支持直接插值(如 bg-[radial-gradient(circle_at_{{mouseXAsPx}}_{{mouseYAsPx}},...)])。因此推荐使用 :style 绑定 CSS background-image,这是最可靠的方式。
  • 移动端适配:mousemove 在触摸设备上不触发。如需全平台支持,应补充 touchmove 事件处理(获取 touches[0].clientX/clientY 并转换为 page 坐标)。

通过以上实现,你即可获得稳定、兼容、响应式的鼠标坐标数据流,并无缝驱动视觉反馈——无论是径向模糊、悬停高亮,还是交互式粒子效果,都拥有了精准的空间锚点。

标签:JS