canvas给我们提供了绘图API,这些API基于JavaScript实现,那么我们可以方便的实现一些动画,在这里我们将展示几个经典的动画绘制技巧,包括:时钟,太阳系,动态蚂蚁线,全景照片

动画绘制的基本步骤

我们知道动画是由关键帧拼接而成,在人眼的视觉暂留下连续起来从而具有动态的效果,在这篇博客中我们也介绍了一些方法,canvas动画的绘制也大同小异:

  • 清空canvas:新一动画帧绘制前,我们要清除原有的状态,以避免原有渲染的污染。除非接下来要画的内容会完全充满 canvas (例如背景图),否则需要清空所有。最简单的做法就是用 clearRect 方法。
  • 保存canvas状态:与前面提到的一样,保存canvas是一种优秀的品质。如果要改变一些会改变 canvas 状态的设置(样式,变形之类的),又要在每画一帧之时都是原始状态的话,需要先保存上一状态。
  • 绘制动画:动画实现的关键之处,动画效果都在这一步绘制关键帧
  • 恢复canvas状态:如果已经保存了 canvas 的状态,可以先恢复它,然后重绘下一帧。

时间间隔设置

动画的实现离不开定时器,在递归函数调用时我们设置一个定时器,从而在固定时刻绘制每一帧动画。目前有三种主要方法:setInterval,setTimeout,requestAnimationFrame()

  • setInterval(function,delay):按照指定的周期(以毫秒计)来调用函数或计算表达式。方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。
  • setTimeout(function,delay):在指定的毫秒数后调用函数或计算表达式。解除方法是clearTimeout(timer).
  • requestAnimationFrame(callback):告诉浏览器你希望执行一个动画,并在重绘之前,请求浏览器执行一个特定的函数来更新动画。相较于前两者这个方法提供了更加平缓并更加有效率的方式来执行动画,当系统准备好了重绘条件的时候,才调用绘制动画帧。一般每秒钟回调函数执行60次,也有可能会被降低。
  • cancelAnimationFrame:取消requestAnimationFrame动画

如何选择这3者?

  • 如果不需要与用户互动,可以使用setInterval()方法,它就可以定期执行指定代码。
  • 如果我们需要做一个游戏,我们可以使用键盘或者鼠标事件配合上setTimeout()方法来实现。通过设置事件监听,我们可以捕捉用户的交互,并执行相应的动作。
  • requestAnimationFrame(callback)方法提供了更加平缓并更加有效率的方式来执行动画,当系统准备好了重绘条件的时候,才调用绘制动画帧。

动画示例:

canvas实现的动画

(1)太阳系

var sun=new Image();
var moon=new Image();
var earth=new Image();
function init()
{sun.src="sun.jpg";earth.src="地球.jpg";moon.src="moon.jpg";window.requestAnimationFrame(draw);//确保图片平稳加载完毕,调用requestAnimationFrame
}//设计draw函数
function draw(ctx)
{var ctx=document.getElementById("canvas").getContext('2d');ctx.globalCompositeOperation="destination-over";//合成为在当前画布内容后绘制新的动画ctx.clearRect(0,0,300,300);//清除区域ctx.strokeStyle="rgba(0,153,255,0.4)";ctx.save();//earthctx.translate(150,150);//earth 确定地球的中心var time=new Date();//create时间对象ctx.rotate((2*Math.PI/60)*time.getSeconds()+(2*Math.PI/60000)*time.getMilliseconds());//getSecond返回一个0~59之间的整数表示秒,getMillioneconds返回一个0~60000之间的整数,表示毫秒ctx.translate(105,0);//确定地球轨道上的位置ctx.drawImage(earth,-12,-12,24,24);//Moonctx.save();ctx.rotate((2*Math.PI/6)*time.getSeconds()+(2*Math.PI/6000)*time.getMilliseconds());ctx.translate(0,30);//确定月球的位置ctx.drawImage(moon,-3.5,-3.5);ctx.restore();ctx.restore();//轨道ctx.beginPath();ctx.arc(150,150,105,0,Math.PI*2,false);ctx.stroke();//sunctx.drawImage(sun,0,0,300,300);//递归调用window.requestAnimationFrame(draw);
}
window.onload=init();

(2)动态蚂蚁线

window.onload=march;
var timer;
var offset=0;
function draw() {var canvas=document.getElementById("canvas");var ctx=canvas.getContext('2d');ctx.strokeStyle="rgb(150,"+offset*16+",0)";ctx.clearRect(0,0, canvas.width, canvas.height);ctx.setLineDash([5, 2]);//线段和间隙交替ctx.lineDashOffset = -offset;//起始偏移量ctx.strokeRect(10,10, 400, 300);
}function march() {offset++;if (offset > 16) {offset = 0;}draw();if(timer) clearTimeout(timer);timer=setTimeout(march, 20);
}

(3)动态时钟

