咱们从一个小例子做引子,见微知著好吧!

        假如说现在有这样一道题,网页上有一个正方形div,大致的外观差不多是这样:

https://img1.mukewang.com/5b3b235e00018c8602050220.jpg

        然后呢,鼠标从左移进去的时候呢,打印一个”左”字,右边移入呢,打印一个”右”字,上边,下边移入呢,也是一样,那怎样判断鼠标在这个div的方位呢?

        咋看起来好像蛮简单的对吧?不就是获取鼠标位置,再鼠标的x小于这个div的左边距的时候是左,大于左边距+宽度的时候是右,小于上边距的时候是上,大于上边距+高度的时候是下,再用个鼠标移入去触发对吧?好像是这样,但是呢?其实你真这样去做你会发现走不通,为什么呢?鼠标的移入事件浏览器实际上是怎样判断的呢?无非是鼠标的位置在这个div之内的第一个落脚点,对吧,得之内,也就是说,之外的是行不通的。而且,假如说,我不是一个,而是5个,10个,甚至100个呢?再这样去想就稍微有点把自己给坑了对吧?

        那得怎样去判断呢?(先看下下面这张图)

https://img1.mukewang.com/5b3b2c7f00018ea204730380.jpg

        我的思路呢是按角度来,可以先想想,假如说以正方形的中心点为圆点画一个坐标轴的话,那我们这个上下左右的角度会是怎样?

https://img3.mukewang.com/5b3b2edb00010dd104940457.jpg

就是上面这样对吧?有负的咱不好理解,全部加个180,变成这样:

https://img.mukewang.com/5b3b313900011d3c05730507.jpg

然后你发现了吗?上下左右都间隔90°,是吧,咱再来除以90,然后就变成了:

https://img.mukewang.com/5b3b31e10001a14d02610101.jpg

然后呢?你发现2.5~3.5的四舍五入变成什么呢? 3对吧? 

好了,发现规律了,然后呢变成这样: 

上:3    左:4或者0    下:1    右:2

你说左有点问题啊,嗯是的,那如果把所有的值再来余4呢?看看,是不是很酷,变成了:

左:0    下:1    右:2    上:3

这样是不是方位就出来了?那具体代码得怎样实现呢?

先看看下面这个:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6     <style>
 7         html,body,div{margin:0;padding:0}
 8         .test{
 9             width:200px;
10             height:200px;
11             margin: 100px auto 0;
12             box-shadow:0 0 5px #000;
13         }
14     </style>
15     <script>
16         window.onload=function(){
17             var oBox=document.getElementsByClassName('test')[0],
18                 centerX=oBox.offsetLeft+oBox.offsetWidth/2,
19                 centerY=oBox.offsetTop+oBox.offsetHeight/2;
20 
21             // console.log(centerX);//中心点
22             // console.log(centerY);
23 
24             var direction;
25 
26             oBox.addEventListener('mouseenter',function(e){
27 
28                 e = e || window.event;
29                 var x=e.clientX-centerX,
30                     y=e.clientY-centerY;
31 
32                 //根据反正切求角度:(arctan(y/x)/π)  *  180
33                 // var deg=-Math.atan2(y,x) * (180/Math.PI);//看看前面有个负号,为什么呢?因为我们浏览器的y轴正向是向下的与我们
34 
35                 // 的普通坐标轴相反
36                 // console.log(deg);//看看deg是不是我们第一个的那种角度呢?这里只是很简单的用一个反正切来得到角度
37                 //
38                 // //这里我分成一步步写哈
39                 // var deg1=deg+180;//是不是加了180?
40                 //
41                 // var deg2=deg1/90;//是不是除以90?
42                 //
43                 // var deg3=Math.round(deg2);//是不是四舍五入?
44                 //
45                 // var degValue=deg3%4;
46                 //
47                 // console.log(degValue);//可以鼠标移动看看哈,看是否有上对应3,左对应0等等的情况
48 
49                 var degValue=Math.round((-Math.atan2(y,x) * (180/Math.PI)+180)/90)%4;
50 
51                 switch(degValue){
52                     case 0 : direction = "left"; break;
53                     case 1 : direction = "bottom"; break;
54                     case 2 : direction = "right"; break;
55                     case 3 : direction = "top"; break;
56                 }
57                 console.log(direction);
58 
59             })
60 
61         }
62     </script>
63 </head>
64 <body>
65 <div class="test"></div>
66 </body>
67 </html>

上面的代码可以看到效果,而实际上写了那么多,最终最终有用的其实就红色框框这么一句:

