1 、简介
HTML5 canvas 标签用于绘制图像
不过,canvas 元素本身并没有绘制能力(它仅仅是图形的容器),您必须使用脚本来完成实际的绘图任务getContext()方法可返回一个对象,该对象提供了用于在画布上画图的方法和属性。
提供完善的getContent(‘2d’)对象的属性和方法,可用于在画布上绘制文本、线条、矩形、圆形等等。
国内 游戏制作 白鹭引擎 白鹭科技
小型3d游戏 threejs
大型游戏开发 虚幻4
2 、标签介绍
<!--
canvas 三要素
id 作为元素的唯一标识符
width 画布内容宽度的像素大小(与style的宽度和高度是有区别的)
height 画布内容高度的像素大小
canvas 仅仅只是1个画布标签,要绘制内容,必须用js绘制
-->
<canvas id="canvas1" width="600" height="600"></canvas>
3、 相关属性
3.1 颜色、样式和阴影、
属性 | 描述 |
fillStyle | 设置或返回用于填充绘画的颜色、渐变或模式 |
strokeStyle | 设置或返回用于笔触的颜色、渐变或模式 |
shadowColor | 设置或返回用于阴影的颜色 |
shadowBlur | 设置或返回用于阴影的模糊级别 |
shadowOffsetX | 设置或返回阴影距形状的水平距离 |
shadowOffsetY | 设置或返回阴影距形状的垂直距离 |
方法 | 描述 |
createLinearGradient(). | 创建线性渐变(用在画布内容上) |
createPattern(). | 在指定的方向上重复指定的元素 |
createRadialGradient(). | 创建放射状/环形的渐变(用在画布内容上) |
addColorStop(). | 规定渐变对象中的颜色和停止位置 |
3.2 线条样式
属性 | 描述 |
lineCap | 设置或返回线条的结束端点样式 |
lineJoin | 设置或返回两条线相交时,所创建的拐角类型 |
lineWidth | 设置或返回当前的线条宽度 |
miterLimit | 设置或返回最大斜接长度 |
3.4 矩形
方法 | 描述 |
rect() | 创建矩形 |
fillRect() | 绘制“被填充”的矩形 |
strokeRect() | 绘制矩形(无填充) |
clearRect() | 在给定的矩形内清除指定的像素 |
3.5 路径
方法 | 描述 |
fill() | 填充当前绘图(路径) |
stroke() | 绘制已定义的路径 |
beginPath() | 起始一条路径,或重置当前路径 |
moveTo() | 把路径移动到画布中的指定点,不创建线条 |
closePath() | 创建从当前点回到起始点的路径 |
lineTo() | 从原始画布剪切任意形状和尺寸的区域 |
clip() | 从原始画布剪切任意形状和尺寸的区域 |
quadraticCurveTo() | 创建二次贝塞尔曲线 |
bezierCurveTo() | 创建三次方贝塞尔曲线 |
arc() | 创建弧/曲线(用于创建圆形或部分圆) |
arcTo() | 创建两切线之间的弧/曲线 |
isPointInPath() | 如果指定的点位于当前路径中,则返回 true,否则返回 false |
3.6 转换
方法 | 描述 |
scale() | 缩放当前绘图至更大或更小 |
rotate() | 旋转当前绘图 |
translate() | 重新映射画布上的 (0,0) 位置 |
transform() | 替换绘图的当前转换矩阵 |
setTransform() | 将当前转换重置为单位矩阵。然后运行 transform() |
3.7 文本
属性 | 描述 |
font | 设置或返回文本内容的当前字体属性 |
textAlign | 设置或返回文本内容的当前对齐方式 |
textBaseline | 设置或返回在绘制文本时使用的当前文本基线 |
方法 | 描述 |
fillText() | 在画布上绘制“被填充的”文本 |
strokeText() | 在画布上绘制文本(无填充) |
measureText() | 返回包含指定文本宽度的对象 |
3.8 图像绘制
方法 | 描述 |
drawImage() | 向画布上绘制图像、画布或视频 |
3.9 像素操作
属性 | 描述 |
width | 返回 ImageData 对象的宽度 |
height | 返回 ImageData 对象的高度 |
data | 返回一个对象,其包含指定的 ImageData 对象的图像数据 |
方法 | 描述 |
createImageData() | 创建新的、空白的 ImageData 对象 |
getImageData() | 返回 ImageData 对象,该对象为画布上指定的矩形复制像素数据 |
putImageData() | 把图像数据(从指定的 ImageData 对象)放回画布上 |
3.10 合成
属性 | 描述 |
globalAlpha | 设置或返回绘图的当前 alpha 或透明值 |
globalCompositeOperation | 设置或返回新图像如何绘制到已有的图像上 |
3.11 其他
方法 | 描述 |
save() | 保存当前环境的状态 |
restore() | 返回之前保存过的路径状态和属性 |
createEvent() | |
getContext() | |
toDataURL() |
4 案例
4.1 时钟
<style>
*{
padding:0px;margin: 0px;
}
html,body{
width: 100%;
height: 100%;
}
</style>
<canvas id="clock" width="800" height="800"></canvas>
<script>
// 获取canvas标签 这个对象
var mycanvas = document.getElementById('clock')
// 获取笔刷
var brush = mycanvas.getContext('2d')
// 设置pi值
var pi = Math.PI;
setInterval(clock,1000);
function clock(){
brush.clearRect(0,0,800,800) // 清除画布内容
brush.save() // 保存状态
// 1. 绘制表盘
brush.translate(400,400); // 平移原点
brush.beginPath()
brush.arc(0,0,300,0,2*pi);
brush.strokeStyle="#abcf34";
brush.lineWidth = 10
brush.stroke()
brush.closePath()
brush.rotate(-2*pi/4)
brush.save()
// 2. 绘制 秒针刻度
for(var i=0;i<60;i++){
brush.rotate(2*pi/60)
brush.beginPath()
brush.moveTo(285,0)
brush.lineTo(295,0)
brush.strokeStyle = "red"
brush.lineWidth = 2
brush.stroke()
brush.closePath()
}
// 3. 绘制 分针刻度
for(var i=0;i<12;i++){
brush.rotate(2*pi/12)
brush.beginPath()
brush.moveTo(275,0)
brush.lineTo(295,0)
brush.strokeStyle = "lightblue"
brush.lineWidth = 6
brush.stroke()
brush.closePath()
}
// 获取当前时间
var t = new Date()
var second = t.getSeconds()
var minute = t.getMinutes()
var hour = t.getHours()
hour = hour>12?hour-12:hour;
// 4. 绘制秒针
brush.rotate(2*pi/60*second)
brush.beginPath()
brush.moveTo(-30,0)
brush.lineTo(120,0)
brush.strokeStyle = "red"
brush.lineWidth = 3
brush.stroke()
brush.closePath()
brush.restore()
brush.save();
// 5. 绘制分针
brush.rotate(2*pi/60*minute+2*pi/3600*second)
brush.beginPath()
brush.moveTo(-20,0)
brush.lineTo(100,0)
brush.strokeStyle = "green"
brush.lineWidth = 5
brush.stroke()
brush.closePath()
brush.restore()
brush.save();
// 6. 绘制时针
brush.rotate(2*pi/12*hour+2*pi/12/3600*minute)
brush.beginPath()
brush.moveTo(-10,0)
brush.lineTo(80,0)
brush.strokeStyle = "blue"
brush.lineWidth = 8
brush.stroke()
brush.closePath()
brush.restore()
brush.save()
// 7. 绘制圆心
brush.beginPath()
brush.arc(0,0,10,0,2*pi)
brush.fillStyle = "orange"
brush.fill()
brush.strokeStyle = "red"
brush.lineWidth = 2
brush.stroke()
brush.closePath()
brush.restore()
brush.restore()
}
</script>
4.2 粒子小球
<style>
*{
padding:0px;
margin: 0px;
}
html{
width:100%;
height: 100%;
}
body{
width: 100%;
height: 100%;
background-image: url(./bg.jpg);
background-size: 100% 100%;
background-position: center;
}
</style>
<canvas id="lizi"></canvas>
<script>
// 1. 获取画布
var cans = document.getElementById("lizi")
// 设置画布的宽和高
var h= window.innerHeight
var w= window.innerWidth
cans.width = w
cans.height = h
// 2. 获取笔刷
var brush = cans.getContext("2d")
// 3. 创建小球
var qiuArr=[]
var qiuqiu = setInterval(function(){
// 如果小球达到100个,则不再继续添加
if(qiuArr.length>100){
clearInterval(qiuqiu)
}
var cx = 10+Math.floor(Math.random()*w)
var cy = 10+Math.floor(Math.random()*h)
var r = 3 +Math.floor(Math.random()*7)
var sx = -4 + Math.floor(Math.random()*8)
var sy = -4 + Math.floor(Math.random()*8)
var red = 55 + Math.floor(Math.random()*190)
var green = 55 + Math.floor(Math.random()*190)
var blue = 55 + Math.floor(Math.random()*190)
var bg = "rgba("+red+","+green+","+blue+",0.3)"
if(sx!=0 || sy != 0){
obj ={
cx:cy,
cy:cy,
r:r,
sx:sx,
sy:sy,
bg:bg
}
qiuArr.push(obj)
}
},1000/20)
// 创建小球函数
function ball(){
brush.clearRect(0,0,w,h)
for(var i=0;i<qiuArr.length;i++){
// 在上下边界处创建时,y轴负数,因此变为正书
if(qiuArr[i].cy+qiuArr[i].r>=h ||qiuArr[i].cy-qiuArr[i].r<0 ){
qiuArr[i].sy*=-1
}
// 在左右边界处创建时,x轴负数,因此变为正书
if(qiuArr[i].cx+qiuArr[i].r>=w ||qiuArr[i].cx-qiuArr[i].r<0 ){
qiuArr[i].sx*=-1
}
qiuArr[i].cx+= qiuArr[i].sx
qiuArr[i].cy+= qiuArr[i].sy
// 画小球
brush.beginPath()
brush.arc(qiuArr[i].cx,qiuArr[i].cy,qiuArr[i].r,0,2*Math.PI)
brush.fillStyle=qiuArr[i].bg
brush.fill()
brush.closePath()
}
}
setInterval(ball,1000/60)
</script>