咱來談談前端中的數學,固然啦,順便也來寫點好玩的東西!

我們從一個小例子作引子,見微知著好吧!javascript

        假如說如今有這樣一道題,網頁上有一個正方形div,大體的外觀差很少是這樣:css

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

        而後呢,鼠標從左移進去的時候呢,打印一個"左"字,右邊移入呢,打印一個"右"字,上邊,下邊移入呢,也是同樣,那怎樣判斷鼠標在這個div的方位呢?html

        咋看起來好像蠻簡單的對吧?不就是獲取鼠標位置,再鼠標的x小於這個div的左邊距的時候是左,大於左邊距+寬度的時候是右,小於上邊距的時候是上,大於上邊距+高度的時候是下,再用個鼠標移入去觸發對吧?好像是這樣,可是呢?其實你真這樣去作你會發現走不通,爲何呢?鼠標的移入事件瀏覽器其實是怎樣判斷的呢?無非是鼠標的位置在這個div以內的第一個落腳點,對吧,得以內,也就是說,以外的是行不通的。並且,假如說,我不是一個,而是5個,10個,甚至100個呢?再這樣去想就稍微有點把本身給坑了對吧?前端

        那得怎樣去判斷呢?(先看下下面這張圖)java

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

        個人思路呢是按角度來,能夠先想一想,假如說以正方形的中心點爲圓點畫一個座標軸的話,那咱們這個上下左右的角度會是怎樣?jquery

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對吧? this

好了,發現規律了,而後呢變成這樣: spa

