【自己給自己題目做】之一:橢圓可點擊區域


【題一】
請實現以下需求,要做一個活動頁面,頁面上有一張圖片(假設是800x600),圖片正中心有一個橢圓形的可點擊區域,假設橢圓長軸為200px(橫向),短軸160px(縱向),請實現點擊這個橢圓區域彈出“我被點擊了”的字樣,而其他區域點擊無效。(不一定要兼容低端瀏覽器,能兼容當然更好)

我說這是我曾經出過的一道筆試題。其實主要考察點是基本的數學能力和用web前端相關知識實現需求的綜合能力。難度不算太大。用普通的dom或者canvas來實現都ok,因為其實重要思路是一致的。橢圓區域還是要自己判斷。

先看demo后講思路:

demo: http://hongru.github.io/quiz/1/index.html

考點主要是以下幾個:

1. 常用dom操作和簡單事件機制(用類庫比如jq也算)
2. 簡單數學知識(橢圓公式,坐標是否在橢圓區域的判斷)
3. 數學模型到編程實踐的簡單轉換

代碼不復雜:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
body{
    font-family:Microsoft Yahei;
}
.doc {
    width: 804px;
    margin: 0 auto;
}
#cont {
    border: 2px solid #999;
    height: 600px;
    position: relative;
}
.dot {
    position: absolute;
    width:1px;
    height: 1px;
    overflow: hidden;
    font-size:0;
    line-height: 0;
    background: #333;
}
</style>
</head>

<body>
    <div class="doc">
    <h4>【題一】</h4>
    <p>
請實現以下需求,要做一個活動頁面,頁面上有一張圖片(假設是800x600),圖片正中心有一個橢圓形的可點擊區域,假設橢圓長軸為200px(橫向),短軸160px(縱向),請實現點擊這個橢圓區域彈出“我被點擊了”的字樣,而其他區域點擊無效。(不一定要兼容低端瀏覽器,能兼容當然更好)</p>

        <div id="cont"></div>
    </div>
    
    <script>
        ;(function () {
            var win = window,
                doc = document,
                OFFSET;
                
            function _bind (el, ev, fn) {
                return el.addEventListener ? el.addEventListener(ev, fn, false) : el.attachEvent('on'+ev, function () { fn.call(el); });
            }
            function _$ (id) {
                return doc.getElementById(id) || id;
            }                               
            
            function _drawElipse (id, a, b) {
                var el = _$(id);
                var docfrag = doc.createDocumentFragment();
                for (var i = 0; i < 360; i ++) {
                    var dot = doc.createElement('div');
                    dot.className = 'dot';
                    
                    var l = a*Math.sin(i) + (el.offsetWidth - 4)/2,
                        t = b*Math.cos(i) + (el.offsetHeight - 4)/2;
                    
                    dot.style.left = l + 'px';
                    dot.style.top = t + 'px';
                    
                    docfrag.appendChild(dot);
                }
                el.appendChild(docfrag);
            }
            
            function offset (el) {
                 var width = el.offsetWidth,
                    height = el.offsetHeight,
                    top = el.offsetTop,
                    left = el.offsetLeft;
                while (el = el.offsetParent) {
                    top = top + el.offsetTop;
                    left = left + el.offsetLeft;
                }

                return {
                    top: top,
                    left: left,
                    height: height,
                    width: width
                }
            }
            
            function clickCheck (e) {
                e = e || win.event;
                var tar = e.target || e.srcElement,
                    x = e.clientX + doc.body.scrollLeft + doc.documentElement.scrollLeft - OFFSET.left - (tar.offsetWidth/2),
                    y = e.clientY + doc.body.scrollTop + doc.documentElement.scrollTop - OFFSET.top - (tar.offsetHeight/2);
                
                var r = Math.pow((x/100), 2) + Math.pow((y/80), 2);
                console && console.log(x, y, r);
                if (r < 1) {
                    alert('橢圓被點擊了!');
                }
            }
            
            function __init() {
                _drawElipse('cont', 100, 80);
                
                var el = _$('cont');
                OFFSET = offset(el);
                _bind(el, 'click', clickCheck);
            }
            __init();
        })();
    </script>
</body>
</html>
View Code

 

其實重要的代碼就是以下一段:

 1         function clickCheck (e) {
 2                 e = e || win.event;
 3                 var tar = e.target || e.srcElement,
 4                     x = e.clientX + doc.body.scrollLeft + doc.documentElement.scrollLeft - OFFSET.left - (tar.offsetWidth/2),
 5                     y = e.clientY + doc.body.scrollTop + doc.documentElement.scrollTop - OFFSET.top - (tar.offsetHeight/2);
 6                 
 7                 var r = Math.pow((x/100), 2) + Math.pow((y/80), 2);
 8                 console && console.log(x, y, r);
 9                 if (r < 1) {
10                     alert('橢圓被點擊了!');
11                 }
12             }    

因為橢圓是畫在中心的,上面的4,5行,獲取x,y其實就是獲取當前鼠標位置相對於容器中心的相對距離。(要算上scroll的距離和容器本身距離頁面邊緣的位置)

然后用橢圓公式,如果這個值小於1,那么表示在橢圓內點擊的。

結束。

-------------------------------------

下期:定寬容器內若干大小不定圖片自動排列的問題,允許一定程度內的縮放和裁剪,類似於下面的結果:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM