关于前端:JavaScript全解析canvas-入门上

27次阅读

共计 5304 个字符,预计需要花费 14 分钟才能阅读完成。

●canvas 是 HTML5 新增的一个标签, 示意画布
●canvas 也是 h5 的画布技术, 咱们通过代码的形式在画布上描述一个图像

canvas 标签
●向进行 canvas 绘图, 首先咱们先要理解到 canvas 标签

●是 html5 推出的一个标签

<html>
<head>
    ...
</head>
<body>
    <canvas></canvas>
</body>
</html>

○canvas 默认是一个行内块元素
○canvas 默认画布大小是 300 * 150
○canvas 默认没有边框, 背景默认为无色通明

canvas 画布大小
●咱们在绘图之前, 先要确定一个画布的大小
○因为画布默认是依照比例调整
○所以咱们调整宽度或者高度的时候, 调整一个, 另一个天然会依照比例本人调整
○咱们也能够宽高一起调整
●调整画布大小有两种计划
○第一种 : 通过 css 款式 (不举荐)

<html>
<head>
    <style>
        canvas {
            width: 1000px;
            height: 500px;
        }
    </style>
</head>
<body>
    <canvas></canvas>
</body>
</html>

○第二种 : 通过标签属性 (举荐)

<html>
<head>
    ...
</head>
<body>
    <canvas width="1000" height="500"></canvas>
</body>
</html>

●两种计划的区别
○通过 css 款式的调整计划, 不举荐
是因为这个计划其实并没有设置了画布的大小
而是把原先 300 150 的画布, 将他的可视窗口变成了 1000 500
所以实在画布并没有放大, 只是可视水平变大了
举个例子 : 就是你把一个 300 150 的图片, 放大到 1000 500 的大小来看
所以这个形式咱们及其不举荐

○通过属性的调整计划, 举荐
这个才是真正的调整画布的的大小
也就是咱们会在一个 1000 * 500 的画布上进行绘制

●画布的坐标
○canvas 画布是和咱们 css 的坐标系一样的
○从 canvas 的左上角为 0 0 右边, 别离向右向下延长为正方向

canvas 初体验
●筹备工作曾经实现了, 咱们能够开始体验一下绘制了
●其实 canvas 画布很简略, 就和咱们 windows 电脑的画板工具是一样的情理

●思考 :
咱们在 windows 这个画板上绘制内容的时候
咱们肯定是先选定一个工具 (画笔, 矩形, 圆形, …)
设定好款式 (粗细, 色彩)
而后开始绘制
●其实在 canvas 绘制也是一个情理
拿到一个画布工具箱
从工具箱中选定工具
设定款式
开始绘制
●初体验步骤
●index.html

<html>
<head>
    ...
</head>
<body>
    <canvas id="canvas" width="600" height="300"></canvas>

    <script src="./index.js"></script>
</body>
</html>

●index.js

// 0. 获取到页面上的 canvas 标签元素节点
const canvasEle = document.querySelector('#canvas')

// 1. 获取以后这个画布的工具箱
// 语法: canvas 元素.getContext('2d')
const ctx = canvasEle.getContext('2d')

// 2. 开始绘制
// 2-1. 讲画笔挪动到一个指定地位开始下笔
// 语法: 工具箱.moveTo(x 轴坐标, y 轴坐标)
ctx.moveTo(100, 100)

// 2-2. 将笔挪动到一个指定地位, 画下一条轨迹
// 留神: 这里是没有显示的, 因为只是画了一个轨迹
// 语法: 工具箱.lineTo(x 轴坐标, y 轴坐标)
ctx.lineTo(300, 100)

// 2-3. 设定本条线的款式
// 设定线的宽度
// 语法: 工具箱.lineWidth = 数字
ctx.lineWidth = 10
// 设定线的色彩
// 语法: 工具箱.strokeStyle = '色彩'
ctx.strokeStyle = '#000'

// 2-4. 描边
// 把上边画下的痕迹依照设定好的款式描绘下来
// 语法: 工具箱.stroke()
ctx.stroke()

●至此咱们的第一个线段就绘制结束, 画布上就会呈现一条线段
○从坐标 (100, 100) 绘制到坐标 (300, 100)
○线段长度为 200px
○线段宽度为 10px
○线段色彩为 ‘#000’ (彩色)