https://img.mukewang.com/5b3b3aeb00017ce006330257.jpg

        是不是很简单?但是呢?还有个问题?什么问题?如果元素不是正方形那可得怎么搞?不是90度了啊?你原来这个不得全部推翻吗?不不不,上面是我们完成下面的思维基石;

        那得怎么分析呢?先看看:

https://img1.mukewang.com/5b3b3dc90001569a05520425.jpg

        看看上面:是不是从上侧移动时的鼠标坐标点的与原点的连线是不是更陡峭?上下都是比较陡峭的对吧?或者说他们的角度绝对值更大一些,是吧?左右呢?则是偏缓一些,或者说角度绝对值更小一些对吧?

        这样,它就促使我们这样去想:

        上,下:|y1/x1|   > 边角点的  |y0/x0|

        左,右:|y1/x1|   < 边角点的  |y0/x0|

        你说那上下怎么办呢?别急,上边移入的y1是不是大于0的?错,是小于0哈,再次强调一边,浏览器的y轴是从上到下,也就是说,当在上面区域,你鼠标的点的y值<中心点的y值,所以呢?得出了一个结论:(在上面的条件下)

        上:y1<0        下:y1>0        左:x1<0        右:x1>0

你说好像写成代码还挺难的样子,是吧?我贴几句话你看看哈,难不难你就心中有数了。

https://img1.mukewang.com/5b3b410d0001d0f705480463.jpg

