<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#div {
width: 100px;
height: 100px;
background-color: #00a8c6;
position: absolute;
} #block {
width: 80px;
height: 80px;
background-color: #0a001f;
position: absolute;
margin-left: 120px;
} #blockTwo {
width: 80px;
height: 80px;
background-color: #00FA9A;
position: absolute;
margin-left: 190px;
} #ball {
width: 100px;
height: 100px;
border-radius: 50px;
border: solid rgb(100, 100, 100) 1px;
position: absolute;
margin-top: 100px;
background-color: #1b1b1b;
} #car {
width: 80px;
height: 80px;
background-color: #4B0082;
position: absolute;
margin-left: 220px;
} #stone {
width: 50px;
height: 50px;
border-radius: 25px;
border: solid rgb(100, 100, 100) 1px;
position: absolute;
margin-top: 150px;
margin-left: 150px;
background-color: #8B0000;
} #SinMove {
width: 50px;
height: 50px;
border-radius: 25px;
border: solid rgb(100, 100, 100) 1px;
position: absolute;
margin-top: 800px;
margin-left: 220px;
background-color: #00FA9A;
} #CircleMove {
width: 50px;
height: 50px;
background-color: #4B0082;
margin-top: 500px;
margin-left: 500px;
} #moveAny {
width: 100px;
height: 100px;
border-radius: 50px;
border: solid rgb(100, 100, 100) 1px;
position: absolute;
margin-top: 800px;
margin-left: 220px;
background-color: #7FFF00;
text-align: center;
padding-top: 20px;
} #controlPan {
margin-top: 400px;
border: 2px solid blue;
height: 400px;
width: auto;
}
</style> <!--1.实现一个简单的div块元素-->
<script>
var id; var direct = -1;
var times = 0; function step() {
times++; // 获取这个块元素
var div = document.getElementById("div"); console.log(div.offsetLeft);
if (div.offsetLeft == 800) {
direct = 0;
} else if (div.offsetLeft == 8) {
direct = 1;
} if (direct == 1) {
// 设置这个div元素向左的偏移量
var temp = div.offsetLeft + 2;
// 设置坐标的距离
div.style.left = temp + "px";
} else if (direct == 0) {
// 设置这个div元素向左的偏移量
var temp = div.offsetLeft - 2;
// 设置坐标的距离
div.style.left = temp + "px";
} //和setTimeout一样,要手动调用才能实现连续动画。
id = window.requestAnimationFrame(step); //返回值是一个id,可以通过这个id来取消 // 复杂的计算
for (var i = 0; i < 50; i++) {
console.log("再牛逼的定时器也得等到我执行完才能执行");
} //取消回调函数
if (times == 0) {
window.cancelAnimationFrame(id);
} } // 第一次调用
//id = window.requestAnimationFrame(step); </script> <!--2.setTimeout和setInterval深入理解-->
<script>
/*console.log("1");
setTimeout(function () {
console.log("3");
}, 0);
console.log("2"); // 输出: 1 2 3*/
// 2. 使用动画的正确姿势,动画其实是 “位移”关于“时间”的函数:s=f(t)
// 解决动画变慢的问题:把动画与时间关联起来
function startAnimation() {
var startTime = Date.now();
requestAnimationFrame(function change(time) {
var current = Date.now() - startTime;
console.log("动画已经执行的时间为:" + current);
requestAnimationFrame(startAnimation);
});
} //startAnimation(); // 动画通常情况下有终止时间,如果是循环动画,我们也可以看做特殊的——当动画达到终止时间之后,重新开始动画。因此,我们可以将动画时间归一(Normalize)表示:
//duration 是动画执行时间 isLoop是否为循环执行。
function startAnimation(duration, isLoop) {
var startTime = Date.now(); requestAnimationFrame(function change() {
// 动画已经用去的时间占总时间的比值
var p = (Date.now() - startTime) / duration;
//console.log(p); if (p >= 1.0) {
if (isLoop) { // 如果是循环执行,则开启下一个循环周期。并且把开始时间改成上个周期的结束时间
startTime += duration;
p -= 1.0; //动画进度初始化
} else {
p = 1.0; //如果不是循环,则把时间进度至为 1.0 表示动画执行结束
}
}
console.log("动画已执行进度", p);
if (p < 1.0) { //如果小于1.0表示动画还诶有值完毕,继续执行动画。
requestAnimationFrame(change);
}
});
} //startAnimation(100, true); // 示例1:用时间控制动画周期精确到2s中
function blockClick(obj) {
var block = document.getElementById("block"); var self = obj,
startTime = Date.now(),
duration = 2000;
// 添加一个动画
setInterval(function () {
var p = (Date.now() - startTime) / duration;
// 时间已经完成了2000的比例,则360度也是进行了这么个比例。
self.style.transform = "rotate(" + (360 * p) + "deg)";
}, 100); } // 示例2:让滑块在2秒内向右匀速移动600px
function blockTwoClick(obj) {
var self = obj;
var startTime = Date.now(),
distance = 600,
duration = 2000; requestAnimationFrame(function step(time) {
var p = Math.min(1.0, (Date.now() - startTime) / duration);
//沿着X方向运动
self.style.transform = "translateX(" + (distance * p) + "px)";
// 如果动画没有执行完毕, 就继续执行
if (p < 1.0) {
requestAnimationFrame(step);
}
})
}; // 实例3: 实现小球的自由落体运动
function ballClick(obj) {
var self = obj,
startTime = Date.now(),
distance = 1000,
duration = 1500;
requestAnimationFrame(function step() {
var p = Math.min(1.0, (Date.now() - startTime) / duration);
self.style.transform = "translateY(" + (distance * p * p) + "px)";
if (p < 1.0) requestAnimationFrame(step);
}); } // 实例4 : 实现汽车的匀减速运动
function carClick(obj) {
var self = obj, startTime = Date.now(),
distance = 1000, duration = 2000;
requestAnimationFrame(function step() {
var p = Math.min(1.0, (Date.now() - startTime) / duration);
self.style.transform = "translateX("
+ (distance * p * (2 - p)) + "px)";
if (p < 1.0) requestAnimationFrame(step);
}); } // 实例5 : 水平抛物运动
function stoneClick(obj) {
var self = obj, startTime = Date.now(),
disX = 1000, disY = 1000,
duration = Math.sqrt(2 * disY / 10 / 9.8) * 1000; // 落到地面需要的时间 单位ms
//假设10px是1米,disY = 100米 requestAnimationFrame(function step() {
var p = Math.min(1.0, (Date.now() - startTime) / duration);
var tx = disX * p; //水平方向是匀速运动
var ty = disY * p * p; //垂直方向是匀加速运动 self.style.transform = "translate("
+ tx + "px" + "," + ty + "px)";
if (p < 1.0) requestAnimationFrame(step);
}); } // 实例6 : 正弦曲线运动
function SinMoveClick(obj) {
var self = obj, startTime = Date.now(),
distance = 800,
duration = 5000; requestAnimationFrame(function step() {
var p = Math.min(1.0, (Date.now() - startTime) / duration);
var ty = distance * Math.sin(2 * Math.PI * p);
var tx = 2 * distance * p; self.style.transform = "translate("
+ tx + "px," + ty + "px)";
if (p < 1.0) requestAnimationFrame(step);
}); } // 实例7 : 圆周运动
function CircleMoveClick(obj) {
var self = obj,
startTime = Date.now(),
r = 100,
duration = 2000; requestAnimationFrame(function step() {
var p = Math.min(1.0, (Date.now() - startTime) / duration);
var tx = r * Math.sin(2 * Math.PI * p),
ty = -r * Math.cos(2 * Math.PI * p); self.style.transform = "translate(" +
tx + "px," + ty + "px)";
requestAnimationFrame(step);
});
} // 实现动画算子的封装
// pow() 方法可返回 x 的 y 次幂的值
var pow = Math.pow,
BACK_CONST = 1.70158;
// t指的的是动画进度 前面的p
Easing = {
// 匀速运动
linear: function (t) {
return t;
},
// 加速运动
easeIn: function (t) {
return t * t;
},
// 减速运动
easeOut: function (t) {
return (2 - t) * t;
},
//先加速后减速
easeBoth: function (t) {
return (t *= 2) < 1 ? .5 * t * t : .5 * (1 - (--t) * (t - 2));
},
// 4次方加速
easeInStrong: function (t) {
return t * t * t * t;
},
// 4次方法的减速
easeOutStrong: function (t) {
return 1 - (--t) * t * t * t;
},
// 先加速后减速,加速和减速的都比较剧烈
easeBothStrong: function (t) {
return (t *= 2) < 1 ? .5 * t * t * t * t : .5 * (2 - (t -= 2) * t * t * t);
},
//
easeOutQuart: function (t) {
return -(Math.pow((t - 1), 4) - 1)
},
// 指数变化 加减速
easeInOutExpo: function (t) {
if (t === 0) return 0;
if (t === 1) return 1;
if ((t /= 0.5) < 1) return 0.5 * Math.pow(2, 10 * (t - 1));
return 0.5 * (-Math.pow(2, -10 * --t) + 2);
},
//指数式减速
easeOutExpo: function (t) {
return (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1;
},
// 先回弹,再加速
swingFrom: function (t) {
return t * t * ((BACK_CONST + 1) * t - BACK_CONST);
}, // 多走一段,再慢慢的回弹
swingTo: function (t) {
return (t -= 1) * t * ((BACK_CONST + 1) * t + BACK_CONST) + 1;
}, //弹跳
bounce: function (t) {
var s = 7.5625,
r; if (t < (1 / 2.75)) {
r = s * t * t;
} else if (t < (2 / 2.75)) {
r = s * (t -= (1.5 / 2.75)) * t + .75;
} else if (t < (2.5 / 2.75)) {
r = s * (t -= (2.25 / 2.75)) * t + .9375;
} else {
r = s * (t -= (2.625 / 2.75)) * t + .984375;
} return r;
}
}; /*
参数1:动画的执行时间
参数2:动画执行的时候的回调函数(动画执行的要干的事情)
参数3:动画算子. 如果没有传入动画算子,则默认使用匀速算子
*/
function Animator(duration, progress, easing) {
this.duration = duration;
this.progress = progress;
this.easing = easing || function (p) {
return p
};
} Animator.prototype = {
/*开始动画的方法,
参数:一个布尔值
true表示动画不循环执行。
*/
start: function (finished) {
/*动画开始时间*/
var startTime = Date.now();
/*动画执行时间*/
var duration = this.duration,
self = this;
/*定义动画执行函数*/
requestAnimationFrame(function step() {
/*得到动画执行进度*/
var p = (Date.now() - startTime) / duration;
/*是否执行下一帧动画*/
var next = true;
/*判断动画进度是否完成*/
if (p < 1.0) {
self.progress(self.easing(p), p); //执行动画回调函数,并传入动画算子的结果和动画进度。
} else {
if (finished) { //判断是否停止动画。如果是true代表停止动画。
next = false;
} else {
startTime = Date.now();
}
}
// 如果next是true执行下一帧动画
if (next) requestAnimationFrame(step);
});
}
}; function ChangeState() {
var self = document.getElementById("moveAny");
// 新建一个动画
new Animator(2000, function (p) {
self.style.top = 500 * p + "px";
}, Easing.easeBoth).start(false); } </script>
</head>
<body>
<div style="border: 2px solid red">
<!--动画实现方式:通过操作JavaScript间接操作CSS样式,每隔一段时间更新一次;-->
<div id="div"></div> <div id="block" onclick="blockClick(this)"></div>
<div id="blockTwo" onclick="blockTwoClick(this)"></div> <div id="ball" onclick="ballClick(this)"></div>
<div id="car" onclick="carClick(this)"></div>
<div id="stone" onclick="stoneClick(this)"></div>
<div id="SinMove" onclick="SinMoveClick(this)"></div>
<div id="CircleMove" onclick="CircleMoveClick(this)"></div>
</div> <div id="moveAny">我是一个可以做任意运动的物体</div>
<div id="controlPan">控制面板
<button onclick="ChangeState(this)">切换运动状态</button>
</div>
</body>
</html>

最新文章

  1. PHP window下安装Spl_Types模块
  2. Activiti工作流学习(三)Activiti工作流与spring集成
  3. 8.10 CSS知识点3
  4. struts2的异常
  5. EMVTag系列1《数据分组》
  6. [C#搜片神器] 之P2P中DHT网络爬虫原理
  7. UVa 11300 Spreading the Wealth 分金币
  8. html的标签中 unselectable=on 属性的作用
  9. javascript外部使用
  10. EXchange导出通讯录提取url纯文本
  11. 线性表(存储结构数组)--Java 实现
  12. iOS之 重绘机制
  13. Java 执行CMD/DOS
  14. scrollTop的兼容性
  15. CF487E Tourists--圆方树
  16. usb描述符简述(二)
  17. Spring Boot tomcat
  18. DNS协议详解
  19. rospy 中service
  20. windows环境下VS2008编译程序在有些电脑上执行不了的问题

热门文章

  1. SIGPROF和SIGALRM使用总结
  2. js 跨浏览器获取事件信息模块
  3. Chromium多线程模型设计和实现分析
  4. android中常见的内存泄漏和解决的方法
  5. MyBatis中sqlSession操作数据库,不报错但无法实现数据修改(增、改、删)
  6. iOS开发之获取沙盒路径
  7. String不可变性
  8. Redis五种数据类型及应用场景
  9. CSS3实现简单的幻灯片
  10. 在线word论文生成的方法