HTML学习笔记(四) Canvas
<canvas> 标签用于定义图形容器,容器本身是没有画图能力的,但我们可以使用脚本来绘制图形
1、创建画布
在 HTML 中,使用 <canvas> 标签可以创建一个矩形画布,这个画布的默认宽高为 300*150
如果要改变画布的大小,建议通过内联样式或者脚本进行设置,否则很容易会出现画布扭曲的情况
<!DOCTYPE html>
<html>
<head>
<title>Canvas Demo</title>
</head>
<body>
<canvas id="graph" width="300" height="300">您的浏览器不支持 canvas 标签</canvas>
</body>
</html>
2、创建画笔
在 JavaScript 中,使用 getContext()
方法可以创建一个渲染上下文对象
这个对象就相当于是这个画布的画笔,拥有一系列用于画图的方法
<script>
var canvas = document.getElementById('graph')
var context = canvas.getContext('2d')
// 开始画图
</script>
3、绘制矩形
Canvas 只支持一种原生图形的绘制方法,那就是矩形,其它图形都必须通过路径生成
strokeRect(x, y, width, height)
:绘制一个矩形的边框fillRect(x, y, width, height)
:绘制一个填充的矩形clearRect(x, y, width, height)
:清空指定的矩形区域
其中,参数 x、y 定义矩形左上角的坐标,参数 width、height 定义矩形的宽高
<script>
var cvs = document.getElementById('graph')
var ctx = cvs.getContext('2d')
ctx.strokeRect(10, 10, 100, 100)
</script>
4、绘制路径
图形的基本元素是路径,路径是线段和点的集合,在 Canvas 中每一个路径都是闭合的
beginPath()
:新建一条路径closePath()
:结束一条路径,它会从当前点到起始点拉一条直线,使得路径闭合moveTo(x, y)
:将画笔移动到指定坐标stroke()
:绘制图形(闭合路径)的边框fill()
:填充图形(闭合路径)的内容,如果路径没有闭合,首先闭合路径
lineTo(x, y)
:创建一条直线路径,从当前坐标
到(x, y)
连接一条直线
<script>
var cvs = document.getElementById('graph')
var ctx = cvs.getContext('2d')
ctx.beginPath()
ctx.moveTo(150, 90)
ctx.lineTo(60, 210)
ctx.lineTo(240, 210)
ctx.closePath() // 结束一条路径,从当前点到起始点拉一条直线,使得路径闭合
ctx.stroke() // 绘制图形(闭合路径)的边框
</script>
<script>
var cvs = document.getElementById('graph')
var ctx = cvs.getContext('2d')
ctx.beginPath()
ctx.moveTo(150, 90)
ctx.lineTo(60, 210)
ctx.lineTo(240, 210)
ctx.fill() // 填充图形(闭合路径)的内容,如果路径没有闭合,首先闭合路径
</script>
-
arc(x, y, r, startAngle, endAngle, anticlockwise)
:创建一段圆弧路径以
(x, y)
为圆心,以r
为半径,从startAngle
开始,到endAngle
结束,画一段圆弧如果
anticlockwise
为true
,则逆时针画,如果anticlockwise
为false
,则顺时针画 -
arcTo(x1, y1, x2, y2, radius)
:创建一段圆弧路径首先我们想象从
当前坐标
到(x1, y1)
画一条直线,然后从(x1, y1)
到(x2, y2)
画一条直线这个方法的作用就是画一段半径为
radius
并且与两条直线相切的圆弧注意哦,从
当前坐标
到(x1, y1)
的直线也会留在画布上
<script>
var cvs = document.getElementById('graph')
var ctx = cvs.getContext('2d')
ctx.beginPath()
ctx.arc(150, 150, 100, Math.PI*1.5, Math.PI*0.5, true)
ctx.fill()
ctx.beginPath()
ctx.moveTo(50, 50)
ctx.arcTo(250, 50, 250, 250, 100)
ctx.stroke()
</script>
-
quadraticCurveTo(cpx, cpy, x, y)
:绘制二次贝塞尔曲线其中,
(cpx, cpy)
表示控制点的坐标,(x, y)
表示结束点的坐标 -
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
:绘制三次贝塞尔曲线(cp1x, cp1y)
是第一个控制点的坐标,(cp2x, cp2y)
是第二个控制点的坐标,(x, y)
是结束点的坐标
<script>
var cvs = document.getElementById('graph')
var ctx = cvs.getContext('2d')
ctx.beginPath()
ctx.moveTo(25, 100)
ctx.quadraticCurveTo(75, 50, 125, 100)
ctx.stroke()
ctx.beginPath()
ctx.moveTo(175, 250)
ctx.bezierCurveTo(205, 200, 245, 200, 275, 250)
ctx.stroke()
</script>
5、绘制文字
我们可以使用以下两个方法绘制文字:
strokeText(text, x, y)
:在指定坐标(x, y)
处创建空心文本text
fillText(text, x, y)
:在指定坐标(x, y)
处创建实心文本text
还能使用以下属性指定文字样式:
font
:指定文本样式,与 CSS font 属性取值相同,默认值为10px sans-serif
textAlign
:指定文本对齐选项,可选值有start
、end
、left
、right
、center
textBaseline
:指定基线对齐选项,可选值有alphabetic
、top
、middle
、bottom
、ideographic
、hanging
direction
:指定文本方向,可选值有inherit
、ltr
、rtl
<script>
var cvs = document.getElementById('graph')
var ctx = cvs.getContext('2d')
ctx.font = '50px sans-serif'
ctx.strokeText('Hello', 80, 160)
</script>
6、添加样式
(1)颜色
除了使用默认的黑色之外,我们还可以给图形设置指定的颜色
strokeStyle
:设置图形边框的颜色fillStyle
:设置图形内容的颜色
注意,一旦设置上面两个属性,那么新绘制的图形都是使用指定好的颜色
<script>
var cvs = document.getElementById('graph')
var ctx = cvs.getContext('2d')
for (let i = 0; i <= 5; i += 1) {
for (let j = 0; j <= 5; j += 1) {
let r = randInt(0, 255)
let g = randInt(0, 255)
let b = randInt(0, 255)
ctx.fillStyle = `rgb(${r}, ${g}, ${b})`
ctx.fillRect(j * 50, i * 50, 50, 50)
}
}
function randInt(start, end) {
return Math.floor(Math.random() * (end - start + 1) + start)
}
</script>
(2)渐变
除了使用常规的颜色,还能通过渐变对象使用渐变效果,渐变效果可以添加在图形、文本上
首先创建一个渐变对象
-
createLinearGradient(x1, y1, x2, y2)
:创建线性渐变(x1, y2)
定义渐变线的起点坐标,(x2, y2)
定义渐变线的终点坐标,渐变效果沿渐变线展开 -
createRadialGradient(x1, y1, r1, x2, y2, r2)
:创建径向渐变定义一个以
(x1, y1)
为坐标、以r1
为圆心的圆,定义一个以(x2, y2)
为坐标、以r2
为圆心的圆渐变效果发生在两个圆之间
然后给渐变对象定义渐变的效果
-
addStopColor(position, color)
:指定渐变颜色position
是一个 0 ~ 1 之间的数值,定义在渐变中的相对位置,color
用于定义在该处的颜色
<script>
var cvs = document.getElementById('graph')
var ctx = cvs.getContext('2d')
var grd = ctx.createLinearGradient(0, 0, 100, 100)
grd.addColorStop(0.0, 'red')
grd.addColorStop(0.5, 'green')
grd.addColorStop(1.0, 'blue')
ctx.fillStyle = grd
ctx.fillRect(0, 0, 100, 100)
</script>
(3)形状
除了可以指定颜色,我们还可以指定线段的形状
lineWidth
:指定线段宽度
<script>
var cvs = document.getElementById('graph')
var ctx = cvs.getContext('2d')
for (let i = 0; i <= 2; i += 1) {
ctx.beginPath()
ctx.moveTo(100, i * 20 + 50)
ctx.lineTo(200, i * 20 + 50)
ctx.lineWidth = i * 10 + 1
ctx.stroke()
}
</script>
-
lineCap
:指定线段末端的样式,其取值有三个:若为
butt
,则以方形结束若为
round
,则以圆形结束若为
square
,则以方形结束,但增加一个宽度与线段宽度相同,高度是宽度一半的矩形区域
<script>
var cvs = document.getElementById('graph')
var ctx = cvs.getContext('2d')
let lineCap = ['butt', 'round', 'square']
for (let i = 0; i <= 2; i += 1) {
ctx.beginPath()
ctx.moveTo(100, i * 20 + 50)
ctx.lineTo(200, i * 20 + 50)
ctx.lineWidth = 10
ctx.lineCap = lineCap[i]
ctx.stroke()
}
</script>
-
lineJoin
:指定线段之间的连接样式,其取值有三个:若为
miter
,通过延伸相连部分的外边缘,使其相交于一点,形成一个额外的菱形区域若为
round
,填充一个额外的、圆心在相连部分末端的扇形若为
bevel
,填充一个额外的、以三角形为底的区域
<script>
var cvs = document.getElementById('graph')
var ctx = cvs.getContext('2d')
let lineJoin = ['miter', 'round', 'bevel']
for (let i = 0; i <= 2; i += 1) {
ctx.beginPath()
ctx.moveTo(100, i * 20 + 50)
ctx.lineTo(150, i * 20 + 100)
ctx.lineTo(200, i * 20 + 50)
ctx.lineWidth = 10
ctx.lineJoin = lineJoin[i]
ctx.stroke()
}
</script>
7、创建图片
-
drawImage(image, x, y, width, height)
参数
image
表示图片的来源,既可以是一个 Image 对象,也可以是一个 <img> 元素参数
x
、y
定义图片位置,表示左上角的坐标;参数width
、height
定义图片大小,表示图片的宽高度
<script>
var cvs = document.getElementById('graph')
var ctx = cvs.getContext('2d')
var img = new Image()
img.src = 'https://cdn.pixabay.com/photo/2020/02/15/16/09/loveourplanet-4851331__340.jpg'
img.onload = function() {
ctx.drawImage(img, 0, 0, 300, 300)
}
</script>
-
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
:剪裁图片参数
image
表示图片的来源,既可以是一个 Image 对象,也可以是一个 <img> 元素sx, sy, sWidth, sHeight
定义对原图片的切片,dx, dy, dWidth, dHeight
定义在画布上的绘制
<script>
var cvs = document.getElementById('graph')
var ctx = cvs.getContext('2d')
var img = new Image()
img.src = 'https://cdn.pixabay.com/photo/2020/02/15/16/09/loveourplanet-4851331__340.jpg'
img.onload = function() {
ctx.drawImage(img, 180, 40, 100, 100, 0, 0, 300, 300)
}
</script>
【 阅读更多 HTML 系列文章,请看 HTML学习笔记 】