一开始我是这么想的,将待移入的元素分割四块,用mousemove获取第一次鼠标落入的区域来判断鼠标是从哪个方向进去的。
所以只要写个算法来判断鼠标的值落入该元素的区域就可以得出鼠标移入的方向,如下图:
对于数学不太好的我,只能上网找下看有没有人解决了。找到了如下这段:
var x = (e.pageX - this.offsetLeft - (w / 2)) * (w > h ? (h / w) : 1);
var y = (e.pageY - this.offsetTop - (h / 2)) * (h > w ? (w / h) : 1);
var direction = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4;
当时就惊呆了,初看不知道什么意思,重新梳理下,发现这段代码跟我的思路是一样的。
那就让我来一步一步解释这段代码吧!
1)、将判断区域问题转成判断角度。
2)、x和y的计算:
该元素的坐标原点是(offsetLeft, offsetTop),那么要转成判断角度,必须将原点拉到该元素的中点上。则中点的坐标是Oz( offsetLeft + w/2, offsetTop + h/2 );
那么鼠标落入的点M(e.pageX,e.pageY);
如果要将这个点转成以Oz为中心,那么就得换算成 x点:e.pageX - (offsetLeft + w/2) ; y点:e.pageY - (offsetTop + h/2)。
那么x和y就出来了。 (w > h ? (h / w) : 1)和 (h > w ? (w / h) : 1)这两个请先忽略,后面会解释。
3)、Math.atan2(x,y)函数:
这个函数返回的值相当于这个点的角度,当然貌似这些编程语言里返回的基本都是弧度。而这代码是用角度来算的所以避免不了弧度和角度的转换,
公式:弧度=角度乘以π后再除以180,
角度=弧度除以π再乘以180
(Math.atan2(y, x) * (180 / Math.PI) 其实等于这个 (Math.atan2(y, x) / ( Math.PI/ 180)
4)、核心部分,
Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4;
- +180 :从第三步我们可以得到角度了,但为什么还要加个180,原因是原来的坐标轴是(-180,180)度的,加个180那么就都成正的,即(0,360),这个不难理解。
- /90 :那为什么要除于90呢,要知道90,就必须理解 (w > h ? (h / w) : 1)和 (h > w ? (w / h) : 1) 这段代码的意思将矩形矫正成正方形(特殊矩形的矩形是正方形所以也就有了这种判断,其实判不判段都一样)。如果我们的元素是个正方形的话,那两条对角线相交的那些角就都是90度了(下图,图中标明的那个角)。
- +3 的意思,只要知道我们角度区间是从右上方开始算起的,然后顺时针计算的就可以了。该作者想要将结果显示的顺序是 上右下左,所以加三就是将第一区间变成上。
- Math.round() ,四舍五入,那么问题来,我们的X轴和Y轴可不是斜着的呀(如图),那这样角度计算不就成问题了。所以就由Math.round()函数发挥作用了,比如计算下0-90中任何一个数除于除于90,我们可以得到 0~1之间的数,如果加个四舍五入呢?那么结果就只有0和1了,刚好45度角是我们分割线。(只能说写出这个代码的人牛)
- %4取余,保证结果是0、1、2、3 之间的一个(分别代表上、右、下、左)。
这个是我的仿百度新闻传媒动画案例,当然比它实现更好些,就是加入了上面的判断,哈哈。 js库是jquery。
http://yunpan.cn/cjz5aBh3rck9e (提取码:ddc0)