真正起作用的仅有中间的3行代码,难吗?

        既然有个比较通用的,比较靠谱的,对吧?那咱就来写一写代码,当然啦,总是弹出上啊,左啊右啊的,没意思,咱加点效果,好吧?

        当然了,下面这个代码呢,我就仅仅写了上边的哈,记住上边移入的时候会有完整效果,其他方向呢,也有,但是呢,没上边的好看,为什么要这样呢?因为你看了这么多对吧?总得自己练一练,不然是没有效果的,代码我就贴下边哈,自己尝试尝试,把左下跟右的效果补全。

        jQuery的请随便搜索个版本自行引入。

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>初步测试</title>
  6     <style>
  7         html,body,div,ul,li{margin:0;padding:0;}
  8         li{list-style:none}
  9         .list{
 10             width:800px;
 11             height:440px;
 12             margin:100px auto 0;
 13             box-shadow:0 0 5px #000;
 14         }
 15         li{
 16             margin:10px;
 17             width:180px;
 18             height:200px;
 19             float:left;
 20             perspective:1000px;
 21             position:relative;
 22         }
 23         .liBox{
 24             width:100%;
 25             height:100%;
 26             position:absolute;
 27             transform-origin:50% 50% -100px;
 28             animation: 250ms ease-out 0ms 1 normal forwards;
 29             transform-style: preserve-3d;
 30         }
 31         .pic,.words{
 32             position:absolute;
 33             width:100%;
 34             height:100%;
 35             /*transition:0.5s;*/
 36         }
 37         .pic{background:skyblue}
 38         .words{background: #a9ebaa;visibility: hidden}
 39 
 40         /*当鼠标进入li的时候呢,里面的picture和words两个元素层呢迅速做变轨*/
 41         .wordsTop{
 42             transform:rotateX(90deg) translate3d(0,-50%,100px);
 43         }
 44 
 45         /**/
 46         .in-top{
 47             animation-name: in-top;
 48             animation-play-state: running;
 49         }
 50         .out-top{
 51             animation-name: out-top;
 52             animation-play-state: running;
 53         }
 54 
 55         /**/
 56         .in-bottom{
 57             animation-name: in-bottom;
 58             animation-play-state: running;
 59         }
 60         .out-bottom{
 61             animation-name: out-bottom;
 62             animation-play-state: running;
 63         }
 64 
 65         /**/
 66         .in-left{
 67             animation-name: in-left;
 68             animation-play-state: running;
 69         }
 70         .out-left{
 71             animation-name: out-left;
 72             animation-play-state: running;
 73         }
 74 
 75         /**/
 76         .in-right{
 77             animation-name: in-right;
 78             animation-play-state: running;
 79         }
 80         .out-right{
 81             animation-name: out-right;
 82             animation-play-state: running;
 83         }
 84 
 85         /**/
 86         @keyframes in-top {
 87             from{transform:rotate3d(0,0,0,0deg)}
 88             to{transform:rotate3d(-1,0,0,90deg)}
 89         }
 90         @keyframes out-top {
 91             from{transform: rotate3d(-1,0,0,90deg)}
 92             to{transform:rotate3d(0,0,0,0deg)}
 93         }
 94         /**/
 95         @keyframes in-bottom {
 96             from{transform:rotate3d(0,0,0,0deg)}
 97             to{transform:rotate3d(1,0,0,90deg)}
 98         }
 99         @keyframes out-bottom {
100             from{transform: rotate3d(1,0,0,90deg)}
101             to{transform:rotate3d(0,0,0,0deg)}
102         }
103         /**/
104         @keyframes in-left {
105             from{transform:rotate3d(0,0,0,0deg)}
106             to{transform:rotate3d(0,1,0,90deg)}
107         }
108         @keyframes out-left {
109             from{transform: rotate3d(0,1,0,90deg)}
110             to{transform:rotate3d(0,0,0,0deg)}
111         }
112         /**/
113         @keyframes in-right {
114             from{transform:rotate3d(0,0,0,0deg)}
115             to{transform:rotate3d(0,-1,0,90deg)}
116         }
117         @keyframes out-right {
118             from{transform: rotate3d(0,-1,0,90deg)}
119             to{transform:rotate3d(0,0,0,0deg)}
120         }
121 
122     </style>
123     <script src="dist/js/jquery-3.3.1.min.js" type="text/javascript"></script>
124     <script>
125         $(function(){
126 
127             var $list=$('.list'),
128                 $li=$list.find('li');
129 
130             var flag,directionClass;//标志位跟方向类名
131 
132             $li.on('mouseenter',function(e){
133 
134                 e = e || window.event;
135 
136                 var cx=$(this).width()/2+$(this).offset().left,//中心点x轴坐标 cx(centerX缩写)
137                     cy=$(this).height()/2+$(this).offset().top,//中心点y轴坐标
138 
139                     bx=$(this).width()+$(this).offset().left,//同时由于元素不一定是正方形,需要获取边角的点坐标
140                     by=$(this).height()+$(this).offset().top;//这里取的是右下角 bx(borderX缩写)
141 
142                 // console.log("cx:"+cx+"\ncy:"+cy);
143 
144                 //鼠标点与中心点的连线,类似于初中数学x1-x2
145                 var spaceX=e.pageX-cx,
146                     spaceY=e.pageY-cy;
147 
148                 //边角点与中心连线,
149                 var borderX=bx-cx,
150                     borderY=by-cy;
151 
152                 //判断方向
153                 var abs=Math.abs(spaceY/spaceX)-Math.abs(borderY/borderX);
154                 console.log("abs"+abs);
155                 abs>0?(spaceY>0?flag=2:flag=0):(spaceX>0?flag=1:flag=3);
156 
157                 switch(flag){
158                     case 0 : directionClass="top";break;
159                     case 1 : directionClass="right";break;
160                     case 2 : directionClass="bottom";break;
161                     case 3 : directionClass="left";break;
162                 }
163 
164                 console.log(directionClass);//看看这个打印哦,看看鼠标从不同方位进入的时候打印了什么?不知道控制台的请按F12即可
165 
166                 $(this).find('.words').css("visibility","visible").addClass('wordsTop');
167 
168 
169                 $(this).children('div').removeClass().addClass('liBox');
170 
171                 $(this).children('div').addClass("in-"+directionClass);
172 
173             })
174         })
175     </script>
176 </head>
177 <body>
178 <div class="list">
179     <ul>
180         <li>
181             <div class="liBox">
182                 <div class="pic"></div>
183                 <div class="words"></div>
184             </div>
185         </li>
186         <li>
187             <div class="liBox">
188                 <div class="pic"></div>
189                 <div class="words"></div>
190             </div>
191         </li>
192         <li>
193             <div class="liBox">
194                 <div class="pic"></div>
195                 <div class="words"></div>
196             </div>
197         </li>
198         <li>
199             <div class="liBox">
200                 <div class="pic"></div>
201                 <div class="words"></div>
202             </div>
203         </li>
204         <li>
205             <div class="liBox">
206                 <div class="pic"></div>
207                 <div class="words"></div>
208             </div>
209         </li>
210         <li>
211             <div class="liBox">
212                 <div class="pic"></div>
213                 <div class="words"></div>
214             </div>
215         </li>
216         <li>
217             <div class="liBox">
218                 <div class="pic"></div>
219                 <div class="words"></div>
220             </div>
221         </li>
222         <li>
223             <div class="liBox">
224                 <div class="pic"></div>
225                 <div class="words"></div>
226             </div>
227         </li>
228     </ul>
229 </div>
230 </body>
231 </html>

总结一下:

  前端中的数学呢?其实不难,仅仅只是一些二维平面的运算或是一些三维几何运算,不用去怕它,以后有什么新数学方法也会放在这后面,真的挺有意思的,对吧!

版权声明:本文为dorseych原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/dorseych/p/9259825.html