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变量控制,可以通过修改这个变量来调整阴影的移动范围,增加了代码的灵活性。

相关推荐
fmdpenny25 分钟前
Vue3初学之商品的增,删,改功能
开发语言·javascript·vue.js
小美的打工日记38 分钟前
ES6+新特性,var、let 和 const 的区别
前端·javascript·es6
涛ing40 分钟前
21. C语言 `typedef`:类型重命名
linux·c语言·开发语言·c++·vscode·算法·visual studio
等一场春雨1 小时前
Java设计模式 十四 行为型模式 (Behavioral Patterns)
java·开发语言·设计模式
涔溪1 小时前
有哪些常见的 Vue 错误?
前端·javascript·vue.js
程序猿online1 小时前
前端jquery 实现文本框输入出现自动补全提示功能
前端·javascript·jquery
黄金小码农1 小时前
C语言二级 2025/1/20 周一
c语言·开发语言·算法
萧若岚1 小时前
Elixir语言的Web开发
开发语言·后端·golang
wave_sky1 小时前
解决使用code命令时的bash: code: command not found问题
开发语言·bash
水银嘻嘻2 小时前
【Mac】Python相关知识经验
开发语言·python·macos