• js运动动画


          今天简单的学了一下js运动动画,再次结构出步骤并附上源码。

          下面是我整理出来的结果。

          知识点一:速度动画。

          1.首先第一步实现速度运动动画,封装一个函数,用到的知识是setInterval(function(){

        oDiv.style.left=oDiv.offsetLeft+10+"px";

      },30).

      对于这里为什么要用到offsetLeft,我特意百度了一下,http://www.cnblogs.com/woshilee/,根据这位博主我得到的有用信息是:

      a.offsetLeft和left的相同之处都是表示子节点相对于父节点的左位置。

      b.但是left是既可以读又可以写的,而offsetLeft是只读的;

      c.并且offsetLeft是没有单位的,获取子节点位置的时候后面不带px。

      这里在引申一下其他的知识,感谢这位博主,http://blog.163.com/hongshaoguoguo@126/blog/static/18046981201372885729561/。

      2.让运动的节点停止下来,这里我们用if语句做一个验证,如果offsetLeft==0,clearInterval(timer),这里的timer应该事先初始化=null,然后将之前的那个运动动画赋值给它。

      3.这里有一个问题,如果在运动结束之前再次触发的运动,那么运动的速度会累加,这里,只要在整个运动开始之前,clearInterval(timer)就可以了。

      4.设置移入移除效果,给运动设置参数,一个是速度speed,一个是目标位置iTarget,我们发现速度也是可以通过ITarget的位置来判断的,所以只需要一个参数即可。

      知识点二:透明度渐变

      1.其实,跟刚刚是差不多的,只不过ITarget的值为透明度而已,流程还是清除定时器再开一个定时器判断等等。

      2.定义一个参数alpha=透明度,注意定时器里面应该这样写:

      alpha+=speed;

      oDiv.style.filter='alpha(opacity:'+alpha+')';         //这是非常重要的一种方法,注意是这样写的

      oDiv.style.opacity=alpha/100;            //注意不要忘记除以100

      3.以上都是行内样式。

      知识点三:缓冲运动

      1.缓冲运动就是距离越大,速度就愈大,距离越小,速度就越小,即速度与距离有关。

      2.根据上面的说法,对速度进行重新的定义,一开始速度为0,而现在:

      var speed=iTarget-oDiv.offsetLeft;

      重新定义定时器:

      oDiv.style.left=oDiv.offsetLeft+speed+'px';

      此时我们发现速度太大了,可以这样:

      var speed=(iTarget-oDiv.offsetLeft)/10;

      3.此时会有一个严重的问题,因为屏幕的最小单位为px,所以会出现最终的left值为小数,而不为目标的iTarget,可以通过判断来解决,这里要引入Math.floor(),这是向下取整,同样还有Math.ceil(),这是向上取整。在定义speed后我们这样写:

      speed=speed>0?Math.ceil(speed):Math.floor(speed);           

      这样就可以完全保证速度都是整数,并且在临界值上都为0

      知识点四:多物体运动  

      1.先获取所有的物体,形成一个数组,然后再用for循环来做(这种方法多么经典呀!),在for循环中添加节点事件,在函数中可以用this代替当前的节点,eg:startMove(this,iTarget),定义函数时startMove(obj,iTarget).

      2.取当前宽度offsetWidth的时候就要用obj的值了。

      3.当鼠标移动特别快的时候,节点的宽度未能恢复原状,这是因为定时器是大家公用的定时器,上一个节点还未恢复原状下一个节点就已经清除定时器了,解决的办法就是给每一个节点加一个index,就是在上面的for循环中加上aDiv[i].timer=null;然后再定义函数中用obj.timer替换timer。由此我们要注意共用定时器会出事的

      4.透明度的运动中,alpha代替了speed,但是即使定时器不共用,多物体的运动也会出现问题,这是因为alpha公用的原因,导致各物体相互撕扯,解决办法就是可以像timer那样在for循环中给每个节点都分配alpha。

          总结:解决冲突问题,要么初始化,要么个性化。

      知识点五.获取样式

      1.在改变节点宽度(移入大,移除小)的定时器中,如果给节点添加一个border边框,那么在移入的时候比目标节点小,移出的时候比目标节点大。注意width+padding+scrollbar(滚动条)+border,所以原因就是每次offset都会增加border*2-(定时器中每次减少的数值)。

      2.解决以上问题的办法就是在行内写入width,并且使用parseInt(oDiv.style.width)代替offsetLeft,但是并不能总是写在行内,所以我们定义一个函数,获取链入样式:

      function getStyle(obj,attr){

        if(obj.currentStyle){

          return obj.currentStyle[attr];                       //ie浏览器 

        }

        else{

          return getComputerStyle(obj,false)[attr];          //其他浏览器

        }

      }

      3.对于font-size这种,在js里只有fontSize这一种写法。

      知识点六:任意属性值

      1.所有的offset-的都会有小bug,要用getStyle函数,这个函数经常和parseInt()一起用,并通常用变量保存。

      2.在写style.width的时候,也可以写成style['width']。  

      3.对于多物体的属性值调整,可以将样式作为参数封装一下,这样多物体属性的函数就包括了(obj,attr,iTarget)这三个属性值。

      4.以上的这个运动框架是不适合于透明度变化的,因为透明度都是小数的,因为两个原因,第一是parseInt,第二是attr=...+px,这里我们可以用一个if判读来对透明度进行单独处理,将parseInt换成parseFloat,去掉px。

      5.计算机本身是有一个bug的,0.07*100并不等于7,所以我们引入一个函数是Math.round(),这是一个四舍五入的值。

      知识点七:链式运动

      1.引入move.js框架。

      2.传入一个回调函数fn(),用if判断,如果有fn(),那么执行fn()。

      知识点八:同时运动

      1.如果写两个运动函数来控制同时运动,会发生函数覆盖。

      2.使用json这个知识点,json的循环是使用for(i in json),运动函数的参数为obj,json,fn。

      3.没有iTarget这个值了,取而代之的是json[attr].

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

    function getStyle(obj,name){ 
    	if (obj.currentStyle) { 
    		return obj.currentStyle[name];
    	}
    	else{ 
    		return getComputedStyle(obj,false)[name];           //注意是computed
    	}
    }
    function startMove(obj,json,fn){ 
    	clearInterval(obj.timer);             //注意是obj.timer
    	obj.timer=setInterval(function(){ 
    		var bStop=true;
    		for(var attr in json){             //注意这一句的写法
    		//一.检测是否为透明度,已经检测当前值
    			var icur=0;
    			if (attr=='opacity') {           //是恒等于
    				icur=Math.round(parseFloat(getStyle(obj,attr))*100);
    			}
    			else{ 
    				icur=parseInt(getStyle(obj,attr));
    			}
    		//二.确定速度
    			var speed=(json[attr]-icur)/6;                   //json[attr]这个值是固定的
    			speed=speed>0?Math.ceil(speed):Math.floor(speed);
    		//三.运动框架
    			if (json[attr]!=icur) { 
    				bStop=false;
    			};
    			if (attr='opacity') { 
    				obj.style.opacity=(icur+speed)/100;           //此时是行内样式
    				obj.style.filter='alpha(opacity:'+(icur+speed)+')';
    			}
    			else{ 
    				obj.style[attr]=icur+speed+'px';
    			};
    			if (bStop) { 
    				clearInterval(obj.timer);           //不要忘记这一步
    				if (fn) { 
    					fn();
    				};
    			};
    		}
    	},30);
    }
    
  • 相关阅读:
    ng-深度学习-课程笔记-1: 介绍深度学习(Week1)
    java发送http请求和多线程
    Spring Cloud Eureka注册中心(快速搭建)
    Spring boot集成Swagger2,并配置多个扫描路径,添加swagger-ui-layer
    springboot在idea的RunDashboard如何显示出来
    Oracle 中select XX_id_seq.nextval from dual 什么意思呢?
    mysql类似to_char()to_date()函数mysql日期和字符相互转换方法date_f
    MySQL的Limit详解
    HikariCP 个人实例
    NBA-2018骑士季后赛
  • 原文地址:https://www.cnblogs.com/dufemeng/p/4324162.html
Copyright © 2020-2023  润新知