使用requestAnimationFrame做动画效果一

时间:2023-03-10 01:22:09
使用requestAnimationFrame做动画效果一

最近学习了requestAnimationFrame,看了张鑫旭直白易懂,但是某些地方语言过于裸露的文章http://www.zhangxinxu.com/wordpress/2013/09/css3-animation-requestanimationframe-tween-%E5%8A%A8%E7%94%BB%E7%AE%97%E6%B3%95/,文章里的例子:http://www.zhangxinxu.com/study/201309/requestanimationframe-tween-easeoutbounce.html让我觉得这个requestAnimationFrame很厉害,虽然我对动画的接触还不多,但是我会努力的。

requestAnimationFrame是什么么?

requestAnimationFrame 是专门为实现高性能的帧动画而设计的一个API:

说简单点

    • setInterval、setTimeout是开发者主动要求浏览器去绘制,但是由于种种问题,浏览器可能会漏掉部分命令
    • requestAnimationFrame 就是浏览器什么要开始绘制了浏览器自己知道,通过requestAnimationFrame 告诉开发者,这样就不会出现重复绘制丢失的问题了
    • requestAnimationFrame 会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧
    • 隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的的cpu,gpu和内存使用量。
    • requestAnimationFrame也会像setTimeout一样有一个返回值ID用于取消,可以把它作为参数传入cancelAnimationFrame函数来取消requestAnimationFrame的回调

下面是一个简单的例子:



<!doctype html><img id="book" style="background:red;opacity:1;position: relative; left: 500px;" alt="" width="100" height="123" data-mce-style="background: red; opacity: 1; position: relative; left: 500px;" /><div id="several"><br /></div><script type="text/javascript">

var book = document.getElementById('book')
var several = document.getElementById('several');

animate(book, {
left: 50,
duration: 2000
})

function animate(elem, options){
//动画初始值
var start = 500
//动画结束值
var end = options.left
//动画id
var timerId;
var createTime = function(){
return (+new Date)
}
//动画开始时间
var startTime = createTime();
var i = 0;

function tick(){
i++;
several.innerHTML = 'setInterval调用次数:' + i;
//每次变化的时间
var remaining = Math.max(0, startTime + options.duration - createTime())
var temp = remaining / options.duration || 0;
var percent = 1 - temp;
var stop = function(){
//停止动画
clearInterval(timerId);
timerId = null;
}
var setStyle = function(value){
elem.style['left'] = value + 'px'
}
//移动的距离
var now = (end - start) * percent + start;
if(percent === 1){
setStyle(now)
stop();
}else{
setStyle(now)
}
}

//开始执行动画
var timerId = setInterval(tick, 13);
}
</script>
    此处不用点了,因为我无法向页面添加js代码,可是,为什么我看到别人的博客中可以呢,伤心。

      function runCode(cod1) {
var cod = window.document.all(cod1)
var code = cod.value;
var newwin = window.document.open('', '', '');
newwin.opener = null
newwin.document.write(code);
newwin.document.close();
}

我做了个练习:

每隔1s长生一个小方块,让其匀速下落,落到底部消失,如果碰到底部中间的方块,小方块消失,分数加1,这个例子还有很多不足的地方,我会继续完善:

 <script>
window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
var h=0;
var timer=setInterval(function(){
if(h>40){
clearInterval(timer);return;
}else{
h+=1;
var isSucceed;
var isOnBelow;
var isStillOn;
var dotX;
var dot=new Dot();
dotX=dot.getName();
isStillOn=true;
animate(dot.dom, {
top: window.innerHeight-dot.dom.offsetHeight,
duration: 3000
});
function animate(elem, options){
//动画初始值
var start = 0
//动画结束值
var end = options.top
var createTime = function(){
return (+new Date)
}
//动画开始时间
var startTime = createTime();
var timerId;
//开始动画
var startAnim = function() {
timerId = requestAnimationFrame(tick,15);
}
//停止动画
var stopAnim = function() {
cancelAnimationFrame(timerId)
}
var number=0;
var isRemove=true;
function tick(){
number++;
//每次变化的时间
var remaining = Math.max(0, startTime + options.duration - createTime())
var temp = remaining / options.duration || 0;
var percent = 1 - temp;
var setStyle = function(value){
elem.style['top'] = value + 'px';
var centerW=center.offsetLeft;
var centerH=center.offsetTop;
if(value>=(centerH-42)){
isOnBelow=true;
}else{
isOnBelow=false;
}
if(dotX>=(centerW-50)&&dotX<=(centerW+200)){
isSucceed=true;
}else{
isSucceed=false;
}
}
if(isRemove&&isOnBelow&&isSucceed){
isRemove=false;
stopAnim() ;
document.getElementById("view").removeChild(elem);
isStillOn=false;
count++;
document.getElementById("count").innerHTML="总分为:"+count+"分";
}
//移动的距离
var now = (end - start) * percent + start;
if(percent === 1){
setStyle(now);
if(isStillOn){
document.getElementById("view").removeChild(elem);
}
stopAnim() ;
}else{
setStyle(now);
startAnim(tick);
}
}
//开始执行动画
startAnim(tick);
}
}},1000)
document.getElementById("center").addEventListener("touchmove",function(e){
var touch=e.targetTouches[0].pageX;
// if(touch<0){touch=100;}
// if(touch>(document.body.clientWidth-center.clientWidth)){touch=document.body.clientWidth-center.clientWidth+100}
document.getElementById("center").style.left=touch+"px";
}); </script>