利用JS判断鼠标移入元素的方向


Posted in Javascript onDecember 11, 2016

利用JS判断鼠标移入元素的方向

最终效果

这里的关键主要是判断鼠标是从哪个方向进入和离开的

$("li").on("mouseenter mouseleave",function(e) {
   var w = this.offsetWidth;
   var h = this.offsetHeight;
   var x = e.pageX - this.getBoundingClientRect().left - w/2;
   var y = e.pageY - this.getBoundingClientRect().top - h/2;
   var direction = Math.round((((Math.atan2(y, x) * 180 / Math.PI) + 180) / 90) + 3) % 4; //direction的值为“0,1,2,3”分别对应着“上,右,下,左”
   var eventType = e.type;
   var res = Math.atan2(y, x) / (Math.PI / 180) + 180 ;
   $('.line').css('transform','rotate('+ res +'deg)');
   // console.log(((Math.atan2(y, x) * 180 / Math.PI) + 180));
   // console.log(Math.round((Math.atan2(y, x) / (Math.PI / 180) + 180) / 90 + 3) % 4);
   var dirName = new Array('上方','右侧','下方','左侧');
    $('.res').text(res + 'deg');
   if(eventType == 'mouseenter'){
    $('.res').text(dirName[direction]+'进入');
    animationIn(direction);
   }else{
    $('.res').text(dirName[direction]+'离开');
    animationOut(direction);
   }
  });

上面代码的重点主要是在direction的值的计算

Math.atan2(y,x) 返回-PI 到 PI 之间的值(负180°到正180°),是从 X 轴正向逆时针旋转到点 (x,y) 时经过的角度 这里的结果是一个弧度值。那如何把这个值转换为角度呢

我们可以先算出一个角度的弧度值(Math.PI / 180) ,然后用上面计算出来的结果除以一度的弧度值

利用JS判断鼠标移入元素的方向

从上图可以看出,当鼠标从右边进入的时候,角度是在-45°~45°之间的 底部是45~135 左边135~180&-180~-135 顶部是 -135 ~ -45

因为上面计算出来的结果不符合我们的习惯,并且负值在计算的时候会影响正确性,现在我们给这个结果加上180 让角度范围变成我们习惯的0~360°。当加上180之后 0°的位置就在左边的中间了

利用JS判断鼠标移入元素的方向

0度的位置

所以现在的范围变成了

0~44 & 360~315 左边

45~134 上边

135~224 右边

225~314 下边

我们再继续转换,现在我们把算出来的角度除以90,然后四舍五入,可以使得45°为分界线

上边算出来的结果为1

利用JS判断鼠标移入元素的方向

上边

右边算出来的结果为2

利用JS判断鼠标移入元素的方向

右边

下边算出来的结果为3

利用JS判断鼠标移入元素的方向

下边

左边算出来的结果有两种 0~44肯定是为0的 315~360 为4

利用JS判断鼠标移入元素的方向

左边

现在算出来的结果一共有5个值(左边2个,其他三个面各一个)。下面我们再精简一下结果,我们给每次的结果都加上3,然后和4取余

左边加3之后就是3和7,然后取余后为3

上边加3之后为4,取余后为0

右边加3为5,取余为1

下边加3为6,取余为2

我们最终的结果就是 0->上边 1->右边 2->下边 3->左边 然后我们通过控制left和top就可以实现上面的效果了

<!DOCTYPE html>
<html lang="en">
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style type="text/css">
   * {
    padding: 0;
    margin: 0;
   }
    
   html,
   body {
    width: 100%;
    height: 100%;
   }
    
   ul {
    list-style: none;
    position: relative;
    width: 600px;
    width: 100%;
   }
    
   ul> li {
    margin: 50px auto;
    position: relative;
    width: 300px;
    height: 300px;
    background-color: black;
    overflow: hidden;
   }
    
   ul> li .bg {
    position: absolute;
    width: 300px;
    height: 300px;
    left: -100%;
    top: 0;
    background-color: red;
    text-align: center;
    line-height: 300px;
    color: blue;
    font-size: 150px;
   }
    
   .line {
    position: absolute;
    width: 50%;
    height: 1px;
    background: red;
    right: 0;
    top: 50%;
    transition: all .3s;
    transform-origin: left;
   }
    
   .res {
    text-align: center;
   }
  </style>
 </head>
 
 <body>
  <ul>
   <li>
    <div class="bg">
     SB
    </div>
   </li>
  </ul>
  <div class="res"></div>
  <script src="js/jquery-3.1.1.js"></script>
  <script>
   $("li").on("mouseenter mouseleave", function(e) {
    var $bg = $(this).find('.bg');
    var w = this.offsetWidth; //获取元素宽度
    var h = this.offsetHeight; //获取元素高度
    var toTop = this.getBoundingClientRect().top + document.body.scrollTop; //兼容滚动条
    var x = e.pageX - this.getBoundingClientRect().left - w / 2; //获取当前鼠标的x轴位置(相对于这个li的中心点)
    var y = e.pageY - toTop - h / 2; ////获取当前鼠标的y轴位置(相对于这个li的中心点)
    var direction = Math.round((((Math.atan2(y, x) * 180 / Math.PI) + 180) / 90) + 3) % 4; //direction的值为“0,1,2,3”分别对应着“上,右,下,左”
    var eventType = e.type;
    var res = Math.atan2(y, x) / (Math.PI / 180) + 180;
    $('.line').css('transform', 'rotate(' + res + 'deg)');
    var dirName = new Array('上方', '右侧', '下方', '左侧');
    if(eventType == 'mouseenter') {
     $('.res').text(dirName[direction] + '进入');
     animationIn(direction, $bg);
    } else {
     $('.res').text(dirName[direction] + '离开');
     animationOut(direction, $bg);
    }
   });
   function animationIn(direction, ele) {
    switch(direction) {
     case 0:
      ele.css({
       left: 0,
       top: '-100%'
      }).animate({
       top: 0
      }, 300);
      break;
     case 1:
      ele.css({
       left: '100%',
       top: 0
      }).animate({
       left: 0
      }, 300);
      break;
     case 2:
      ele.css({
       left: 0,
       top: '100%'
      }).animate({
       top: 0
      }, 300);
      break;
     case 3:
      ele.css({
       left: '-100%',
       top: 0
      }).animate({
       left: 0
      }, 300);
      break;
    }
   }
   function animationOut(direction, ele) {
    switch(direction) {
     case 0:
      ele.animate({
       top: '-100%'
      }, 300);
      break;
     case 1:
      ele.animate({
       left: '100%'
      }, 300);
      break;
     case 2:
      ele.animate({
       top: '100%'
      }, 300);
      break;
     case 3:
      ele.animate({
       left: '-100%'
      }, 300);
      break;
    }
   }
  </script>
 </body>
