Canvas保姆级入门教程

Canvas

Canvas概念

canvas 是h5提供的一个标签,帮我们创建一块画布。可以绘制任意图形,包括图片、动画等内容。当前主流浏览器均支持。

基本用法

<canvas id="canvas" width="500" height="500"></canvas>

注意:设置canvas画布大小时不能通过style样式调整,会造成画布内容模糊

绘制上下文

Canvas创建了一个画布,并提供了一个上下文对象getContext()获得渲染上下文和绘画功能

const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')

画布坐标系

Canvas坐标系采用笛卡尔坐标系,默认0,0坐标为右上角。遵循我们屏幕、报纸的阅读习惯,从上往下,从左往右

img

了解了坐标系后让我们开始绘制基本图形吧

绘制图形

通过上下文对象,我们可以绘制多种图形,例如直线、矩形、圆形等

直线

绘制直线的基本api

moveTo(x, y) 画笔移动到指定位置

lineTo(x, y) 从画笔指定位置绘制到x和y坐标

stroke() 绘制

ctx.moveTo(50, 50) // 将画笔移动到50,50
ctx.lineTo(150, 150) // 画直线
ctx.stroke() // 绘制

在这里插入图片描述

矩形

strokeRect(x,y,width,height) 绘制矩形边框

fillRect(x,y,width,height) 绘制填充矩形

clearRect(x, y, width, height) 清除指定矩形区域

// 矩形的边框 strokeRect(x,y,width,height)
ctx.strokeStyle = 'red'   // 设置边框颜色
ctx.strokeRect(50, 50, 200, 100)

// 填充矩形 fillRect(x,y,width,height)
ctx.fillStyle = 'blue'  // 设置填充颜色
ctx.fillRect(100, 100, 200, 100)

// clearRect(x, y, width, height) 清除指定矩形区域
ctx.clearRect(120, 100, 100, 70)

红色区域为矩形边框,蓝色部分为填充矩形,中间白色缺少部分则是清除的矩形区域
在这里插入图片描述

圆弧和圆

arc(x, y, radius, startAngle, endAngle, anticlockwise) x和y为圆心的坐标,radius为半径,startAngle为圆弧或圆的开始位置,endAngle为圆弧或圆的结束位置,anticlockwise是绘制的方向(不写默认为false,从顺时针方向)。

ctx.arc(60, 60, 50, 0, Math.PI, false)
ctx.stroke()

在这里插入图片描述

注意:startAngleendAngle均为弧度,而不是角度。弧度转角度公式:弧度=(Math.PI/180)*角度 Math.PI*2 则是一个圆

ctx.arc(60, 60, 50, 0, Math.PI, false)
ctx.stroke()
ctx.arc(200, 60, 50, 0, Math.PI * 2, false)
ctx.stroke()

在这里插入图片描述

可以看到两个圆弧之间连接到了一起,这是因为每次绘制的时候没有开启关闭绘制路径

beginPath 开启新的路径绘制

closePath 关闭路径

ctx.beginPath() // 开启路径
ctx.arc(60, 60, 50, 0, Math.PI, false)
ctx.stroke()
ctx.closePath()
ctx.beginPath() // 开启路径
ctx.arc(200, 60, 50, 0, Math.PI * 2, false)
ctx.stroke()
ctx.closePath()

在这里插入图片描述

ctx.closePath()并非必须,只需要每次重新绘制时开启新的路径即可

fill可以为圆弧填充,填充时可以使用strokeStylefillStyle来调整边框颜色和填充颜色

ctx.beginPath() // 开启路径
ctx.arc(60, 60, 50, 0, Math.PI, false)
ctx.stroke()

ctx.beginPath() // 开启路径
ctx.arc(200, 60, 50, 0, Math.PI * 2, false)
ctx.stroke()

ctx.beginPath() // 开启路径
ctx.arc(60, 200, 50, 0, Math.PI * 2 / 4, false)
ctx.fill(); // 填充
ctx.stroke()

ctx.beginPath() // 开启路径
ctx.arc(200, 200, 50, 0, Math.PI * 2 / 6, false)
ctx.fill(); // 填充
ctx.stroke()

ctx.beginPath() // 开启路径
ctx.arc(400, 200, 50, 0, Math.PI * 2, false)
ctx.fill(); // 填充
ctx.stroke()

在这里插入图片描述

椭圆

ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise)

  • x、y:椭圆的圆心位置
  • radiusX、radiusY:x轴和y轴的半径
  • rotation:椭圆的旋转角度,以弧度表示
  • startAngle:开始绘制点
  • endAngle:结束绘制点
  • anticlockwise:绘制的方向(默认顺时针),可选参数。