下面我们将会绘制一个动态的时钟,绘制过程轻车熟路,要注意两点:

  • 指针旋转的角度计算:
  • 时针 rotate_hour=(2Math.PI((hour%12/12)+min/720+sec/43200));
  • 分针 rotate_min=(2Math.PI(min/60+sec/3600));
  • 秒针 rotate_sec=(2Math.PI(sec/60));
  • 注意一个save要对应一个restore,以防止出现错乱
function draw()
{var time=new Date();var ctx=document.getElementById("canvas").getContext('2d');ctx.save();ctx.clearRect(0,0,500,500);ctx.translate(250,250);ctx.rotate(-Math.PI/2);//旋转到起始位置ctx.fillStyle="#5F9EA0";ctx.strokeStyle="black";ctx.lineWidth=5;ctx.lineCap="round";//背景ctx.beginPath();ctx.arc(0,0,201,Math.PI*2,false);ctx.fill();//边框ctx.save();ctx.strokeStyle="white";ctx.lineWidth=1;ctx.beginPath();ctx.arc(0,0,195,0,Math.PI*2,false);ctx.stroke();ctx.beginPath();ctx.arc(0,0,200,0,Math.PI*2,false);ctx.stroke();ctx.restore();//小时刻度ctx.save();for(var i=0;i<12;i++){ctx.beginPath();ctx.moveTo(0,-175);ctx.lineTo(0,-190);ctx.stroke();ctx.rotate(Math.PI/6);}ctx.restore();//分刻度ctx.lineWidth=1;ctx.save();for(var i=0;i<60;i++){ctx.beginPath();ctx.moveTo(0,-185);ctx.lineTo(0,-190);ctx.stroke();ctx.rotate(Math.PI/30);}ctx.restore();//画指针var hour=time.getHours();var min=time.getMinutes();var sec=time.getSeconds();var rotate_hour=(2*Math.PI*((hour%12/12)+min/720+sec/43200));var rotate_min=(2*Math.PI*(min/60+sec/3600));var rotate_sec=(2*Math.PI*(sec/60));ctx.fillStyle="black";//时针ctx.save();ctx.rotate(rotate_hour);ctx.lineWidth=11;ctx.beginPath();ctx.moveTo(0,20);ctx.lineTo(0,-150);ctx.stroke();ctx.restore();//分针ctx.save();ctx.rotate(rotate_min);ctx.lineWidth=7;ctx.beginPath();ctx.moveTo(0,30);ctx.lineTo(0,-180);ctx.stroke();ctx.restore();//秒针ctx.save();ctx.rotate(rotate_sec);ctx.lineWidth=2;ctx.beginPath();ctx.moveTo(0,40);ctx.lineTo(0,-188);ctx.stroke();ctx.restore();//画出中心点ctx.save();ctx.fillStyle=" #4B0082";ctx.beginPath();ctx.arc(0,0,5,0,Math.PI*2,false);ctx.fill();ctx.restore();//显示数字时间ctx.save();ctx.rotate(Math.PI/2);ctx.strokeStyle="white";ctx.font="15px 幼圆";ctx.fillText(hour+":"+min+":"+sec,50,-50);ctx.restore();ctx.restore();window.requestAnimationFrame(draw);
}
window.requestAnimationFrame(draw);

(4)全景照片

还记得这篇文章中用动画增强网页吗?我们设置一张长图,这张长图将所有的图片横向包含,隐藏这张长图的绝大部分,当鼠标悬浮时,显示这张图的相应子图。这里我们仍然采用这样的做法,首先我们需要一张长图。

var img = new Image();// User Variables - customize these to change the image being scrolled, its
// direction, and the speed.
img.src = '对称.png';
var CanvasXSize = 603;
var CanvasYSize = 300;
var speed = 30; //lower is faster
var scale = 1.05;
var y = -4.5; //vertical offset// Main program
var imgW;
var imgH;
var x = 0;
var clearX;
var clearY;
var ctx;img.onload = function() {imgW = img.width*scale;imgH = img.height*scale;if (imgW > CanvasXSize) { x = CanvasXSize-imgW; } // image larger than canvasif (imgW > CanvasXSize) { clearX = imgW; } // image larger than canvaselse { clearX = CanvasXSize; }if (imgH > CanvasYSize) { clearY = imgH; } // image larger than canvaselse { clearY = CanvasYSize; }//Get Canvas Elementctx = document.getElementById('canvas').getContext('2d');//Set Refresh Ratereturn setInterval(draw, speed);
}function draw() {//Clear Canvasctx.clearRect(0,0,clearX,clearY);//If image is <= Canvas Sizeif (imgW <= CanvasXSize) {//reset, start from beginningif (x > (CanvasXSize)) { x = 0; }//draw aditional imageif (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-CanvasXSize+1,y,imgW,imgH); }}//If image is > Canvas Sizeelse {//reset, start from beginningif (x > (CanvasXSize)) { x = CanvasXSize-imgW; }//draw aditional imageif (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-imgW+1,y,imgW,imgH); }}//draw imagectx.drawImage(img,x,y,imgW,imgH);//amount to movex += 0.75;
}


简化版:

