学习完canvas,我用canvas画了写动画代码在这里啦canvas动画源码
canvas简介
画布,用来绘制图形, 长久以来,web上的东阿虎都是flash, 比如动画广告都是flash实现的,flash需要插件,漏洞比较多,重量比较大,卡顿和不流畅
canvas是一个轻量级的画布, 可以使用js编程,他是H5标签,不需要任何插件就可以实现广告,游戏,动画,性能也很好,不卡顿,在手机上也能很流畅
hello canvas
简单使用
// 得到canvas画布
const canvas = document.getElementById('canvas')
console.log(canvas)
// 得到画布的上下文,上下文有两个,2d的上下文和3d的上下文
let ctx = canvas.getContext("2d")
// 所有的图像的绘制都是通过ctx属性或者是方法设置的,和canvas标签没有关系了
// 设置颜色
ctx.fillStyle = "pink"
// 绘制矩形
ctx.fillRect(100,100,100,100)
可见,canvas就是通过js代码在浏览器上画画 注意: 标签的属性只有width 和height,不能通过style属性设置样式
常用的API
- getContext() 获取上下文
- fillStyle 填充颜色
- fillRect(x,y,width,height) 绘制矩形
canvas的像素化
我们使用canvas绘制了一个图形, 一旦绘制成功了, canvas就像素化了他们, canvas没有能力, 从画布上再次得到这个图形,也就是说我们没有能力去修改已经在画布上的内容,就是就是canvas的比较轻量级的原因,flash重的原因之一就是他有可能通过对应的api的到已经上画布的内容然后再绘制 如果我们想要让这个canvas图形移动,必须按照清屏更新渲染的逻辑进行编程,总之就是再重新画\
canvas的动画思想
清屏-更新-渲染
canvas上画布的元素就被像素化了,不能通过style.left 方法进行修改,必须重新渲染 实际上,动画的生成就是相关静态画面连续播放,这个是就是动画的过程,我们把每一次绘制的静态画面叫做一帧,时间的间隔(定时器的间隔)就表示是帧的间隔
我的第一个canvas动画
// 得到canvas画布
const canvas = document.getElementById('canvas')
console.log(canvas)
// 得到画布的上下文,上下文有两个,2d的上下文和3d的上下文
let ctx = canvas.getContext("2d")
// 所有的图像的绘制都是通过ctx属性或者是方法设置的,和canvas标签没有关系了
// 设置颜色
ctx.fillStyle = "pink"
// 绘制矩形
ctx.fillRect(100,100,200,100)
// 定义信号量
let left = 200
setInterval(function() {
// 清除画布,0,0代表从什么位置开始清除,600,600代表清除的宽度和高度
ctx.clearRect(0,0,600,600)
// 更新信号量
left++
// 重新绘制
ctx.fillRect(left,100,100,100)
},10)
面向对象思维实现canvas动画
实例走起
// 得到canvas画布
const canvas = document.getElementById('canvas')
let ctx = canvas.getContext("2d")
console.log(canvas)
// 定义canvas构造函数
function Rect (x,y,w,h,color) {
this.x=x
this.y=y
this.w=w
this.h=h
this.color = color
}
// 更新方法
Rect.prototype.update = function() {
this.x++
}
// 渲染方法
Rect.prototype.render = function() {
ctx.fillStyle = this.color
ctx.fillRect(this.x,this.y,this.w,this.h)
}
// 实例化画布对象
const r1 = new Rect (100,100,50,50,'red')
setInterval(function() {
// 清除画布,0,0代表从什么位置开始清除,600,600代表清除的宽度和高度
ctx.clearRect(0,0,canvas.width,canvas.height)
// 更新信号量
r1.update()
r1.render()
},10)
canvas的绘制
- 绘制矩形:
fillStylefillRect
// 设置颜色
ctx.fillStyle = "pink"
// 绘制矩形
ctx.fillRect(100,100,200,100)
- 绘矩形边框,
strokeStylestrokeRect
ctx.strokeStyle = 'red'
ctx.strokeRect(300,100,100,100)
- 清除
clearRect
// 清除画布,0,0代表从什么位置开始清除,600,600代表清除的宽度和高度
ctx.clearRect(0,0,600,600)
绘制路径
绘制路径是为了设置一个不规则的多边形的状态 路径都是闭合的.使用路径进行绘制的时候需要既定的步骤
- 需要设置路径的起点 beginPath()
- 使用绘制命令画出路径 lineTo()
- 封闭路径 closePath()
- 填充或者绘制已经封闭路径的形状
// 得到canvas画布
const canvas = document.getElementById('canvas')
let ctx = canvas.getContext("2d")
// 创建一个路径
ctx.beginPath()
// 描述进行路径
ctx.moveTo(100,100)
// 描述行进路径
ctx.lineTo(200,200)
ctx.lineTo(400,100)
ctx.lineTo(380,50)
// 封闭路径
ctx.closePath()
// 绘制这个不规则的图形
ctx.strokeStyle = 'red'
ctx.stroke()
绘制圆弧
arc()
arc(x, y, radius, startAngle, endAngle, anticlockwise)
画一个以(x,y)为圆心的以radius为半径的圆弧(圆),从startAngle开始到endAngle结束,按照anticlockwise给定的方向(默认为顺时针)来生成。
**注意:
arc()函数中表示角的单位是弧度,不是角度。角度与弧度的js表达式:*弧度=(Math.PI/180)角度。
ctx.arc(100,100,100,0,1,true);
ctx.stroke()
ctx.arc(100,100,100,0,1,false);
ctx.stroke()
ctx.arc(100,100,100,0,2*Math.PI,true);
ctx.stroke()
如果两个参数之间的差值大于7,这个圆弧就是一个圆
透明度
ctx.globalAlpha : 透明度
线型
线宽
我们可以利用lineWidth 设置先得粗细,属性值必须是数组,默认是1
ctx.lineWeidth = 20
线段末端
lineCap属性决定了每一条线段末端的属性,一共3个属性:分别是butt,round square
连线部分的样式
lineJoin决定了两个线段连接部分的样式的属性 belve miter round
实线和虚线
setLineDash([虚线的长度,两个虚线之间的距离]) lineDashOffset设置虚线的起始偏移量
文本
ctx.font = '30px 微软雅黑' cst,fillText("这个是填充的文字",100,100) textAline = start left center right (基于fillText的x的值)
使用图片
ctx,drawImage(img,100,100,200,120)
资源管理器
我们在开发游戏的时候有一些静态资源是需要求那个球回来的,否则如果直接开始,某些资源没有,会报错,或者空白,比如我们的游戏背景图,如果没有请求回来就加载会有空白的
requestAnimationFrame
requestAnimationFrame 比起 setTimeout、setInterval的优势主要有两点:
1、requestAnimationFrame 会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒60帧。
2、在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的的cpu,gpu和内存使用量。