ctx.beginPath();
ctx.ellipse(100, 100, 50, 100, 0, 0, 2 * Math.PI);
ctx.stroke()


ctx.beginPath();
ctx.ellipse(300, 100, 50, 100, Math.PI / 2, 0, 2 * Math.PI);
ctx.stroke()

ctx.beginPath();
ctx.ellipse(200, 350, 100, 100, Math.PI / 4, 0, 2 * Math.PI);
ctx.stroke()

在这里插入图片描述

radiusXradiusY相等是绘制出来的就是圆形,同样可以使用strokeStylefillStyle来调整边框颜色和填充颜色

贝塞尔曲线
二次贝塞尔曲线

二次贝塞尔曲线由三个点组成,分别是起点、终点、控制点

二次贝塞尔曲线在线调试工具

quadraticCurveTo(controlX, controlY, x, y)

  • controlX、controlY:控制点坐标
  • x、y:结束点坐标
  • 起点坐标为画笔坐标,如moveTo()
ctx.moveTo(50, 50);
ctx.quadraticCurveTo(200, 200, 350, 50);
ctx.stroke();// 绘制

在这里插入图片描述

三次贝塞尔曲线

三次贝塞尔曲线相较于二次贝塞尔曲线多了一个控制点

三次贝塞尔曲线在线调试工具

bezierCurveTo(control1X,control1Y, control2X,control2Y, x, y)

  • control1X、control1Y:第一个控制点坐标
  • control2X、control2Y:第二个控制点坐标
  • x、y:结束点坐标
  • 起点坐标为画笔坐标,如moveTo()
ctx.moveTo(50, 200)
ctx.bezierCurveTo(150, 50, 250, 350, 350, 200)
ctx.stroke() // 绘制

在这里插入图片描述

样式
线条样式

lineWidth 设置绘制线条粗细,默认值1

// 绘制样式
// lineWidth 线宽
ctx.moveTo(50, 50)
ctx.lineTo(150, 50)
ctx.stroke()

ctx.beginPath();
ctx.moveTo(50, 100)
ctx.lineTo(200, 100)    
ctx.lineWidth = 10
ctx.stroke()

ctx.beginPath();
ctx.moveTo(50, 150)
ctx.lineTo(250, 150)
ctx.lineWidth = 20
ctx.stroke()

在这里插入图片描述

lineCap 设置线段端点显示的样子,默认是 butt。可选值为:buttroundsquare

// lineCap 线帽
ctx.moveTo(50, 50)
ctx.lineTo(200, 50)
ctx.lineWidth = 10
ctx.lineCap = 'butt'
ctx.stroke()

ctx.beginPath();
ctx.moveTo(50, 100)
ctx.lineTo(200, 100)    
ctx.lineWidth = 10
ctx.lineCap = 'round'
ctx.stroke()

ctx.beginPath();
ctx.moveTo(50, 150)
ctx.lineTo(200, 150)
ctx.lineWidth = 10
ctx.lineCap = 'square'
ctx.stroke()

在这里插入图片描述

lineJoin 设置线段之间连接处的样式,默认是 miter。可选值为:roundbevel miter

// lineJoin 线连接
ctx.moveTo(50, 50)
ctx.lineTo(100, 100)
ctx.lineTo(150, 50)
ctx.lineTo(200, 100)
ctx.lineTo(250, 50)
ctx.lineWidth = 10
ctx.lineJoin = 'miter'
ctx.stroke()

ctx.beginPath();
ctx.moveTo(50, 150)
ctx.lineTo(100, 200)
ctx.lineTo(150, 150)
ctx.lineTo(200, 200)
ctx.lineTo(250, 150)
ctx.lineWidth = 10
ctx.lineJoin = 'round'
ctx.stroke()

ctx.beginPath();
ctx.moveTo(50, 250)
ctx.lineTo(100, 300)
ctx.lineTo(150, 250)
ctx.lineTo(200, 300)
ctx.lineTo(250, 250)
ctx.lineWidth = 10
ctx.lineJoin = 'bevel '
ctx.stroke()

在这里插入图片描述

透明度

在之前绘制矩形时我们用到过fillRect来填充矩形,颜色支持rgba

ctx.fillStyle = "rgba(255,0,0,0.2)"  // 设置填充颜色
ctx.fillRect(100, 100, 200, 100)


ctx.fillStyle = "rgba(255,0,0,0.7)"  // 设置填充颜色
ctx.fillRect(100, 300, 200, 100)

在这里插入图片描述

渐变
线性渐变

createLinearGradient(x1, y1, x2, y2),参数分别为 起点的坐标和终点的坐标。

