canvas 的动画原理非常简单, 使用 requestAnimationFrame 定期清除画布, 重新画只要画的内容的位置或形状发生变化, 即可形成动画这里给出简单的物理动画
1. 匀速运动
位置信息线性增加, 即可
- <canvas></canvas>
- <style>
- html,body,canvas{
- width:100vw;
- height:100vh;
- background:#000000;
- overflow:hidden;
- }
- </style>
- <script>
- setTimeout(function() {
- var canvas = document.querySelector('canvas');
- var context = canvas.getContext('2d');
- canvas.width = canvas.offsetWidth;
- canvas.height = canvas.offsetHeight;
- var pointer = {
- x: 0,
- y: canvas.height / 2
- };
- var render = function() {
- context.clearRect(0, 0, canvas.width, canvas.height);
- context.fillStyle = "green";
- context.beginPath();
- context.arc(pointer.x ,pointer.y, 100, 0, 2 * Math.PI, false);
- context.fill();
- };
- (function run() {
- pointer.x += 7; // 位置恒定变化
- if (pointer.x > canvas.width) {
- pointer.x = 0;
- }
- render();
- requestAnimationFrame(run)
- })();
- }, 500);
- </script>
2. 匀加速运动
常见的匀加速运动如重力, 速度逐步线性增加
- <canvas></canvas>
- <style>
- html,body,canvas{
- width:100vw;
- height:100vh;
- background:#000000;
- overflow:hidden;
- }
- </style>
- <script>
- setTimeout(function() {
- var canvas = document.querySelector('canvas');
- var context = canvas.getContext('2d');
- canvas.width = canvas.offsetWidth;
- canvas.height = canvas.offsetHeight;
- var pointer = {
- x: canvas.width / 2,
- y: 0
- };
- var render = function() {
- context.clearRect(0, 0, canvas.width, canvas.height);
- context.fillStyle = "green";
- context.beginPath();
- context.arc(pointer.x ,pointer.y, 100, 0, 2 * Math.PI, false);
- context.fill();
- };
- var v = 5;
- (function run() {
- v += 0.2; // 速度恒定变化
- pointer.y += v;
- if (pointer.y > canvas.height) {
- pointer.y = 0;
- v = 5;
- }
- render();
- requestAnimationFrame(run)
- })();
- }, 500);
- </script>
3. 平抛物运动
水平匀速运动与垂直方向匀加速运动的组合
- <canvas></canvas>
- <style>
- html,body,canvas{
- width:100vw;
- height:100vh;
- background:#000000;
- overflow:hidden;
- }
- </style>
- <script>
- setTimeout(function() {
- var canvas = document.querySelector('canvas');
- var context = canvas.getContext('2d');
- canvas.width = canvas.offsetWidth;
- canvas.height = canvas.offsetHeight;
- var pointer = {
- x: 0,
- y: 0
- };
- var render = function() {
- context.clearRect(0, 0, canvas.width, canvas.height);
- context.fillStyle = "green";
- context.beginPath();
- context.arc(pointer.x ,pointer.y, 100, 0, 2 * Math.PI, false);
- context.fill();
- };
- var vx = 7;
- var vy = 2;
- (function run() {
- pointer.x += vx; // 位置恒定变化
- vy += 0.1; // 速度恒定变化
- pointer.y += vy;
- if (pointer.x > canvas.width
- || pointer.y > canvas.height) {
- pointer.x = 0;
- pointer.y = 0;
- vy = 2;
- }
- render();
- requestAnimationFrame(run)
- })();
- }, 500);
- </script>
4. 抛射运动
垂直方向初始速度为负的抛物运动
- <canvas></canvas>
- <style>
- html,body,canvas{
- width:100vw;
- height:100vh;
- background:#000000;
- overflow:hidden;
- }
- </style>
- <script>
- setTimeout(function() {
- var canvas = document.querySelector('canvas');
- var context = canvas.getContext('2d');
- canvas.width = canvas.offsetWidth;
- canvas.height = canvas.offsetHeight;
- var pointer = {
- x: 0,
- y: canvas.height / 2
- };
- var render = function() {
- context.clearRect(0, 0, canvas.width, canvas.height);
- context.fillStyle = "green";
- context.beginPath();
- context.arc(pointer.x ,pointer.y, 100, 0, 2 * Math.PI, false);
- context.fill();
- };
- var vx = 7;
- var vy = -7;
- (function run() {
- pointer.x += vx; // 位置恒定变化
- vy += 0.1; // 速度恒定变化
- pointer.y += vy;
- if (pointer.x > canvas.width
- || pointer.y > canvas.height) {
- pointer.x = 0;
- pointer.y = canvas.height / 2;
- vy = -7;
- }
- render();
- requestAnimationFrame(run)
- })();
- }, 500);
- </script>
5. 匀速圆周运动
canvas 实现旋转, 需要使用 rotate 方法注意 translate 和 rotate 是对坐标系的操作 save 和 restore 方法是对绘图环境状态保存 (压栈) 和恢复 (出栈) 状态包括 fillStyle 和坐标系变换等操作等状态
- <canvas></canvas>
- <style>
- html,body,canvas{
- width:100vw;
- height:100vh;
- background:#000000;
- overflow:hidden;
- }
- </style>
- <script>
- setTimeout(function() {
- var canvas = document.querySelector('canvas');
- var context = canvas.getContext('2d');
- canvas.width = canvas.offsetWidth;
- canvas.height = canvas.offsetHeight;
- var pointer = {
- x: canvas.width / 2,
- y: canvas.height / 2
- };
- var angle = 0;
- var render = function() {
- context.clearRect(0, 0, canvas.width, canvas.height);
- // 轨道
- context.strokeStyle = "white";
- context.lineWidth = 2;
- context.beginPath();
- context.arc(pointer.x ,pointer.y, 200, 0, 2 * Math.PI, false);
- context.stroke();
- // 小球
- context.save();
- context.fillStyle = "green";
- context.translate(pointer.x, pointer.y);
- context.rotate(angle);
- context.beginPath();
- context.arc(0, 200, 30, 0, 2 * Math.PI, false);
- context.fill();
- context.restore();
- };
- (function run() {
- angle += Math.PI / 180;
- render();
- requestAnimationFrame(run)
- })();
- }, 500);
- </script>
6. 无重力钟摆运动
不考虑重力因素的钟摆运动, 只是匀速圆周运动的一部分
- <canvas></canvas>
- <style>
- html,body,canvas{
- width:100vw;
- height:100vh;
- background:#000000;
- overflow:hidden;
- }
- </style>
- <script>
- setTimeout(function() {
- var canvas = document.querySelector('canvas');
- var context = canvas.getContext('2d');
- canvas.width = canvas.offsetWidth;
- canvas.height = canvas.offsetHeight;
- var pointer = {
- x: canvas.width / 2,
- y: canvas.height / 4
- };
- var angle = Math.PI / 6;
- var render = function() {
- context.clearRect(0, 0, canvas.width, canvas.height);
- // 小球
- context.save();
- context.fillStyle = "green";
- context.translate(pointer.x, pointer.y);
- context.rotate(angle);
- context.beginPath();
- context.arc(0, 200, 30, 0, 2 * Math.PI, false);
- context.fill();
- context.strokeStyle = "gray";
- context.lineWidth = 3;
- context.beginPath();
- context.moveTo(0, 0);
- context.lineTo(0, 200);
- context.stroke();
- context.restore();
- };
- var reverse = false;
- (function run() {
- var w = Math.PI / 180; // 角速度
- if (!reverse) {
- angle += w;
- } else {
- angle -= w;
- }
- if (Math.abs(angle) > Math.PI / 6) {
- reverse = !reverse;
- }
- render();
- requestAnimationFrame(run)
- })();
- }, 500);
- </script>
来源: http://www.qdfuns.com/article/17398/5ae559f912d362f2014f005db7afd7b1.html