javascript 小型动画组件与实现代码_PHP教程
做一个普通的动画效果,js是怎么完成的呢.看一下例子
setInterval(function(){
element.style.left =parseFloat(element.style.left) +(n) +'px';
},10);
[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]
用window.setInterval 动画函数 ,每隔10毫秒 都会去执行一次动画 ;
和 set配套的是 clearInterval 函数,用来结束动画。
每隔setInterval 都会返回一个类似于线程id的值 ;
var interval =setInterval(function(){
element.style.left =parseFloat(element.style.left) +(n) +'px';
},10);
用 clearInterval (interval) 既可结束动画播放.
interval = setInterval(function(){
if(parseFloat(element.style.left)>500) clearInterval(interval)
element.style.left =parseFloat(element.style.left) +2 +'px';
},10);
超过500px的时候,动画就会停止, element将不在移动。
[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]
但是上面的动画是比较生硬的,然后我们有另外一种时间线动画。
看例子:
var element = document.getElementById('test1');
var start = +new Date,dur=1000,finish = start+dur;
interval = setInterval(function(){
var time = +new Date,
pos = time > finish ? 1 : (time-start)/dur;
element.style.left = (100*pos)+"px";
if(time>finish) {
clearInterval(interval);
}
},10);
start 为目标动画的开始时间 ( +new Date 其实就是 new Date().getTime() )
dur 为 动画执行一共所需要的时间
finish 是目标动画结束的时间
pos = time > finish ? 1 : (time-start)/dur; //可以把pos 想象成频率 ,一个时间比
(100*pos) ,100代表距离,,如果距离为500px 就设置为 500*pos;
time>finish : 如果超过时间,就停止动画!
[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]
很好,到这里我们已经知道一个简单动画效果是怎么样写的了.
再来看一个小型的完整的动画组件是如何写的 :
(function($,name){
var parseEl = document.createElement('div')
,
props = ('backgroundColor borderBottomColor borderBottomWidth borderLeftColor borderLeftWidth '+
'borderRightColor borderRightWidth borderSpacing borderTopColor borderTopWidth bottom color fontSize '+
'fontWeight height left letterSpacing lineHeight marginBottom marginLeft marginRight marginTop maxHeight '+
'maxWidth minHeight minWidth opacity outlineColor outlineOffset outlineWidth paddingBottom paddingLeft '+
'paddingRight paddingTop right textIndent top width wordSpacing zIndex').split(' ')
,
normalize =function (style){
var css,
rules = {},
i = props.length,
v;
parseEl.innerHTML = '';
css = parseEl.childNodes[0].style;
while(i--) if(v = css[props[i]]) rules[props[i]] = parse(v);
return rules;
},
color = function(source,target,pos){
var i = 2, j, c, tmp, v = [], r = [];
while(j=3,c=arguments[i-1],i--)
if(s(c,0)=='r') { c = c.match(/\d+/g); while(j--) v.push(~~c[j]); } else {
if(c.length==4) c='#'+s(c,1)+s(c,1)+s(c,2)+s(c,2)+s(c,3)+s(c,3);
while(j--) v.push(parseInt(s(c,1+j*2,2), 16)); }
while(j--) { tmp = ~~(v[j+3]+(v[j]-v[j+3])*pos); r.push(tmp255?255:tmp); }
return 'rgb('+r.join(',')+')';
},
parse = function(prop){
var p = parseFloat(prop), q = prop.replace(/^[\-\d\.]+/,'');
return isNaN(p) ? { v: q, f: color, u: ''} : { v: p, f: interpolate, u: q };
},
s = function(str, p, c){
return str.substr(p,c||1);//color 用
},
interpolate =function(source,target,pos){
return (source+(target-source)*pos).toFixed(3);
},
flower = function(el, style,opts,after){
var el = document.getElementById(el), //通过id获取元素对象
opts = opts || {},
target = normalize(style),
comp = el.currentStyle ? el.currentStyle : getComputedStyle(el, null), //ie和w3c兼容,获取样式
prop,
current = {},
start = +new Date, //开始时间
dur = opts.duration||200, //执行事件,默认为200
finish = start+dur, //结束时间
interval,
easing = opts.easing || function(pos){ return (-Math.cos(pos*Math.PI)/2) + 0.5; };
for(prop in target) current[prop] = parse(comp[prop]);
interval = setInterval(function(){
var time = +new Date,
pos = time>finish ? 1 : (time-start)/dur;
for(prop in target){
el.style[prop] = target[prop].f(current[prop].v,target[prop].v,easing(pos)) + target[prop].u;
}
if(time>finish) {
clearInterval(interval); opts.after && opts.after(); after && setTimeout(after,1);
}
},10);
};
$[name] = flower;
})(window,"flower");
var parse = function(prop){
var p = parseFloat(prop), q = prop.replace(/^[\-\d\.]+/,'');
return isNaN(p) ? { v: q, f: color, u: ''} : { v: p, f: interpolate, u: q };
}
var p = parseFloat(prop) 意思是 : 500px => 500;
q = prop.replace(/^[\-\d\.]+/,''); 500px => px;
return isNaN(p) ? { v: q, f: color, u: ''} : { v: p, f: interpolate, u: q }; 意思是 如果取的是颜色值(因为带有#号),返回{ v: q, f: color, u: ''} u 代表代为,f是一个color函数(后面会讲到);
var s = function(str, p, c){ return str.substr(p,c||1); }
s 函数是用来截取字符串,并将最后结果返回
color 函数 将颜色值,最后统一返回 "rgb(x,x,x)" 的形式
normalize 函数 返回一个json对象,对象里包含了该元素要执行的css属性名和值
while(i--) if(v = css[props[i]]) rules[props[i]] = parse(v);
把一行代码拆开,看看到底如何作用
while(i--){
//这里用了一个 =号, 先进行赋值运算,如果不存在之 if将不通过, 一举两得 : )
if(v = css[props[i]]){
rules[props[i]] = parse(v); //赋给新的对象,
}
}
interpolate函数中 return (source+(target-source)*pos).toFixed(3);
toFixed 是为了解决小数问题,如 0.000000001; 会变成 1e-9; 不是我们想要的结果,通过toFixed 可以解决, toFixed (n), 其中n代表保留小数点后几位
el.currentStyle ? el.currentStyle : getComputedStyle(el, null);
这个其实兼容多浏览器,获取元素的一句代码 具体参考 : JS 获取最终样式 【getStyle】
flower的 4个参数 el 目标对象,style 是最终样式,opts,是参数选项包括 (dur时间,easing缓懂函数,after结束后运行的callbak) ,第4个after是最后执行的callbak;
opts.easing 可以利用各种缓动算法,来改变元素的运动状态;
如
function bounce(pos) {
if (pos return (7.5625*pos*pos);
} else if (pos return (7.5625*(pos-=(1.5/2.75))*pos + .75);
} else if (pos return (7.5625*(pos-=(2.25/2.75))*pos + .9375);
} else {
return (7.5625*(pos-=(2.625/2.75))*pos + .984375);
}
}
(function($,name){
window.flower = flower;
})(window,'flower');
这样其实就是让内部函数自由,并且只通过这个调用去暴露一个接口。不然外面的函数,访问不到匿名函授中的flower;
看一下调用的例子 : )
<script> <BR>(function($,name){ <BR>var parseEl = document.createElement('div') <BR>, <BR>props = ('backgroundColor borderBottomColor borderBottomWidth borderLeftColor borderLeftWidth '+ <BR>'borderRightColor borderRightWidth borderSpacing borderTopColor borderTopWidth bottom color fontSize '+ <BR>'fontWeight height left letterSpacing lineHeight marginBottom marginLeft marginRight marginTop maxHeight '+ <BR>'maxWidth minHeight minWidth opacity outlineColor outlineOffset outlineWidth paddingBottom paddingLeft '+ <BR>'paddingRight paddingTop right textIndent top width wordSpacing zIndex').split(' ') <BR>, <BR>normalize =function (style){ <BR>var css, <BR>rules = {}, <BR>i = props.length, <BR>v; <BR>parseEl.innerHTML = '<div style="'+style+'"></script>
css = parseEl.childNodes[0].style;
while(i--) if(v = css[props[i]]) rules[props[i]] = parse(v);
return rules;
},
color = function(source,target,pos){
var i = 2, j, c, tmp, v = [], r = [];
while(j=3,c=arguments[i-1],i--)
if(s(c,0)=='r') { c = c.match(/\d+/g); while(j--) v.push(~~c[j]); } else {
if(c.length==4) c='#'+s(c,1)+s(c,1)+s(c,2)+s(c,2)+s(c,3)+s(c,3);
while(j--) v.push(parseInt(s(c,1+j*2,2), 16)); }
while(j--) { tmp = ~~(v[j+3]+(v[j]-v[j+3])*pos); r.push(tmp255?255:tmp); }
return 'rgb('+r.join(',')+')';
},
parse = function(prop){
var p = parseFloat(prop), q = prop.replace(/^[\-\d\.]+/,'');
return isNaN(p) ? { v: q, f: color, u: ''} : { v: p, f: interpolate, u: q };
},
s = function(str, p, c){
return str.substr(p,c||1);
},
interpolate =function(source,target,pos){
return (source+(target-source)*pos).toFixed(3);
},
flower = function(el, style,opts,after){
var el = document.getElementById(el),
opts = opts || {},
target = normalize(style),
comp = el.currentStyle ? el.currentStyle : getComputedStyle(el, null),
prop,
current = {},
start = +new Date,
dur = opts.duration||200,
finish = start+dur,
interval,
easing = opts.easing || function(pos){ return (-Math.cos(pos*Math.PI)/2) + 0.5; };
for(prop in target) current[prop] = parse(comp[prop]);
interval = setInterval(function(){
var time = +new Date,
pos = time>finish ? 1 : (time-start)/dur;
for(prop in target){
el.style[prop] = target[prop].f(current[prop].v,target[prop].v,easing(pos)) + target[prop].u;
}
if(time>finish) {
clearInterval(interval); opts.after && opts.after(); after && setTimeout(after,1);
}
},10);
};
$[name] = flower;
})(window,"flower");
(function(){
var bounce = function(pos) {
if (pos return (7.5625*pos*pos);
} else if (pos return (7.5625*(pos-=(1.5/2.75))*pos + .75);
} else if (pos return (7.5625*(pos-=(2.25/2.75))*pos + .9375);
} else {
return (7.5625*(pos-=(2.625/2.75))*pos + .984375);
}
}
flower('test2', 'left:300px;padding:10px;border:50px solid #ff0000', {
duration: 1500,
after: function(){
flower('test1', 'background:#0f0;left:100px;padding-bottom:100px;opacity:1', {
duration: 1234, easing: bounce
});
}
});
})();
参考 : http://scripty2.com/doc/scripty2%20fx/s2/fx/transitions.html

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

