穿墙效果附加注释,附加鼠标进入方向算法
<!doctype html> <html> <head> <meta charset="UTF-8"> <title>Title</title> <style> * { margin: 0; padding: 0; list-style: none; } ul { overflow: hidden; width: 630px; margin: 100px auto; } ul li { float: left; position: relative; width: 200px; height: 200px; background: #ccc; margin: 5px; overflow: hidden; } ul li span { position: absolute; width: 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
时间: 2024-11-16 20:58:02