上: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:880px;
 11             height:400px;
 12             margin:100px auto 0;
 13             box-shadow:0 0 5px #000;
 14         }
 15         li{
 16             margin:10px;
 17             width:200px;
 18             height:180px;
 19             float:left;
 20             perspective:1000px;
 21             position:relative;
 22             cursor: pointer;
 23         }
 24         .liBox{
 25             width:100%;
 26             height:100%;
 27             position:absolute;
 28             transform-origin:50% 50% -100px;
 29             animation: 200ms ease-out 0ms 1 normal forwards;
 30             transform-style: preserve-3d;
 31         }
 32         .pic,.words{
 33             position:absolute;
 34             width:100%;
 35             height:100%;
 36         }
 37         .pic{background:skyblue}
 38         .words{background: #a9ebaa;visibility: hidden}
 39 
 40         /*當鼠標進入li的時候呢,裏面的picture和words兩個元素層呢迅速作變軌*/
 41         .words-top{
 42             transform:rotateX(90deg) translate3d(0,-50%,90px);
 43         }
 44         .words-bottom{
 45             transform: rotateX(-90deg) translate3d(0,50%,90px);
 46         }
 47         .words-left{
 48             transform: rotateY(-90deg) translate3d(-50%,0,100px);
 49         }
 50         .words-right{
 51             transform: rotateY(90deg) translate3d(50%,0,100px);
 52         }
 53 
 54 
 55         /**/
 56         .in-top{
 57             animation-name: in-top;
 58             animation-play-state: running;
 59         }
 60         .out-top{
 61             animation-name: out-top;
 62             animation-play-state: running;
 63         }
 64 
 65         /**/
 66         .in-bottom{
 67             animation-name: in-bottom;
 68             animation-play-state: running;
 69         }
 70         .out-bottom{
 71             animation-name: out-bottom;
 72             animation-play-state: running;
 73         }
 74 
 75         /**/
 76         .in-left{
 77             animation-name: in-left;
 78             animation-play-state: running;
 79         }
 80         .out-left{
 81             animation-name: out-left;
 82             animation-play-state: running;
 83         }
 84 
 85         /**/
 86         .in-right{
 87             animation-name: in-right;
 88             animation-play-state: running;
 89         }
 90         .out-right{
 91             animation-name: out-right;
 92             animation-play-state: running;
 93         }
 94 
 95         /**/
 96         @keyframes in-top {
 97             from{transform:rotate3d(0,0,0,0deg)}
 98             to{transform:rotate3d(-1,0,0,90deg)}
 99         }
100         @keyframes out-top {
101             from{transform: rotate3d(-1,0,0,90deg)}
102             to{transform:rotate3d(0,0,0,0deg)}
103         }
104         /**/
105         @keyframes in-bottom {
106             from{transform:rotate3d(0,0,0,0deg)}
107             to{transform:rotate3d(1,0,0,90deg)}
108         }
109         @keyframes out-bottom {
110             from{transform: rotate3d(1,0,0,90deg)}
111             to{transform:rotate3d(0,0,0,0deg)}
112         }
113         /**/
114         @keyframes in-left {
115             from{transform:rotate3d(0,0,0,0deg)}
116             to{transform:rotate3d(0,1,0,90deg)}
117         }
118         @keyframes out-left {
119             from{transform: rotate3d(0,1,0,90deg)}
120             to{transform:rotate3d(0,0,0,0deg)}
121         }
122         /**/
123         @keyframes in-right {
124             from{transform:rotate3d(0,0,0,0deg)}
125             to{transform:rotate3d(0,-1,0,90deg)}
126         }
127         @keyframes out-right {
128             from{transform: rotate3d(0,-1,0,90deg)}
129             to{transform:rotate3d(0,0,0,0deg)}
130         }
131 
132     </style>
133     <script src="../dist/js/jquery-3.3.1.min.js" type="text/javascript"></script>
134     <script>
135         $(function(){
136 
137             var $list=$('.list'),
138                 $li=$list.find('li');
139 
140             var directionClass,//方向類名
141                 offset; //旋轉中心偏移值
142 
143 
144             $li.on('mouseenter',function(e){
145                 directionClass=getDirection(e,$(this));
146 
147                 (directionClass === "left" || directionClass === "right") ? offset =$(this).width()/2 : offset = $(this).height()/2;
148                 $(this).find('.words').css("visibility","visible").removeClass().addClass('words words-'+directionClass);
149                 $(this).children('div').removeClass().addClass('liBox');
150                 $(this).children('div').addClass("in-"+directionClass);
151                 $(this).children('.liBox').css("transform-origin","50% 50% -"+offset+"px");
152             });
153             $li.on("mouseleave",function(){
154                 $(this).children('div').addClass("out-"+directionClass);
155             });
156 
157             var getDirection=function(e,obj){
158 
159                 e = e || window.event;
160 
161                 var direction;
162                 //obj中心點與邊角點(任意取一個都行)
163                 var cx = obj.width()/2 + obj.offset().left,
164                     cy = obj.height()/2 + obj.offset().top;
165 
166                 var abs=Math.abs((e.pageY-cy)/(e.pageX-cx))-Math.abs(obj.width()/obj.height());
167                 abs > 0 ? (e.pageY > cy ? direction = "bottom" : direction = "top") : (e.pageX > cx ? direction = "right" : direction = "left");
168 
169                 return direction;
170             }
171 
172         });
173     </script>
174 </head>
175 <body>
176 <div class="list">
177     <ul>
178         <li>
179             <div class="liBox">
180                 <div class="pic"></div>
181                 <div class="words"></div>
182             </div>
183         </li>
184         <li>
185             <div class="liBox">
186                 <div class="pic"></div>
187                 <div class="words"></div>
188             </div>
189         </li>
190         <li>
191             <div class="liBox">
192                 <div class="pic"></div>
193                 <div class="words"></div>
194             </div>
195         </li>
196         <li>
197             <div class="liBox">
198                 <div class="pic"></div>
199                 <div class="words"></div>
200             </div>
201         </li>
202         <li>
203             <div class="liBox">
204                 <div class="pic"></div>
205                 <div class="words"></div>
206             </div>
207         </li>
208         <li>
209             <div class="liBox">
210                 <div class="pic"></div>
211                 <div class="words"></div>
212             </div>
213         </li>
214         <li>
215             <div class="liBox">
216                 <div class="pic"></div>
217                 <div class="words"></div>
218             </div>
219         </li>
220         <li>
221             <div class="liBox">
222                 <div class="pic"></div>
223                 <div class="words"></div>
224             </div>
225         </li>
226     </ul>
227 </div>
228 </body>
229 </html>

 

總結一下:

  前端中的數學呢?其實不難,僅僅只是一些二維平面的運算或是一些三維幾何運算,不用去怕它,之後有什麼新數學方法也會放在這後面,真的挺有意思的,對吧!

相關文章
相關標籤/搜索