Maison > Questions et réponses > le corps du texte
大神看下代码:我是学习慕课网上js动画效果时自己尝试制作的。
然后发现几个问题:
非匀速动画
无法控制动画持续时间
动画会在未达到终止条件时产生其他动作(尤其是在动态改变透明度的时候....js在计算小数点的时候那狗一样的长度,小数位居然能够达到8,9位之多,我也是醉了)
若是能修改麻烦替我修改下·····蟹蟹
若是有大神能写个简洁的原生js可多属性联动的动画函数提供参考那就更好了(必须要能够控制动画运行时间,且必须严格按照给定的终止条件终止的那种....)
<!doctype html>
<html lang="en">
<head>
<meta http-equiv='content-type' content='text/html;charset=utf-8' />
<script>
/*--获取id--*/
function $id(id){
return document.getElementById(id);
}
/*----获取元素样式属性值--*/
function $gs(ele,attr){
if (ele.currentStyle)
{
return ele.currentStyle[attr];
}else if (ele.style[attr]!==''){
return ele.style[attr];
}else{
if (window.getComputedStyle(ele,null)[attr]!=='auto')
{
return window.getComputedStyle(ele,null)[attr];
}else{
return 0;
}
}
}
// 多属性动画
function animate(ele,time,json,fn){
window.clearInterval(ele.timer);
var fps=60/1000;
ele.timer=window.setInterval(function(){
for (var a in json)
{
var curVal=(a.search('opacity')!==-1) ? parseFloat($gs(ele,a)) :parseInt($gs(ele,a)); // $gs 是自定义的获取元素某样式值德函数
var unit=(a.search('opacity')!==-1) ? '' : 'px';
var speed=(json[a]-curVal)/(fps*time);
if (speed>=0){
if (curVal>=json[a]){
window.clearInterval(ele.timer);
ele.style[a]=json[a]+unit;
if (fn){
fn();
}
}else{
ele.style[a]=curVal+speed+unit;
}
}else{
if (curVal<=json[a]+0.05){
window.clearInterval(ele.timer);
ele.style[a]=json[a]+unit;
if (fn){
fn();
}
}else{
ele.style[a]=curVal+speed+unit;
}
}
}
},1/fps);
}
</script>
</head>
<body>
<style>
#animate{width:200px;height:200px;background-color:blue;}
</style>
<p id='animate'></p>
<button id='pos'>开始多属性联动动画</button>
<script>
$id('pos').onclick=function(){ // $id(id) 是自定义的快捷获取元素的函数
animate($id('animate'),1000,{width:500,opacity:0},function(){
animate($id('animate'),1000,{width:200,opacity:1});
});
}
</script>
</body>
</html>
巴扎黑2017-04-11 09:24:34
感觉这段代码的问题主要在那个speed变量的计算上
你默认了fps为60帧,speed是每一帧的变化量
但是实际上由于各种因素,浏览器的帧数是不确定的,每帧的时间间隔也是不确定的
所以实际动画进程应该由起始时间与当前时间的差来计算
animate执行的时候,通过Date.now()取起始时间,setInterval里,每次都去Date.now()取一次当前时间
计算两个时间差elapsed与动画时间变量time的比例,就是style的变化比例
当elapsed >= time时视为动画结束
晚点有空的话上代码
补代码
// 多属性动画
var interval = 1000 / 60;
var animate = function animate(ele, time, json, fn) {
if (ele.timer) return;
var startTime = Date.now(),
vals = [];
for (var key in json) {
var curVal = key.search('opacity') !== -1 ? parseFloat($gs(ele, key)) : parseInt($gs(ele, key)),
unit = key.search('opacity') !== -1 ? '' : 'px';
vals.push({ style: key, startVal: curVal, endVal: json[key], unit: unit });
}
ele.timer = setInterval(function () {
var elapsed = Date.now() - startTime;
if (elapsed >= time) {
clearInterval(ele.timer);
ele.timer = null;
for (var i = 0; i < vals.length; i++) {
ele.style[vals[i].style] = vals[i].endVal + vals[i].unit;
}
fn && fn();
} else {
for (var i = 0; i < vals.length; i++) {
ele.style[vals[i].style] = vals[i].startVal + (vals[i].endVal - vals[i].startVal) * (elapsed / time) + vals[i].unit;
}
}
}, interval);
};