JS——动画
来源:互联网 发布:淘宝店铺找谁可以装修 编辑:程序博客网 时间:2024/05/21 18:35
运动实现思路
1. 速度(匀速)
改变left、right、width、height、opacity
实例1(速度)
做一个侧栏分享的案例
思路
容器设置相对定位。
内容原本的left是负值,设置一个定时器,每隔一段时间,露出一点来。
直至offsetLeft为0,结束计时器。
代码
window.onload=function(){ var oDiv=document.getElementById("div1"); oDiv.onmouseover=function(){ startMove(0); } oDiv.onmouseout=function(){ startMove(-200); } } var timer=null; function startMove(iTarget){ clearInterval(timer); var oDiv=document.getElementById("div1"); timer=setInterval(function(){ var speed=0; // 判断该 增 or 减 left if(oDiv.offsetLeft > iTarget){ speed = -10; }else{ speed = 10; } //判断停止或继续运动 if(oDiv.offsetLeft==iTarget){ clearInterval(timer); }else{ oDiv.style.left=oDiv.offsetLeft+speed+"px"; } },30) }
实例2(透明度)
透明度css属性
filter:alpha(opacity:30); 针对 IE8 以及更早的版本 0-100 opacity:0.3; 0~1
思路
跟上面的例子一样,只不过最后操作的属性是透明度。
实例
window.onload=function(){ var oDiv=document.getElementById("div1"); oDiv.onmouseover=function(){ startMove(100); } oDiv.onmouseout=function(){ startMove(30); } } var timer=null, alpha=30; function startMove(iTarget){ clearInterval(timer); var oDiv=document.getElementById("div1"); //每次运动时,先把变量speed清零 timer=setInterval(function(){ var speed=0; if(alpha > iTarget){ speed = -10; }else{ speed = 10; } if(alpha==iTarget){ clearInterval(timer); }else{ alpha+=speed; oDiv.style.filter = "alpha(opacity:'+alpha+')"; oDiv.style.opacity = alpha/100; } },30) }
2. 缓冲(渐慢)
思路
speed = (目标值和当前值的差)/ 数值
当差值大的时候,速度就快。
当差值小的时候,速度就慢。
特别注意
上面的计算会导致小数点的出现,浏览器是向下取整的小数点一直被忽略。
结果,就会导致一直达不到我们所设定的目标值。
因此,我们需要做一些处理。
实例
window.onload=function(){ var oDiv=document.getElementById("div1"); oDiv.onmouseover=function(){ startMove(0); } oDiv.onmouseout=function(){ startMove(-200); } } var timer=null; function startMove(iTarget){ clearInterval(timer); var oDiv=document.getElementById("div1"); timer=setInterval(function(){ var speed = (iTarget-oDiv.offsetLeft)/20; speed = speed>0?Math.ceil(speed):Math.floor(speed); if(oDiv.offsetLeft==iTarget){ clearInterval(timer); }else{ oDiv.style.left=oDiv.offsetLeft+speed+"px"; } },30) }
3. 多物体运动
思路
遍历需要元素,分别加上事件。
由于是多物体,所以需要区分物体是哪一个,把this作为参数也传进去。
每一个物体都应该有子集专属的定时器,所以在循环体设置定时器。
特别注意
在实际工作中,物体肯定会有边框、内外边距。继续使用offset类的属性,将会导致bug出现,所以我们需要获取物体自身的宽高等尺寸属性。
在代码内,封装了一个getStyle方法,IE是通过currentStyle属性获取元素属性的,而其余浏览器则是通过getComputedStyle()方法取得元素属性的。
实例
window.onload=function(){ var aLi = document.getElementsByTagName("li"); //遍历元素 for(var i=0;i<aLi.length;i++){ //每个元素都创建自己的定时器为null aLi[i].timer=null; aLi[i].onmouseover=function(){ //this作为参数传入 startMove(this,400); } aLi[i].onmouseout=function(){ startMove(this,200); } } } //获取属性 function getStyle(obj,attr){ if(obj.currentStyle){ //ie return obj.currentStyle[attr]; } else{ //W3C return getComputedStyle(obj,false)[attr]; } } function startMove(obj,iTarget){ //清除定时器 clearInterval(obj.timer); obj.timer = setInterval(function(){ var icur = parseInt(getStyle(obj,'width')); var speed = (iTarget-icur)/8; speed = speed>0?Math.ceil(speed):Math.floor(speed); if(icur==iTarget){ clearInterval(obj.timer); }else{ obj.style.width = icur+speed+"px"; } },30) }
4. 链式运动
在运动函数内加一个参数,让它执行一个回调函数。
第一版代码
<!doctype html><html><head> <meta charset="utf-8"> <title>链式动画</title> <style> *{ margin:0; padding:0; } ul,li { list-style:none; } ul li { width:200px; height:100px; background:yellow; margin-bottom:20px; border:4px solid #000; filter:alpha(opacity:30); opacity:0.3; } </style> <script> window.onload=function(){ var Li=document.getElementById('li1'); Li.onmouseover= function(){ startMove(Li,'width',400,function(){ alert("done"); }); } } function getStyle(obj, atttr) { if(obj.currentStyle) { return obj.currentStyle[atttr]; } else { return getComputedStyle(obj, false)[atttr]; } } function startMove(obj, attr, iTarget, fn) { clearInterval(obj.timmer); obj.timmer = setInterval(function() { var icur = 0; if(attr == 'opacity') { icur = Math.round(parseFloat(getStyle(obj, attr)) * 100); } else { icur = parseInt(getStyle(obj, attr)); } var speed = (iTarget - icur) / 8; speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); if(icur == iTarget) { clearInterval(obj.timmer); if(fn) { fn(); } } else { if(attr == 'opacity') { obj.style.opacity = (icur + speed) / 100; } else { obj.style[attr] = (icur + speed) + 'px'; } } }, 30); } </script></head> <body> <ul> <li id="li1"></li> </ul> </body></html>
这一版方案存在以下问题:
在屏幕缩放比例为非100%的时候,有可能会导致元素计算宽度问题,从而导致最终无法进行链式运动。
解决思路:
1. 既然是屏幕缩放比例出现问题,那我首先可以提醒一下用户,请他把屏幕分辨率调整为100%
如果是Chrome和FireFox,可以使用window.devicePixelRatio接口查询;
IE使用window.screen.deviceXDPI 和 window.screen.logicalXDPI ;
其他浏览器使用window.outerWidth 和 window.innerWidth 这两个属性。
2. 使用rem相对单位
使用rem相对单位,并且把iTarget变为函数内部变量,传入参数改变为倍数。
这里面有一个问题,getStyle函数获取属性的单位是px,而不是rem,所以需要对icur变量进行处理。
由于现在iTarget是不固定的值,判断条件应该改为icur和最终值的比较。
第二版代码
<!doctype html><html><head> <meta charset="utf-8"> <title>链式动画</title> <style> *{ margin:0; padding:0; } html { font-size:20px; } ul,li { list-style:none; } ul li { width:10rem; height:5rem; background:yellow; margin-bottom:20px; border:4px solid #000; filter:alpha(opacity:30); opacity:0.3; } </style> <script> window.onload=function(){ detectZoom (); var Li=document.getElementById('li1'); Li.onmouseover= function(){ startMove(Li,'width',2,function(){alert("done");}); } } function detectZoom (){ var ratio = 0, screen = window.screen, ua = navigator.userAgent.toLowerCase(); if (window.devicePixelRatio !== undefined) { ratio = window.devicePixelRatio; } else if (~ua.indexOf('msie')) { if (screen.deviceXDPI && screen.logicalXDPI) { ratio = screen.deviceXDPI / screen.logicalXDPI; } } else if (window.outerWidth !== undefined && window.innerWidth !== undefined) { ratio = window.outerWidth / window.innerWidth; } if (ratio){ if(ratio !=1){ alert("为了您的使用体验,请把浏览器缩放比例调整至100%"); } } } function getStyle(obj, atttr) { if(obj.currentStyle) { return obj.currentStyle[atttr]; } else { return getComputedStyle(obj, false)[atttr]; } } function startMove(obj, attr, beishu, fn) { clearInterval(obj.timmer); obj.timmer = setInterval(function() { var icur = 0; if(attr == 'opacity') { icur = Math.round(parseFloat(getStyle(obj, attr)) * 100); } else { icur = parseInt(getStyle(obj, attr))/20; } var iTarget = icur*beishu; var speed = (iTarget - icur) / 15; speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); if(icur >= 20 ) { clearInterval(obj.timmer); if(fn) { fn(); } } else { if(attr == 'opacity') { obj.style.opacity = (icur + speed) / 100; } else { obj.style[attr] = (icur + speed) + 'em'; } } }, 30); } </script></head> <body> <ul> <li id="li1"></li> </ul> </body></html>
5. 同时运动
使用json储存我们的属性和目标值。
另外,停止条件改为所有属性变为目标值。为此,我们声明一个变量flag,还有属性未达到目标值,flag为false,不能停止。
实例代码
<!doctype html><html><head> <meta charset="utf-8"> <title>同时运动</title> <style> *{ margin:0; padding:0; } ul,li { list-style:none; } ul li { width:200px; height:100px; background:yellow; margin-bottom:20px; border:4px solid #000; filter:alpha(opacity:30); opacity:0.3; } </style> <script> window.onload=function(){ var oLi=document.getElementById("li1"); oLi.onmouseover=function(){ startMove(oLi,{width:400,height:201,opacity:100}); } oLi.onmouseout=function(){ startMove(oLi,{width:200,height:100,opacity:30}); } } function getStyle(obj,attr){ if(obj.currentStyle){ //ie return obj.currentStyle[attr]; } else{ //W3C return getComputedStyle(obj,false)[attr]; } } function startMove(obj,json,fn){ clearInterval(obj.timer); obj.timer = setInterval(function(){ var flag = true;//假设所有的运动都到达了目标值 for(var attr in json){ //1.取当前的值 var icur=0; if(attr == 'opacity'){ icur = Math.round(parseFloat(getStyle(obj,attr))*100); } else{ icur = parseInt(getStyle(obj,attr)); } //2.算速度 var speed = (json[attr]-icur)/8; speed = speed>0?Math.ceil(speed):Math.floor(speed); //3.检测停止 if(icur!=json[attr]){ //如果不是所有的目标都到达目标值 flag = false; } if(attr == 'opacity') { obj.style.filter = 'alpha(opacity:'+(icur+speed)+')'; obj.style.opacity=(icur+speed)/100; } else { obj.style[ attr] = icur+speed+"px"; } } if(flag) { clearInterval(obj.timer); if(fn){ fn(); } } },30) } </script> </head> <body> <ul> <li id="li1"></li> </ul> </body></html>
- JS——动画
- js——小动画
- 【15】vue.js — 动画
- js动画(1)——速度动画
- js动画(2)——透明度动画
- js动画(3)——缓冲动画
- js动画——图片轮播
- 性能更好的js动画实现方式——requestAnimationFrame
- 性能更好的js动画实现方式——requestAnimationFrame
- bootstrap js插件篇——动画过渡、模态弹窗
- 性能更好的js动画实现方式——requestAnimationFrame
- js动画(4)——多物体运动
- 性能更好的js动画实现方式——requestAnimationFrame
- 性能更好的js动画实现方式——requestAnimationFrame
- 性能更好的js动画实现方式——requestAnimationFrame
- js -- 动画
- js动画
- JS动画
- Js apply()使用详解
- C# 经典练习题——百钱买百鸡
- GPU下caffe训练cifar10
- 《OC基础教程》读书笔记9-特性(set and get)
- (运维监控)supervisor 管理进程-入门
- JS——动画
- angular material2 控件动画失效
- 深克隆
- JSP中实现当前年份前后二十年的选择的下拉框
- EventBus3.0 使用
- Flume
- python基础:(2)第一个程序
- Bootstrap模态对话框中显示动态内容
- 9月21日云栖精选夜读:专访新浪微博黄波:千人千面,机器学习赋能用户信息流消费