你可能遇到过智能手机屏幕出现绿色线条的问题,即使没见过,也一定在网络上看到过相关图片。那么,智能手表屏幕变白的情况你遇见过吗?4月2日,CNMO从外媒了解到,一名Reddit用户在社交平台上分享了一张图片,展示了三星Watch系列智能手表屏幕变白的情况。该用户写道:"我离开时正在充电,回来时就这样了,我尝试重启,但重启过程中屏幕还是这样。"三星Watch智能手表屏幕变白这位Reddit用户并未指明这款智能手表的具体型号。不过,从图片上看,应该是三星Watch5。此前,另一位Reddit用户也报告

华为手机如何实现双微信登录?随着社交媒体的兴起,微信已经成为人们日常生活中不可或缺的沟通工具之一。然而,许多人可能会遇到一个问题:在同一部手机上同时登录多个微信账号。对于华为手机用户来说,实现双微信登录并不困难,本文将介绍华为手机如何实现双微信登录的方法。首先,华为手机自带的EMUI系统提供了一个很便利的功能——应用双开。通过应用双开功能,用户可以在手机上同

说起阿萨辛ASSASSIN,相信玩家们一定会想到《刺客信条》中的各位刺客大师,不仅身手了得,而且"躬身于黑暗、服务于光明"的信条,与国内知名机箱/电源/散热器品牌九州风神(DeepCool)旗下的阿萨辛ASSASSIN系列旗舰级风冷散热器不谋而合。最近,该系列的最新产品阿萨辛ASSASSIN4S重磅上线,"西装刺客,再进阶"为高级玩家带来全新的风冷散热体验。外观一览细节满满阿萨辛4S散热器采用双塔构造+单风扇内嵌设计,外面包覆立方体造型的整流罩,整体感极强,并提供白、黑两种配色可选,满足不同色系

