利用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 相关文章推荐
js对象数组按属性快速排序
Jan 31 Javascript
如何确保JavaScript的执行顺序 之jQuery.html深度分析
Mar 03 Javascript
用RadioButten或CheckBox实现div的显示与隐藏
Sep 21 Javascript
javascript三元运算符用法实例
Apr 16 Javascript
JAVA四种基本排序方法实例总结
Jul 24 Javascript
利用jquery禁止外层滚动条的滚动
Jan 05 Javascript
vue2.0嵌套路由实现豆瓣电影分页功能(附demo)
Mar 13 Javascript
node的process以及child_process模块学习笔记
Mar 06 Javascript
jQuery简单实现的HTML页面文本框模糊匹配查询功能完整示例
May 09 jQuery
nuxt中使用路由守卫的方法步骤
Jan 27 Javascript
在vue项目中引入vue-beauty操作方法
Feb 11 Javascript
vue-cli3项目展示本地Markdown文件的方法
Jun 07 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
smarty模板引擎之内建函数用法
2015/03/30 PHP
PHP中仿制 ecshop验证码实例
2017/01/06 PHP
Javascript - HTML的request类
2006/07/15 Javascript
javascript优先加载笔记代码
2008/09/30 Javascript
Jquery轮播效果实现过程解析
2016/03/30 Javascript
浅析jquery unbind()方法移除元素绑定的事件
2016/05/24 Javascript
js实现精确到秒的倒计时效果
2016/05/29 Javascript
解决jQuery ajax请求在IE6中莫名中断的问题
2016/06/20 Javascript
Jqprint实现页面打印
2017/01/06 Javascript
JavaScript中最常见的三个面试题解析
2017/03/04 Javascript
解决webpack打包速度慢的解决办法汇总
2017/07/06 Javascript
node实现简单的反向代理服务器
2017/07/26 Javascript
Vue.js通用应用框架-Nuxt.js的上手教程
2017/12/25 Javascript
React之PureComponent的使用作用
2018/07/10 Javascript
对Python 内建函数和保留字详解
2018/10/15 Python
使用 Python 处理 JSON 格式的数据
2019/07/22 Python
使用python实现unix2dos和dos2unix命令的例子
2019/08/13 Python
Python json转字典字符方法实例解析
2020/04/13 Python
TensorFlow tf.nn.softmax_cross_entropy_with_logits的用法
2020/04/19 Python
Python 实现一行输入多个数字(用空格隔开)
2020/04/29 Python
python中altair可视化库实例用法
2021/01/26 Python
西班牙英格列斯百货法国官网:El Corte Inglés法国
2017/07/09 全球购物
印尼太阳百货公司网站:Matahari
2018/02/04 全球购物
西海岸男士和男童服装:Johnnie-O
2018/03/15 全球购物
意大利宠物用品购物网站:Bauzaar
2018/09/15 全球购物
Ooni英国官网:披萨烤箱
2020/05/31 全球购物
EJB2和EJB3在架构上的不同点
2014/09/29 面试题
农村产权制度改革实施方案
2014/03/21 职场文书
新年团拜会主持词
2014/04/02 职场文书
终止或解除劳动合同及劳动关系的证明书
2014/10/06 职场文书
2014年后勤工作总结范文
2014/12/16 职场文书
2015驻村干部工作总结
2015/04/07 职场文书
2016年3月份红领巾广播稿
2015/12/21 职场文书
Mysql分库分表之后主键处理的几种方法
2022/02/15 MySQL
MongoDB数据库部署环境准备及使用介绍
2022/03/21 MongoDB