canvas 线宽色彩问题
●方才咱们通过了初体验, 画了一个线段
●看似没有问题, 也呈现了线段, 然而其实外在是有一些问题的
●咱们先来察看
●这次咱们再来画一个线段
○从坐标 (100, 100) 绘制到坐标 (300, 100)
○线段长度为 200px
○线段宽度为 1px
○线段色彩为 ‘#000’ (彩色)

// 0. 获取到页面上的 canvas 标签元素节点
const canvasEle = document.querySelector('#canvas')

// 1. 获取以后这个画布的工具箱
const ctx = canvasEle.getContext('2d')

// 2. 开始绘制
ctx.moveTo(100, 100)

// 2-2. 将笔挪动到一个指定地位, 画下一条轨迹
ctx.lineTo(300, 100)

// 2-3. 设定本条线的款式
// 设定线的宽度
ctx.lineWidth = 10
// 设定线的色彩
ctx.strokeStyle = '#000'

// 2-4. 描边
ctx.stroke()

●成果呈现了, 没有什么问题
●只是看上去不太想 1px, 而且色彩有些浅
●不焦急, 咱们再来画一个线段
○从坐标 (100, 100) 绘制到坐标 (300, 100)
○线段长度为 200px
○线段宽度为 2px
○线段色彩为 ‘#000’ (彩色)

●这个时候问题就呈现了
○两次画进去的线段, 一次设置 1px 一次设置 2px
○感觉上 线宽度 一样
○两次画进去的线段, 两次都是设置为 ‘#000’ 的色彩
○然而感觉上色彩不太一样

●这是因为浏览器在形容内容的时候, 最小的形容单位是 1px
●咱们来模仿一下浏览器绘制的内容
○假如这是咱们浏览器形容的画布中的像素点

○咱们来做一个坐标的标记

○当初呢不关注线的长度和坐标, 咱们就画一个宽度为 1px 的线段

○咱们来分析一下问题
因为在描述这个线段的时候, 会把线段的最中心点放在这个像素点位上
也就是说, 在形容线宽的时候, 实际上会从 0.5px 的地位绘制到 1.5px 的地位
共计形容宽度为 1px
然而浏览器的最小形容为 1px
这里说的不是最小宽度为 1px, 是浏览器不能在非整数像素开始形容
也就是说浏览器没方法从 0.5 开始绘制, 也没有方法绘制到 1.5 进行
那么就只能是从 0 开始绘制到 2
所以线宽就会变成 2px 了
因为自身一个像素的彩色被强制拉伸到两个像素宽度, 所以色彩就会变浅
就像咱们一杯墨水, 倒在一个杯子外面就是彩色
然而到在一个杯子外面的时候, 又倒进去一杯水, 色彩就会变浅
○理论描绘出来的样子

○这就变成了咱们方才看到的样子
●所以, 咱们在进行 canvas 绘制内容的时候, 波及到线段的时候
●咱们个别不会把线段宽度设置成奇数, 个别都是偶数的

canvas 绘制平行线
●方才咱们绘制了线段, 接下来咱们来绘制一个平行线, 也就是两个线段
●小伙伴: ” 一个简略的成果, 想到就搞 “

// 0. 获取到页面上的 canvas 标签元素节点
const canvasEle = document.querySelector('#canvas')

// 1. 获取以后这个画布的工具箱
const ctx = canvasEle.getContext('2d')

// 2. 开始绘制第一个线段
ctx.moveTo(100, 100)
ctx.lineTo(300, 100)
ctx.lineWidth = 2
ctx.strokeStyle = '#000'
ctx.stroke()

// 3. 开始绘制第二个线段
ctx.moveTo(100, 100)
ctx.lineTo(300, 100)
ctx.lineWidth = 2
ctx.strokeStyle = '#000'
ctx.stroke()

●没有问题, 成果实现了

●接下来, 咱们略微减少一下需要
○第一个线段线宽 2px, 彩色
○第二个线段线宽 10px, 红色
●这也简略啊, 略微批改一下

// 0. 获取到页面上的 canvas 标签元素节点
const canvasEle = document.querySelector('#canvas')

// 1. 获取以后这个画布的工具箱
const ctx = canvasEle.getContext('2d')

