【自己给自己题目做】之一:椭圆可点击区域

【题一】
请实现以下需求,要做一个活动页面,页面上有一张图片(假设是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,那么表示在椭圆内点击的。

结束。

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

下期:定宽容器内若干大小不定图片自动排列的问题,允许一定程度内的缩放和裁剪,类似于下面的结果:

【自己给自己题目做】之一:椭圆可点击区域

你可能感兴趣的:(区)