随着春天的到来,万物复苏,一切都充满了生机与活力。在这个美好的季节里,如何为家居生活增添一抹别样的色彩?哈趣H2投影仪,以其精致的设计和超高的性价比,成为了这个春天里不可或缺的一道亮丽风景。这款H2投影仪小巧玲珑却不失时尚。无论是放在客厅的电视柜上,还是卧室的床头柜旁,都能成为一道亮丽的风景线。它的机身采用了奶白色的磨砂质地,这种设计不仅让投影仪的外观更显高级,同时也增加了触感的舒适度。米色仿皮纹材质,更是为整体外观增添了一抹温馨与雅致。这种色彩与材质的搭配,既符合现代家居的审美趋势,又能够融入

ITX平台以小巧的身形吸引了不少追求极致和独特美感的玩家,随着制程的提升和技术的进步,英特尔第14代酷睿和RTX40系显卡都可以在ITX平台中发挥实力,游戏玩家也对SFX电源有了更高的要求。游戏爱好者航嘉推出新的MX系列电源,在满足高性能需求的ITX平台中,MX750P全模组电源的定额功率高达750W,同时通过了80PLUS白金级认证。以下我们就带来这款电源的评测。航嘉MX750P全模组电源采用了简约时尚的设计理念,共有黑白两款供玩家选择,均采用磨砂表面处理,搭配银灰色和红色的字体有很好的质感,