var img = new Image();
img.src = '对称.png';
var speed = 30; //lower is faster
var y = -4.5;
var x = 0;
var ctx;
img.onload = function() {ctx = document.getElementById('canvas').getContext('2d');return setInterval(draw, speed);
}
function draw()
{ctx.clearRect(0,0,ctx.width,ctx.height);if(x>=img.width) x=0;ctx.drawImage(img,x-img.width,y,img.width,img.height);ctx.drawImage(img,x,y,img.width,img.height);x+=0.75;
}

canvas动画 时钟动画 太阳系动画 动态蚂蚁线 全景照片相关推荐

  1. 前端开发练习——包含了计时功能的动画时钟

    前言 学了一段时间的前端,三大核心知识总算是磕磕绊绊的学完了,于是花了一个多小时做出来了这么一个相当于总结复习一样的动画时钟. 这个动画时钟实现的功能: 固定在页面中央显示. 可以在普通时钟模式和计时 ...

  2. 使用canvas绘制动画时钟

    一代码 <!DOCTYPE html > <head> <meta charset="UTF-8" ><title>绘制动态时钟&l ...

  3. html5画布时钟cnsd,canvas动画时钟

    最近在学canvas,然后根据MDN上的例子做了个动画时钟(为什么要造个轮子,因为丑..) 这是MDN上的例子,怎么说呢,比较复古吧. 首先,找一张时钟的图片,就是下面这张了. --来自bigger ...

  4. Canvas炫酷3D线条动画背景

    下载地址 Canvas炫酷3D线条动画背景,可以变色的颜色渐变网页动态背景特效. dd:

  5. 运用计算机来动画制作的视频,如何制作一个时钟转动动画视频?电脑制作动画的软件制作时钟转动的小视频的方法...

    今天小编要来介绍的是制作动画的软件,可以用于制作时钟转动的动画效果,之前小编就介绍过时钟动画制作的方法,但今天的方法更先进哦,这里的时钟的样式还有颜色都可以自定义的哦.制作动画的软件是什么?不是手机自 ...

  6. 计算机动画制作简单动画视频教程,如何制作一个时钟转动动画视频?电脑制作动画的软件制作时钟转动的小视频的方法...

    今天小编要来介绍的是制作动画的软件,可以用于制作时钟转动的动画效果,之前小编就介绍过时钟动画制作的方法,但今天的方法更先进哦,这里的时钟的样式还有颜色都可以自定义的哦.制作动画的软件是什么?不是手机自 ...

  7. HTML动画太阳旋转,html5旋转的太阳系动画

    html5旋转的太阳系动画 var cxt=document.getElementById('canvas').getContext('2d') function draw(){ for(var i= ...

  8. html5 canvas雨点打到窗玻璃动画

    html5 canvas雨点打到窗玻璃动画 HTML5下雨效果 效果预览:http://hovertree.com/texiao/html5/4.htm 以下是代码: 1 <!doctype h ...

  9. 第166天:canvas绘制饼状图动画

    canvas绘制饼状图动画 1.HTML 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 < ...

最新文章

  1. java并发编程实践 读书笔记_Java - 并发编程实践(读书笔记)
  2. 中兴手机数据通道打不开_中兴手机有流量,但是数据开不了怎么办?
  3. gitlab 安装_Linux学习14CentOS安装gitlab环境
  4. 使用C#像google/zx一样编写脚本
  5. Windows Phone 7 button控件
  6. Java基础系列--static关键字
  7. ROS中测试机器人里程计信息
  8. Friends S01.01 Part A
  9. 云算子矩阵计算机,《CASIOfx-5800P矩阵编程计算器测量程序集锦梁宝禄.pdf》-支持高清全文免费浏览-max文档...
  10. 2021-11-04
  11. 常见的夜间经济项目有哪些?
  12. GAN异常检测论文笔记(一)《GANomaly: Semi-Supervised Anomaly Detection via Adversarial Training》
  13. 安卓代码播放手机本地视频
  14. Android 之BlockingQueue
  15. 欧几里得扩展欧几里得算法及相关的数学证明
  16. matlab可视化界面怎么修改,matlab可视化界面
  17. ORACLE数据库的统一命名与编码规范
  18. mysql master 重置_[数据库]重置mysql主从同步(MySQL Reset Master
  19. java:浅谈axis调用webservice接口
  20. 实验一  安装并熟悉Rational Rose 环境

热门文章

  1. 关于linux中socket阻塞与非阻塞
  2. 目前支持WebGL的浏览器有哪些?
  3. 怎么用c语言画余弦函数,用c语言绘制余弦函数图像
  4. react + ant design 实现动态合并Table表格(相同数据合并为一条)
  5. 【虚拟现实】学习笔记
  6. 中文标点符号unicode码
  7. 安路FPGA学习之有趣的下载方式
  8. Ubuntu 16.04+CUDA8.0+Caffe+OpenCV3.1
  9. 详解脑的功能区域分布以及布罗德曼分区系统
  10. ESP8266 + MAX7219 做一个简易的自动同步的倒计时时钟