</html>

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
Dojo之路:如何利用Dojo实现Drag and Drop效果
Apr 10 Javascript
对于this和$(this)的个人理解
Sep 08 Javascript
网站内容禁止复制和粘贴、另存为的js代码
Feb 26 Javascript
dreamweaver 8实现Jquery自动提示
Dec 04 Javascript
loading动画特效小结
Jan 22 Javascript
jQuery插件FusionCharts绘制的2D帕累托图效果示例【附demo源码】
Mar 28 jQuery
详解JavaScript数组过滤相同元素的5种方法
May 23 Javascript
Vue 按键修饰符处理事件的方法
May 04 Javascript
vue的toast弹窗组件实例详解
May 14 Javascript
JavaScript捕捉事件和阻止冒泡事件实例分析
Aug 03 Javascript
vue项目添加多页面配置的步骤详解
May 22 Javascript
Vue + Elementui实现多标签页共存的方法
Jun 12 Javascript
实现JavaScript高性能的数据存储
Dec 11 #Javascript
探索Javascript中this的奥秘
Dec 11 #Javascript
实例浅析js的this
Dec 11 #Javascript
解析js如何获取css样式
Dec 11 #Javascript
BootStrap轮播HTML代码(推荐)
Dec 10 #Javascript
JQuery.validationEngine表单验证插件(推荐)
Dec 10 #Javascript
JS产生随机数的用法小结
Dec 10 #Javascript
You might like
基于mysql的bbs设计(五)
2006/10/09 PHP
php获取远程图片并下载保存到本地的方法分析
2016/10/08 PHP
实例讲解通过​PHP创建数据库
2019/01/20 PHP
php的命名空间与自动加载实现方法
2019/08/25 PHP
JavaScript 学习技巧
2010/02/17 Javascript
js验证模型自我实现的具体方法
2013/06/21 Javascript
理解javascript回调函数
2014/12/28 Javascript
js操作滚动条事件实例
2015/01/29 Javascript
javascript实现checkbox全选的代码
2015/04/30 Javascript
JavaScript中有关一个数组中最大值和最小值及它们的下表的输出的解决办法
2016/07/01 Javascript
AngularJS 中使用Swiper制作滚动图不能滑动的解决方法
2016/11/15 Javascript
详解Angular2表单-模板驱动的表单(Template-Driven Forms)
2017/08/04 Javascript
详谈js对url进行编码和解码(三种方式的区别)
2017/08/16 Javascript
vue click.stop阻止点击事件继续传播的方法
2018/09/04 Javascript
Vue cli3 库模式搭建组件库并发布到 npm的流程
2018/10/12 Javascript
Vue CL3 配置路径别名详解
2019/05/30 Javascript
JavaScript实现简单随机点名器
2019/11/21 Javascript
浅谈Vue.use到底是什么鬼
2020/01/21 Javascript
JS判断数组是否包含某元素实现方法汇总
2020/06/24 Javascript
Python第三方库xlrd/xlwt的安装与读写Excel表格
2017/01/21 Python
Python爬虫DOTA排行榜爬取实例(分享)
2017/06/13 Python
socket + select 完成伪并发操作的实例
2017/08/15 Python
Python反射和内置方法重写操作详解
2018/08/27 Python
python 实现检验33品种数据是否是正态分布
2019/12/09 Python
Python Tornado批量上传图片并显示功能
2020/03/26 Python
python基于win32api实现键盘输入
2020/12/09 Python
路德维希•贝克(LUDWIG BECK)中文官网:德国大型美妆百货
2020/09/19 全球购物
介绍一下Ruby的特点
2013/01/20 面试题
前台文员岗位职责
2013/12/28 职场文书
应用艺术专业个人的自我评价
2014/01/03 职场文书
关于环保的建议书400字
2014/03/12 职场文书
2014年党的群众路线教育实践活动总结
2014/04/25 职场文书
党的群众路线教育实践活动总结大会主持词
2014/10/30 职场文书
2015年体检中心工作总结
2015/05/27 职场文书
《彼得与狼》教学反思
2016/02/20 职场文书
Spring Security使用单点登录的权限功能
2022/04/03 Java/Android