自己实现js运动框架的一些心得
2016-05-07 12:24
796 查看
以前学了js的动画效果,当时看了别人的实现思路,以为自己听懂了,然后没太管,感觉太简单,但是这次做的一个项目中要用到动画效果,想着如果自己都手写一下就太麻烦了,于是想着自己实现一下这个完美运动框架,但是实现的过程中发现,其实没有那么简单,要写一个完美运动框架,那么他就要适合改变各种属性,那么他的参数必须有两个,一个是要改变的元素,第二个是要改变的属性,为了实现多个属性同时运动,我们的第二个参数需要是JSON格式的数据,第三个参数可以是一个回调函数,就是当我们达到目标值后,要执行的函数,看就是下面这个样子
代码中要获取一个元素的属性值,需要有这样的一个函数
这里关于
张鑫旭写的获取元素CSS值之getComputedStyle方法熟悉这篇文章,
看了之后会有一个很好的理解,我理解大概就是这么个意思
getComputedStyle是可以把一个元素所有的样式获取出来;而元素的style只能获取到元素的style属性里面的值,如果元素的样式是外联的,就没办法获取了。
currentStyle是ie出的一个产物,作用和getComputedStyle一样
接着又回过头来讲我们运动框架,先上一般别人的代码
用起来,是没有问题,可是元素要改变的属性如果是opacity的话,他就必须要传入0-100之间的值,这与我们平时写的opacity的值不一样,所以我自己写了一个
我自己写的这个如果属性是opacity就可以写成0到1之间的值了,这里我总结了一条很重要的一点就是动画的当前值加上速度值,一定要在某个阶段等于目标值,我在代码中还专门为那一行做了注释,为了实现这一目标,我们在速度值的时候因为是有小数的存在,一定要在把他变为整数,这样才会到最后为1的时候精确控制目标元素的值,目标元素的值必须为整数,如果不是整数就必须做上述代码中的opacity的值*100然后在取整的操作,就是还原到整数那个阶段,但是这样其实也不太完美,如果opacity的值的小数位大于两位的话,他就有可能不会完美的到达目标值。
希望看到的人赐教。
function startMove (obj, json, fn) { }
代码中要获取一个元素的属性值,需要有这样的一个函数
function getStyle (obj, attr) { if (obj.currentStyle) { return obj.currentStyle[attr]; } else { return getComputedStyle(obj, false)[attr]; } }
这里关于
obj.currentStyle和getComputedStyle可以参考下面这篇文章
张鑫旭写的获取元素CSS值之getComputedStyle方法熟悉这篇文章,
看了之后会有一个很好的理解,我理解大概就是这么个意思
getComputedStyle是可以把一个元素所有的样式获取出来;而元素的style只能获取到元素的style属性里面的值,如果元素的样式是外联的,就没办法获取了。
currentStyle是ie出的一个产物,作用和getComputedStyle一样
接着又回过头来讲我们运动框架,先上一般别人的代码
function startMove(obj, json, fn) { clearInterval(obj.timer); obj.timer = setInterval(function (){ var bStop = true; //这一次运动就结束了——所有的值都到达了 for(var attr in json) { //1.取当前的值 var iCur = 0; if(attr == 'opacity') { iCur = parseInt(parseFloat(getStyle(obj, attr))*100); } else { iCur = parseInt(getStyle(obj, attr)); } //2.算速度 var iSpeed = (json[attr]-iCur)/8; iSpeed = iSpeed > 0?Math.ceil(iSpeed):Math.floor(iSpeed); //3.检测停止 if(iCur!=json[attr]) { bStop=false; } if(attr=='opacity') { obj.style.filter='alpha(opacity:'+(iCur+iSpeed)+')'; obj.style.opacity=(iCur+iSpeed)/100; } else { obj.style[attr]=iCur+iSpeed+'px'; } } if(bStop) { clearInterval(obj.timer); if(fn){ fn(); } } }, 30) }
用起来,是没有问题,可是元素要改变的属性如果是opacity的话,他就必须要传入0-100之间的值,这与我们平时写的opacity的值不一样,所以我自己写了一个
function startMove (obj, json, fn) { clearInterval(obj.timer); obj.timer = setInterval(function () { var bStop = true, cur, speed; for (var attr in json) { if (attr === "opacity") { cur = parseInt((getStyle(obj, attr))*100); //让json[attr]和cur有朝一日能相等 speed = (parseInt(json[attr]*100) - cur)/8; } else { cur = parseInt(getStyle(obj, attr)); speed = (json[attr] - cur)/8; } speed = speed > 0?Math.ceil(speed):Math.floor(speed); if (cur != json[attr]) { bStop = false; } if (attr === "opacity") { obj.style.opacity = (cur + speed)/100; } else { obj.style[attr] = cur + speed + "px"; } } if(bStop) { clearInterval(obj.timer); if (fn) { fn(); } } }, 1000); }
我自己写的这个如果属性是opacity就可以写成0到1之间的值了,这里我总结了一条很重要的一点就是动画的当前值加上速度值,一定要在某个阶段等于目标值,我在代码中还专门为那一行做了注释,为了实现这一目标,我们在速度值的时候因为是有小数的存在,一定要在把他变为整数,这样才会到最后为1的时候精确控制目标元素的值,目标元素的值必须为整数,如果不是整数就必须做上述代码中的opacity的值*100然后在取整的操作,就是还原到整数那个阶段,但是这样其实也不太完美,如果opacity的值的小数位大于两位的话,他就有可能不会完美的到达目标值。
希望看到的人赐教。
相关文章推荐
- JQuery1——基础($对象,选择器,对象转换)
- Android学习笔记(二九):嵌入浏览器
- Android java 与 javascript互访(相互调用)的方法例子
- JavaScript演示排序算法
- javascript实现10进制转为N进制数
- 最后一次说说闭包
- Ajax
- 2019年开发人员应该学习的8个JavaScript框架
- HTML中的script标签研究
- 对一个分号引发的错误研究
- 异步流程控制:7 行代码学会 co 模块
- ES6 走马观花(ECMAScript2015 新特性)
- JavaScript拆分字符串时产生空字符的原因
- Canvas 在高清屏下绘制图片变模糊的解决方法
- Redux系列02:一个炒鸡简单的react+redux例子
- JavaScript 各种遍历方式详解
- call/apply/bind 的理解与实例分享