如何在华为手机上实现微信分身功能随着社交软件的普及和人们对隐私安全的日益重视,微信分身功能逐渐成为人们关注的焦点。微信分身功能可以帮助用户在同一台手机上同时登录多个微信账号,方便管理和使用。在华为手机上实现微信分身功能并不困难,只需要按照以下步骤操作即可。第一步:确保手机系统版本和微信版本符合要求首先,确保你的华为手机系统版本已更新到最新版本,以及微信App

一个可以自动分析PDF、网页、海报、Excel图表内容的大模型,对于打工人来说简直不要太方便。上海AILab,香港中文大学等研究机构提出的InternLM-XComposer2-4KHD(简写为IXC2-4KHD)模型让这成为了现实。相比于其他多模态大模型不超过1500x1500的分辨率限制,该工作将多模态大模型的最大输入图像提升到超过4K(3840x1600)分辨率,并支持任意长宽比和336像素~4K动态分辨率变化。发布三天,该模型就登顶HuggingFace视觉问答模型热度榜单第一。轻松拿捏

在当今智能手机市场中,屏幕素质已经成为衡量一款手机综合性能的关键指标之一。iQOO旗下的Neo系列一直致力于为用户提供出色的游戏体验和视觉享受,最新款产品iQOONeo9SPro+更是采用一块"三好护眼电竞屏",接下来我们就来一起看看这块屏幕的素质有多出色。iQOONeo9SPro+搭载了一块1.5KOLED电竞直屏,支持从1Hz到144Hz的旗舰级LTPO自适应刷新率,意味着在显示静态内容时能够实现超低功耗的待机状态,而在游戏过程中也能智能切换至90Hz至144Hz的动态高
