30天JS挑战(第十六天)----鼠标拖影效果

第十六天挑战(鼠标拖影效果)

地址:https://javascript30.com/

所有内容均上传至gitee,答案不唯一,仅代表本人思路

中文详解:https://github.com/soyaine/JavaScript30

该详解是Soyaine及其团队 整理编撰的,是对源代码的详解强烈推荐大家观看学习!!!

本人gitee:https://gitee.com/thats-all-right-ha-ha/30-days---js-challenge

效果

  • 样式分析

    • 组件本体页面内居中(黑色),其他效果是组件的文本阴影
  • 逻辑分析

    • 阴影效果以组件中心点作为基准点向四周移动

    • 阴影效果随着鼠标移动进行移动,对位的阴影效果向相反方向移动

本人代码及思路分析

仅提供布局及逻辑代码

结构:

html 复制代码
<div class="hero">
  <h1 contenteditable>🔥WOAH!</h1>
</div>

逻辑:

js 复制代码
//设定横纵向初始值
let transverse = 0;
let direction = 0
//获取鼠标偏移量
let iniX = 0
let iniY = 0
const title = document.querySelector('h1')
document.addEventListener('mousemove', (e) => {
  iniX = e.clientX - title.offsetLeft - title.offsetWidth / 2
  iniY = e.clientY - title.offsetTop - title.offsetHeight / 2
  direction = iniY / 2
  transverse = iniX / 2
  title.style.textShadow = `${transverse}px ${direction}px 0 rgba(255, 0, 255, 0.7), ${-transverse}px ${-direction}px 0 rgba(0, 255, 255, 0.7), ${-direction}px ${transverse}px 0 rgba(0, 255, 0, 0.7) , ${direction}px ${-transverse}px 0 rgba(0, 0, 255, 0.7)`
})

分析:

  • **整体思路:**这里监听了整个dom对象的鼠标移动事件,以鼠标移动距离为偏移量,给中心组件动态添加textShadow样式

  • 具体实现:

    • 首先选定需要监听和修改的元素
    • 由于这里监听的是根Dom,根Dom的位移基准点在页面最左上角,获取组件中心点的位置作为偏移量,将clientX的起始点初始化至组件的中心
    • 由于clientX是只读属性,所以这里的修改只是通过增加偏移量实现的伪修改
    • 将修改后的clientX和clientY的值进行处理,作为组件阴影效果移动的值。
    • 添加textShadow样式
  • 弊端分析(与官方方法对比):

    • 性能问题 :监听了整个文档的mousemove事件,当鼠标移动时会频繁地触发事件处理函数,可能导致性能问题,尤其是在页面元素较多或复杂的情况下。
    • 硬编码:阴影效果的计算是硬编码在JavaScript中的,如果标题文字的样式或布局发生变化,需要手动调整计算阴影的逻辑,不够灵活。
    • 重复计算:每次鼠标移动都重新计算阴影效果的位置,即使鼠标移动的距离很小,也会触发整个计算和样式更新的过程,这样的重复计算可能会影响性能。

官方代码

官方代码仅代表该案例原作者思路,不唯一

结构

html 复制代码
<div class="hero">
  <h1 contenteditable>🔥WOAH!</h1>
</div>

逻辑

js 复制代码
const hero = document.querySelector('.hero');
const text = hero.querySelector('h1');
const walk = 500; // 500px
function shadow(e) {
  const { offsetWidth: width, offsetHeight: height } = hero;
  let { offsetX: x, offsetY: y } = e;
  if (this !== e.target) {
    x = x + e.target.offsetLeft;
    y = y + e.target.offsetTop;
  }
  const xWalk = Math.round((x / width * walk) - (walk / 2));
  const yWalk = Math.round((y / height * walk) - (walk / 2));
  text.style.textShadow = `
      ${xWalk}px ${yWalk}px 0 rgba(255,0,255,0.7),
      ${xWalk * -1}px ${yWalk}px 0 rgba(0,255,255,0.7),
      ${yWalk}px ${xWalk * -1}px 0 rgba(0,255,0,0.7),
      ${yWalk * -1}px ${xWalk}px 0 rgba(0,0,255,0.7)
    `;
}
hero.addEventListener('mousemove', shadow);

分析

仅代表本人对该代码的分析

建议直接去看Soyaine的中文详解

  • **整体思路:**整体思路与上述保持一致

  • 具体实现:

    • 这里先获取了组件的高度和宽度,其次获取了鼠标的偏移量
    • 第二步判断了鼠标事件是否是在hero元素中,如果鼠标在组件内移动,则切换偏移量的计算方式
    • 偏移量的计算方式:
      • 通过比值的方式,在文字组件中映射鼠标移动的距离,通过这个比值和最大范围数进行相乘并减最大范围的一半,作为移动的距离
  • 优点:

    • 更高效的事件处理 :代码只监听了.hero元素的mousemove事件,而不是整个文档,这样可以减少事件处理函数的触发次数,提高性能。
    • 更精简的阴影计算逻辑:通过使用解构赋值和简洁的计算,将阴影效果的计算逻辑简化了,使代码更易读、更易维护。
    • 更灵活的阴影效果 :阴影效果的移动距离通过walk变量控制,可以通过修改这个变量来调整阴影的移动范围,增加了代码的灵活性。

相关推荐
Ajiang28247353041 小时前
对于C++中stack和queue的认识以及priority_queue的模拟实现
开发语言·c++
ggdpzhk1 小时前
VUE:基于MVVN的前端js框架
前端·javascript·vue.js
幽兰的天空1 小时前
Python 中的模式匹配:深入了解 match 语句
开发语言·python
小曲曲2 小时前
接口上传视频和oss直传视频到阿里云组件
javascript·阿里云·音视频
学不会•3 小时前
css数据不固定情况下,循环加不同背景颜色
前端·javascript·html
EasyNTS4 小时前
H.264/H.265播放器EasyPlayer.js视频流媒体播放器关于websocket1006的异常断连
javascript·h.265·h.264
Theodore_10224 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
活宝小娜6 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点6 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow6 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js