zoukankan      html  css  js  c++  java
  • 【自己给自己题目做】之一:椭圆可点击区域

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

    结束。

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

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

  • 相关阅读:
    在IIS中为SQL Server 2008配置报表服务
    安装VS2008 SP1
    SQL Server 2008正式发布了,示例数据库安装
    order by居然不能直接在union子句中使用
    如何让TabContainer居左
    公布下SQL Server 2008 RC0英文版下载地址
    BIT类型在SQL Server中的存储大小
    使用Windows照片库修改图片后记得清理原始图片副本
    老赵面试题参考答案(一)
    漂亮的系统后台UI 欣赏
  • 原文地址:https://www.cnblogs.com/hongru/p/3187934.html
Copyright © 2011-2022 走看看