// 2. 开始绘制第一个线段
ctx.moveTo(100, 100)
ctx.lineTo(300, 100)
ctx.lineWidth = 2
ctx.strokeStyle = '#000'
ctx.stroke()

// 3. 开始绘制第二个线段
ctx.moveTo(100, 100)
ctx.lineTo(300, 100)
ctx.lineWidth = 10
ctx.strokeStyle = 'red'
ctx.stroke()

●这是什么鬼, 为什么两个线段都变了, 不是应该只扭转一个吗 ?
这是因为咱们并没有通知他这是两个不一样的线段
所以在设置线段款式的时候, 会默认依照最初一次设置的款式来绘制所有的线段
咱们要想让第一个线段绘制结束当前, 和第二个没有关系
咱们须要通知画布, 我的这个线段完结了, 前面的不要和我扯上关系

// 0. 获取到页面上的 canvas 标签元素节点
const canvasEle = document.querySelector('#canvas')

// 1. 获取以后这个画布的工具箱
const ctx = canvasEle.getContext('2d')

// 2. 开始绘制第一个线段
ctx.moveTo(100, 100)
ctx.lineTo(300, 100)
ctx.lineWidth = 2
ctx.strokeStyle = '#000'
ctx.stroke()

// 3. 完结之前的绘制内容
// 语法: 工具箱.beginPath()
ctx.beginPath()

// 4.. 开始绘制第二个线段
ctx.moveTo(100, 100)
ctx.lineTo(300, 100)
ctx.lineWidth = 10
ctx.strokeStyle = 'red'
ctx.stroke()

●这样才是咱们的需要

canvas 绘制三角形
●画完了线段, 咱们就来画一个简略的图形, 画一个三角形
●其实就是由三个线段组成, 用三个线段围成一个关闭图形即可

// 0. 获取到页面上的 canvas 标签元素节点
const canvasEle = document.querySelector('#canvas')

// 1. 获取以后这个画布的工具箱
const ctx = canvasEle.getContext('2d')

// 2. 开始绘制第一个线段
// 三角形第一个点
ctx.moveTo(100, 100)
// 三角形第二个点
ctx.lineTo(200, 100)
// 三角形第三个点
ctx.lineTo(200, 200)
// 回到第一个点
ctx.lineTo(100, 100)
ctx.lineWidth = 2
ctx.strokeStyle = '#000'
// 描边
ctx.stroke()

●看似没啥问题, 一个三角形就进去了●然而咱们仔细观察一下三角形的第一个角

●因为这是两个线段, 只是画到了一个点, 不可能重叠出一个 尖儿~~
●这个时候, 咱们就不能这样绘制三角形了
当咱们要绘制闭合图形的时候
咱们不要手动绘制最初一个门路, 而是形容出形态
通过 canvas 让他主动闭合
●首先, 咱们绘制出形态, 不要闭合最终门路

// 0. 获取到页面上的 canvas 标签元素节点
const canvasEle = document.querySelector('#canvas')

// 1. 获取以后这个画布的工具箱
const ctx = canvasEle.getContext('2d')

// 2. 开始绘制第一个线段
// 三角形第一个点
ctx.moveTo(100, 100)
// 三角形第二个点
ctx.lineTo(200, 100)
// 三角形第三个点
ctx.lineTo(200, 200)

ctx.lineWidth = 2
ctx.strokeStyle = '#000'
// 描边
ctx.stroke()

●接下来, 让 canvas 来帮咱们闭合这个关闭图形

// 0. 获取到页面上的 canvas 标签元素节点
const canvasEle = document.querySelector('#canvas')

// 1. 获取以后这个画布的工具箱
const ctx = canvasEle.getContext('2d')

// 2. 开始绘制第一个线段
ctx.moveTo(100, 100)
ctx.lineTo(200, 100)
ctx.lineTo(200, 200)

// 主动闭合图形
// 语法: 工具箱.closePath()
ctx.closePath()

ctx.lineWidth = 2
ctx.strokeStyle = '#000'
// 描边
ctx.stroke()

●这个时候, 咱们发现一个失常的三角形就呈现了
●留神 : 闭合门路
closePath() 这个办法
是从以后坐标点, 间接用线段的形式连贯到 modeTo() 的地位
也就是从以后坐标点间接连贯到开始坐标点

正文完
 0