穿墙效果及注释

穿墙效果附加注释,附加鼠标进入方向算法

<!doctype html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
    * {
        margin: 0;
        padding: 0;
        list-style: none;
    }

    ul {
        overflow: hidden;
         630px;
        margin: 100px auto;
    }

    ul li {
        float: left;
        position: relative;
         200px;
        height: 200px;
        background: #ccc;
        margin: 5px;
        overflow: hidden;
    }

    ul li span {
        position: absolute;
         100%;
        height: 100%;
        background: rgba(255, 0, 0, 0.3);
        left: -200px;
        top: 0;
    }
    </style>
    <script>
    function getStyle(obj, sName) {
        // 获取元素对象的css属性值兼容ie和其他浏览器
        return (obj.currentStyle || getComputedStyle(obj, false))[sName];
    }

    function move(obj, json, options) {
        // obj 为元素对象、json为设定最后结果对象、options为设置对象
        // 给options设定默认值
        options = options || {};
        // 设定持续时间
        options.duration = options.duration || 700;
        // 设定运动方式
        options.easing = options.easing || 'ease-out';
        // 定义空对象
        var start = {};
        // 定义差值对象
        var dis = {};
        // 遍历设定设定最后结果对象
        for (var name in json) {
            // 将设定最后结果对象中的属性值与初始值取差值
            start[name] = parseFloat(getStyle(obj, name) );
            dis[name] = json[name] - start[name];
        }
        // 下方每30毫秒执行一次运动,这里获取运动总次数
        var count = Math.floor(options.duration / 30);
        // 设定运动初始次数
        var n = 0;
        // 清空间歇调用,如果以前定义过则清除动画次数
        clearInterval(obj.timer);
        // 用obj.timer来代替动画次数
        obj.timer = setInterval(function() {
            n++;
            for (var name in json) {
                switch (options.easing) {
                    case 'linear':
                        var cur = start[name] + dis[name] * n / count;
                        break;
                    case 'ease-in':
                        var a = n / count;
                        var cur = start[name] + dis[name] * Math.pow(a, 3);
                        break;
                        // 次数默认使用ease-out
                    case 'ease-out':
                        var a = 1 - n / count;
                        // cur为每次运动后的元素的落脚位置
                        var cur = start[name] + dis[name] * (1 - Math.pow(a, 3));
                        break;
                }
                if (name == 'opacity') {
                    obj.style.opacity = cur;
                    obj.style.filter = 'alpha(opacity:' + cur * 100 + ')';
                } else {
                    obj.style[name] = cur + 'px';
                }
            }
            // 如果运动完成,则清除运动(obj.timer)
            if (n == count) {
                // 清除动画次数
                clearInterval(obj.timer);
                // 回调函数
                options.complete && options.complete();
            }
        }, 30);
    }

    function a2d(n) {
        // n 为弧度 ;弧度转化为角度
        return n * 180 / Math.PI;
    }

    function hoverDir(ev, obj) {
        // 领边长度
        var a = ev.clientX - obj.offsetLeft - obj.offsetWidth / 2;
        // 对边长度
        var b = obj.offsetTop + obj.offsetHeight / 2 - ev.clientY;
        // 通过角度来获得鼠标进入的方向;0为左侧、 1为下 、2为右、 3为上
        // Math.atan2(b, a)为获取弧度公式
        // a2d(n)为获取角度公式
        return Math.round((a2d(Math.atan2(b, a)) + 180) / 90) % 4;
    }

    function through(obj) {
        var oS = obj.children[0]; //这个是li里面的span
        // 鼠标进入的时候
        obj.onmouseenter = function(ev) {
            // 如果不知道ev是啥  就打印出来看看
            console.log(ev)
            // 兼容ie浏览器
            var oEvent = ev || event;
            // obj为li,将oEvent和 li 作为参数,dir为返回值代表着鼠标的进入方向
            var dir = hoverDir(oEvent, obj);
            switch (dir) {
                case 0:
                    //左,oS为li中的 span
                    oS.style.left = '-200px';
                    oS.style.top = 0;
                    break;
                case 1:
                    //
                    oS.style.left = 0;
                    oS.style.top = '200px';
                    break;
                case 2:
                    //
                    oS.style.left = '200px';
                    oS.style.top = 0;
                    break;
                case 3:
                    //
                    oS.style.left = 0;
                    oS.style.top = '-200px';
                    break;
            }
            //oS是li里面的span,设置运动  
            // move(obj, json, options) obj = oS 、 json = { left: 0, top: 0 }、options取默认值,并且没有回调函数
            move(oS, { left: 0, top: 0 });
        };

        // 鼠标离开时
        obj.onmouseleave = function(ev) {
            var oEvent = ev || event;
            var dir = hoverDir(oEvent, obj);
            switch (dir) {
                case 0:
                // move(obj, json, options) obj = oS 、 json = { left: -200, top: 0 }、options取默认值,并且没有回调函数
                    move(oS, { left: -200, top: 0 });
                    break;
                case 1:
                    move(oS, { left: 0, top: 200 });
                    break;
                case 2:
                    move(oS, { left: 200, top: 0 });
                    break;
                case 3:
                    move(oS, { left: 0, top: -200 });
                    break;
            }
        };
    }
    window.onload = function() {
        var aLi = document.getElementsByTagName('li');
        for (var i = 0; i < aLi.length; i++) {
            through(aLi[i]);
        }
    };
    </script>
</head>

<body>
    <ul>
        <li><span></span></li>
        <li><span></span></li>
        <li><span></span></li>
        <li><span></span></li>
        <li><span></span></li>
        <li><span></span></li>
    </ul>
</body>

</html>
原文地址:https://www.cnblogs.com/hss-blog/p/9040431.html