我們從一個小例子作引子,見微知著好吧!javascript
假如說如今有這樣一道題,網頁上有一個正方形div,大體的外觀差很少是這樣:css
而後呢,鼠標從左移進去的時候呢,打印一個"左"字,右邊移入呢,打印一個"右"字,上邊,下邊移入呢,也是同樣,那怎樣判斷鼠標在這個div的方位呢?html
咋看起來好像蠻簡單的對吧?不就是獲取鼠標位置,再鼠標的x小於這個div的左邊距的時候是左,大於左邊距+寬度的時候是右,小於上邊距的時候是上,大於上邊距+高度的時候是下,再用個鼠標移入去觸發對吧?好像是這樣,可是呢?其實你真這樣去作你會發現走不通,爲何呢?鼠標的移入事件瀏覽器其實是怎樣判斷的呢?無非是鼠標的位置在這個div以內的第一個落腳點,對吧,得以內,也就是說,以外的是行不通的。並且,假如說,我不是一個,而是5個,10個,甚至100個呢?再這樣去想就稍微有點把本身給坑了對吧?前端
那得怎樣去判斷呢?(先看下下面這張圖)java
個人思路呢是按角度來,能夠先想一想,假如說以正方形的中心點爲圓點畫一個座標軸的話,那咱們這個上下左右的角度會是怎樣?jquery
就是上面這樣對吧?有負的咱很差理解,所有加個180,變成這樣:瀏覽器
而後你發現了嗎?上下左右都間隔90°,是吧,咱再來除以90,而後就變成了:測試
而後呢?你發現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>
上面的代碼能夠看到效果,而實際上寫了那麼多,最終最終有用的其實就紅色框框這麼一句:
是否是很簡單?可是呢?還有個問題?什麼問題?若是元素不是正方形那可得怎麼搞?不是90度了啊?你原來這個不得所有推翻嗎?不不不,上面是咱們完成下面的思惟基石;
那得怎麼分析呢?先看看:
看看上面:是否是從上側移動時的鼠標座標點的與原點的連線是否是更陡峭?上下都是比較陡峭的對吧?或者說他們的角度絕對值更大一些,是吧?左右呢?則是偏緩一些,或者說角度絕對值更小一些對吧?
這樣,它就促使咱們這樣去想:
上,下:|y1/x1| > 邊角點的 |y0/x0|
左,右:|y1/x1| < 邊角點的 |y0/x0|
你說那上下怎麼辦呢?別急,上邊移入的y1是否是大於0的?錯,是小於0哈,再次強調一邊,瀏覽器的y軸是從上到下,也就是說,當在上面區域,你鼠標的點的y值<中心點的y值,因此呢?得出了一個結論:(在上面的條件下)
上:y1<0 下:y1>0 左:x1<0 右:x1>0
你說好像寫成代碼還挺難的樣子,是吧?我貼幾句話你看看哈,難不難你就心中有數了。
真正起做用的僅有中間的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>
總結一下:
前端中的數學呢?其實不難,僅僅只是一些二維平面的運算或是一些三維幾何運算,不用去怕它,之後有什麼新數學方法也會放在這後面,真的挺有意思的,對吧!