利用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) ,然后用上面计算出来的结果除以一度的弧度值

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

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

0度的位置

所以现在的范围变成了

0~44 & 360~315 左边

45~134 上边

135~224 右边

225~314 下边

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

上边算出来的结果为1

上边

右边算出来的结果为2

右边

下边算出来的结果为3

下边

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

左边

现在算出来的结果一共有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>

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

(0)

相关推荐

  • javascript鼠标跟随运动3种效果(眼球效果,苹果菜单,方向跟随)

    运动除了直线运动和曲线运动两种运动形式外,还有一种运动形式是鼠标跟随运动,而这种跟随运动需要用到三角函数的相关内容或者需要进行比例运算.本文将以几个小实例来介绍角度运动的相关内容 眼球转动 在很多网页中,都存在着跟随运动,比如眼球转动.鼠标在网页中移动时,眼球也会跟着朝相应方向转动 上面是眼球转动的示意图,(x0,y0)是眼球的位置,而(x,y)是鼠标的位置.设直线与垂直方向的夹角为a,假设圆心点坐标为(0,0),可以得到以下公式 tan(a) = x/y = x0/y0 x0 = r*sin(

  • ajax请求成功后新开窗口window.open()被拦截解决方法

    问题: 前面开发项目时碰到一个问题,ajax 异步请求成功后需要新开窗口打开 url,使用的是 window.open() 方法,但是很可惜被浏览器给拦截了,怎么解决这个问题呢? 分析: 浏览器之所以拦截新开窗口是因为该操作并不是用户主动触发的,所以它认为这是不安全的就拦截了(不过如果是 _self 的话就不会有这个限制),即使 ajax 回调函数中模拟执行 click 或者 submit 等用户行为(trigger('click')),浏览器也会认为不是由用户主动触发的,因此不能被安全执行,所

  • js实现window.open不被拦截的解决方法汇总

    本文实例讲述了js实现window.open不被拦截的解决方法.分享给大家供大家参考.具体分析如下: 一.问题: 今天在处理页面ajax请求过程中,想实现请求后打开新页面,就想到通过 js window.open 来实现,但是最终都被浏览器拦截了. 二.分析: 在谷歌搜索有没有解决方法,有些说可以通过新建a标签,模拟点击来实现,但是测试发现都实现不了,照样被浏览器拦截. 最后找到了一个折中的办法,可以实现新页面打开,但是没有a标签的那种直接流量新页面的效果. 三.实现代码: 复制代码 代码如下:

  • window.open不被拦截的实现代码

    复制代码 代码如下: $("#last").click(function(){ var w=window.open(); setTimeout(function(){ w.location="http://www.baidu.com"; }, 1000); return false; });

  • window.open关于浏览器拦截问题分析及解决方法

    window.open是javascript函数,该函数的作用是打开一个新窗口或这改变原来的窗口,不过一般用来的是打开新窗口,因为修改原来的网页地址,可以有另一个函数,那就是window.location,他可以重定向网页地址,使网页跳转到另一个页面. 我现在要说的是window.open函数的几个使用策略,一般情况下,如果你直接在js中调用window.open()函数去打开一个新窗口,浏览器会拦截你,认为你将弹出广告等用户不想得到的窗体,所以如果不想让浏览器拦截你,你可以将这个函数改为用户点

  • JavaScript检测鼠标移动方向的方法

    本文实例讲述了JavaScript检测鼠标移动方向的方法.分享给大家供大家参考.具体实现方法如下: function Start() { stage.addEventListener(MouseEvent.MOUSE_MOVE, CheckDirection); } Start(); var prevX=0; var prevY=0; var curX=0; var curY=0; var dirX:String=""; var dirY:String=""; fu

  • JS判断鼠标进入容器的方向与window.open新窗口被拦截的问题

    一.鼠标进入容器方向的判定 判断鼠标从哪个方向进入元素容器是一个经常碰到的问题,如何来判断呢? 首先想到的是:获取鼠标的位置,然后经过一大堆的if..else逻辑来确定.这样的做法比较繁琐,下面介绍两种比较方便的方法: 第一种方法,利用圆和反正切三角函数 如下图所示: 以div容器的中心点作为圆心,以高和宽的最小值作为直径画圆,将圆以[π/4,3π/4),[3π/4,5π/4),[5π/4,7π/4),[-π/4,π/4)划分为四个象限. 代码如下: $(".box").on(&quo

  • JS用斜率判断鼠标进入DIV四个方向的方法

    网上大部分判断鼠标移入div移入移出都是使用一下方法: 这个方法确实十分奇特,使用起来十分方便. 后来自己看了一些文章,看到有另一种以斜率的方法来判断鼠标的移动方向. 上图是此方法的示意图,以浏览器左上角做原点,水平轴作为x轴,往右为正:竖直轴作为y轴,向上为正. 中间的div的左上角坐标(x1,y1),右下角坐标(x2,y2),中心点的坐标(x0,y0). 设如图两点的斜率为k(k<0),关于x轴对称的斜率为-k. 另外鼠标刚移入时,鼠标的坐标设为(x,y): window.onload =

  • window.open被浏览器拦截后的自定义提示效果代码

    现在越来越多的浏览器有拦截弹出窗口的功能.广告弹出来给拦掉了就无所谓,要是客户在付款时给拦掉了可就不能乱算了. Gmail的"哎呀"算是经典,可是,前天心云给出了更帅的提示=.= 记得打开浏览器拦截后 测试一下,在线阅读器里不知道代码会不会给过滤..代码在下边,其实没什么技术含量滴.挖哈哈... 复制代码 代码如下: window._open=window.open;  window.open=function(sURL,sName,sFeatures,bReplace){    if

  • JS判断鼠标从什么方向进入一个容器实例说明

    偶然将想到的一个如何判断鼠标从哪个方向进入一个容器的问题.首先想到的是给容器的四个边添加几块,然后看鼠标进入的时候哪个块先监听到鼠标事件.不过这样麻烦太多了.google了一下找到了一个不错的解决方法,是基于jquery的,说实话,其中的var direction = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4;这句用到的数学知识我是真没有看明白,原文中有一些英文注释我就不一一说明了.代码部分不是

随机推荐