在渐变的设置中还需要一个方法来添加渐变的颜色,语法为:gradient.addColorStop(offset, color),其中color就是颜色,offset 则是颜色的偏移值,只为0到1之间的数。

let gradient = ctx.createLinearGradient(10, 200, 400, 200)
gradient.addColorStop(0, '#00ff00')
gradient.addColorStop(1, '#ff0000')

ctx.fillStyle = gradient
ctx.fillRect(10, 10, 400, 400)

在这里插入图片描述

addColorStop 可以添加渐变颜色

let gradient = ctx.createLinearGradient(10, 200, 400, 200)

gradient.addColorStop(0, 'rgb(255, 0, 0)')
gradient.addColorStop(0.5, 'rgb(0, 255, 0)')
gradient.addColorStop(1, 'rgb(0, 0, 255)')

ctx.fillStyle = gradient
ctx.fillRect(10, 10, 400, 400)

在这里插入图片描述

createLinearGradient创建渐变时可以设置颜色渐变方向,比如我们想让颜色从左上角到右下角渐变

let gradient = ctx.createLinearGradient(10, 10, 400, 400)

在这里插入图片描述

径向渐变

createRadialGradient(x0, y0, r0, x1, y1, r1),参数分别为开始圆的坐标和半径以及结束圆的坐标和半径。

let gradient = ctx.createRadialGradient(250, 250, 50, 250, 250, 200)
gradient.addColorStop(0, 'rgb(255, 0, 0)')
gradient.addColorStop(0.5, 'rgb(0, 255, 0)')
gradient.addColorStop(1, 'rgb(0, 0, 255)')
ctx.fillStyle = gradient
ctx.arc(250, 250, 200, 0, Math.PI * 2, false)
ctx.fill() // 填充

在这里插入图片描述

图案填充

createPattern(image, type),参数分别为:Image 参数可以是一个 Image 对象,也可以是一个 canvas 对象,Type 为图案绘制的类型,可用的类型分别有:repeatrepeat-xrepeat-y 和、no-repeat

let img = new Image()
img.src = 'https://img0.baidu.com/it/u=147381800,3591524360&fm=253&fmt=auto&app=138&f=JPEG?w=371&h=194'
img.onload = function () {
    let pattern = ctx.createPattern(img, 'no-repeat')
    ctx.fillStyle = pattern
    ctx.fillRect(0, 0, 500, 500)
}

在这里插入图片描述

可以看到,我们绘制的矩形大小为500x500,当我们设置no-repeat时不会铺满。让我们改成repeat试试,repeat为x轴和y轴均平铺,可以自己尝试一下repeat-x和repeat-y。

let pattern = ctx.createPattern(img, 'repeat')

在这里插入图片描述

绘制文本
strokeText 文字描边

ctx.strokeText(text, x, y, maxWidth) 参数:text:文本内容、x,y :坐标、maxWidth:最大宽度

ctx.font = "50px serif"; // 设置字体大小和文字样式
ctx.strokeText("Canvas", 50, 50);

在这里插入图片描述

fillText 填充字体
ctx.fillText("Canvas", 50, 50);

在这里插入图片描述

文本样式

font 修改文本字体大小及文字样式,默认值:10px sans-serif

textAlign 文本对齐方式,参数为:leftrightcenterstartend,默认值:start

direction 文本方向,参数为:ltr(文本方向从左向右)rtl(文本方向从右向左)inherit(根据情况继承 Canvas元素或者 Document ),默认值是: inherit

ctx.font = "30px serif"; // 设置文案大小和字体
ctx.direction = "ltr"; // 文本方向从左向右
ctx.textAlign = "left"; // 左对齐
ctx.strokeText("Hi Canvas !", 250, 100);
ctx.direction = "ltr"; // 文本方向从左向右
ctx.textAlign = "center"; // 右对齐
ctx.strokeText("Hi Canvas !", 250, 150);
ctx.direction = "ltr"; // 文本方向从左向右
ctx.textAlign = "right"; // 右对齐
ctx.strokeText("Hi Canvas !", 250, 200);
ctx.direction = "rtl"; // 文本方向从左向右
ctx.textAlign = "left"; // 左对齐
ctx.strokeText("Hi Canvas !", 250, 250);
ctx.direction = "rtl"; // 文本方向从左向右
ctx.textAlign = "center"; // 右对齐
ctx.strokeText("Hi Canvas !", 250, 300);
ctx.direction = "rtl"; // 文本方向从左向右
ctx.textAlign = "right"; // 右对齐
ctx.strokeText("Hi Canvas !", 250, 350);

在这里插入图片描述

后续内容待补充…

文章内容借鉴:原文连接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值