zoukankan      html  css  js  c++  java
  • 咱来谈谈前端中的数学,当然啦,顺便也来写点好玩的东西!

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

            假如说现在有这样一道题,网页上有一个正方形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: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>

    总结一下:

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

  • 相关阅读:
    《CLR via C#》读书笔记1 之 CLR的执行模型
    C#中的事件和委托
    优分享VR开源啦,优分享VR是基于Google VR开发的一款手机VR视频资源的聚合软件
    安卓端开源移动浏览器开源项目
    Android客户端发布博客
    博客园的IOS客户端“我的博客园”已发布到AppStore
    博客园的IOS客户端图片展示
    ios在tableview里面加subview后在ip4和ip5上显示不一样的问题
    APP开发手记01(app与web的困惑)
    ios开发3.5和4.0寸屏幕自适应中的一点问题
  • 原文地址:https://www.cnblogs.com/dorseych/p/9259825.html
Copyright © 2011-2022 走看看