摘要:有不對的地方,或者有更好的理解,請告訴我,謝謝原理以容器的中心點作為圓心,以高和寬的最小值作為直徑畫圓,將圓以,,,,,,,劃分為四個象限,鼠標進入容器時的點的值在這四個象限里分別對應容器邊框的下,右,上,左。
$("#wrap").bind("mouseenter mouseleave",function(e) { var w = $(this).width(); var h = $(this).height(); 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; //direction的值為“0,1,2,3”分別對應著“上,右,下,左” var eventType = e.type; var dirName = new Array("上方","右側","下方","左側"); if(e.type == "mouseenter"){ $("#result").html(dirName[direction]+"進入"); } else { $("#result").html(dirName[direction]+"離開"); } });
就這么幾行代碼,將我印象里會有一長串的if else或者switch來完成的事完美的解決掉。在感到神奇之后,更多的是不解,因為看不懂。在網上搜索一番,也沒有找到有誰來分析這個算法。于是自己研究了一下,現在寫下來,作為自己的一份學習筆記,也希望能夠和大家分享。
有不對的地方,或者有更好的理解,請告訴我,謝謝!
原理:以div容器的中心點作為圓心,以高和寬的最小值作為直徑畫圓,將圓以[π/4,3π/4),[3π/4,5π/4),[5π/4,7π/4),[-π/4,π/4)劃分為四個象限,鼠標進入容器時的點的atan2(y,x)值在這四個象限里分別對應容器邊框的下,右,上,左。如下圖所示
var x = (e.pageX - this.offsetLeft - (w / 2)) * (w > h ? (h / w) : 1);
計算x坐標值時,如果點原來的x坐標的絕對值大于圓的半徑值,則按 h/w 這個比例進行縮小,使得到的點的位置在容器的邊界位置所對應的象限區(qū)間里。 y 坐標的計算也是一樣。
var direction = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4;
((Math.atan2(y, x) * (180 / Math.PI)將點的坐標對應的弧度值換算成角度度數值,這里加上180并非必要,只是為了使得到的0,1,2,3能夠與習慣性的上,右,下,左的位置對照,如果不加上180,得到的0,1,2,3就會分別對應下,右,上,左。
*修正:這里加上180不是并非必要的,而是在這個算法里必須的,因為atan2(y,x)返回值的范圍是[-π,π],而不是我們習慣的[0,2π],負值會影響結果的正確性(比如右上和右下算出來的結果會不同),而且確實也使得得到的結果0,1,2,3的順序符合了習慣(原作者可能沒想這個,只是css里總是這個順序,或許是我自己的習慣~)。
除以90,再取四舍五入值,是一個很精妙的用法,使得可以以45°為分界線。
分析完這個算法后,我內心有些激動。這里并沒有用到什么高深的知識,即使是三角函數的基礎知識都可以不知道(雖然初中就學了),但是可以用這么短短的三兩行代碼,就把我腦袋里浮現的那一長串的if else拋向云和山的彼端去,真的讓我很難抑制內心的激動,深深的體會到算法之美,數學之美。
來源:http://sentsin.com/web/112.html
相關參考文檔:http://www.cnblogs.com/lyzg/p...
代碼參考: https://github.com/liuyunzhug...
最后感謝兩位大牛的總結
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/80187.html
js實現點擊切換和自動播放的輪播圖,其實十分簡單,話不多說,我們直接看示例: 輪播圖案例 <!DOCTYPEhtml> <html> <head> <metacharset="UTF-8"> <metaname="vie...
摘要:之前總結了事件捕獲和冒泡以及阻止事件傳播,今天寫一下事件代理方面的總結事件之捕獲冒泡阻止事件傳播事件代理監(jiān)聽列表中多項時,實現點擊控制臺打印對應文本,如下蘋果香蕉葡萄首先想到的對每一個進行監(jiān)聽或者使用和的區(qū)別是屬性,是方法。 之前總結了事件捕獲和冒泡以及阻止事件傳播,今天寫一下事件代理方面的總結DOM 事件之捕獲、冒泡:阻止事件傳播: 事件代理 監(jiān)聽列表中多項 li 時,實現點擊 li...
摘要:然而問題是,這個法則在導航條的主體是可行的但是子選單因為前面提到的三層嵌套構造圓角,已經無法減少嵌套了,同時還得考慮到子選單也是嵌套在導航條里的啊。。。同理,反過來進入子選單時自然就用來抵消達到篩選的目的。 0x1setTimeout應用 實現效果:4-01setTimeout應用 又見導航條,先看下css,這里用的是雪碧圖背景做出圓角的效果,雖然是經典的方法、兼容性好,但這種代碼寫起...
摘要:這篇文章將介紹如何使用原生主要使用語法實現全屏滾動插件,兼容手機觸屏,觸摸板優(yōu)化,支持自定義頁面動畫,壓縮后文件只有。 這篇文章將介紹如何使用原生 JS (主要使用 ES6 語法)實現全屏滾動插件,兼容 IE 10+、手機觸屏,Mac 觸摸板優(yōu)化,支持自定義頁面動畫,壓縮后 gzip 文件只有 2.15KB。完整源碼在這 pure-full-page,點這查看 demo。 1)前面的話...
摘要:嘗試實現畫出一個彈射的小球很簡單,那怎么用多個小球實現這樣的效果呢。 本文首發(fā)于我的博客,這是我的github,歡迎star。 ??這篇博客是模仿nest.js實現一個demo,由簡單到復雜,來一步步的實現它。這里是效果預覽。我的github里邊還有很多別的前端的demo,喜歡的話可以點個star,你的支持就是我的動力。 從一道面試題開始 實現一個半徑10px的小球在500px*5...
閱讀 3054·2021-11-19 11:31
閱讀 3143·2021-09-02 15:15
閱讀 998·2019-08-29 17:22
閱讀 1067·2019-08-29 16:38
閱讀 2470·2019-08-26 13:56
閱讀 841·2019-08-26 12:16
閱讀 1445·2019-08-26 11:29
閱讀 939·2019-08-26 10:12