Canvas简单整理 - sk

news/2025/11/12 16:05:55/文章来源:https://www.cnblogs.com/xm0328/p/19214390

1. Canvas概述

1.1 Canvas是什么

Canvas又称为“画布”,是HTML5的核心技术之一,通常说的Canvas技术,指的就是使用Canvas元素结合JavaScript来绘制各种图形的技术。

1.2 Canvas的用途

1)绘制图形;2)绘制图表;3)动画效果;4)游戏开发。

1.3 Canvas和SVG的区别

1)Canvas是使用JavaScript动态生成的,SVG是使用XML静态描述的;
2)使用Canvas绘制出来的是一个“位图”,而使用SVG绘制出来的是一个“矢量图”;
3)每次发生修改,Canvas需要重绘,而SVG不需要重绘;
4)Canvas与SVG的关系,就像“美术与几何”的关系。

2. Canvas元素知识

2.1 使用Canvas元素来绘制图形,需要三步:

1)获取canvas对象:
let cnv = document.getElementById('canvas');
2)获取上下文环境对象context:
let cxt = cnv.getContext('2d');
3)绘制图形:
cxt.moveTo(50, 100);
cxt.lineTo(150, 50);
cxt.stroke();
...

2.2 Canvas元素

Canvas是一个行内快元素,一般需要指定其三个属性:id、width和height,默认情况下,Canvas的宽度为300px,高度为150px。
对于Canvas的宽度和高度应该在HTML属性中定义,如果在CSS样式中定义,那么使用canvas对象获取的宽度和高度是默认值,而不是实际的宽度和高度。

2.3 Canvas对象

2.3.1 canvas对象属性
1)width:Canvas的宽度;
2)height:Canvas的高度。

2.3.2 canvas对象方法
1)getContext('2d'):获取Canvas 2D上下文环境对象;
2)toDataURL():获取canvas对象产生的位图的字符串。
HTML5 Canvas暂时只提供2D绘图API,3D绘图可以使用HTML5中的WebGL进行开发。

3. 直线图形

3.1 直线

3.1.1 Canvas坐标系
Canvas使用的坐标系是W3C坐标系。
数学坐标系:y轴正方向向上;W3C坐标系:y轴正方向向下。

3.1.2 一条直线

cxt.moveTo(x1, y1);//起点坐标
cxt.lineTo(x2, y2);//终点坐标
cxt.stroke();//画线

3.1.3 多条直线

cxt.moveTo(x1, y1);//起点坐标
cxt.lineTo(x2, y2);//终点坐标
cxt.lineTo(x3, y3);//终点坐标
...
cxt.stroke();//画线

第二次使用lineTo()后,Canvas会以“上一个终点坐标”作为第二次调用的起点坐标,然后再开始画直线,以此类推。
在实际开发中,对于三角形和多边形,我们都是用moveTo()和lineTo()来实现。

example

const c=document.getElementById("myCanvas");
const ctx=c.getContext("2d");
ctx.moveTo(0,0);
ctx.lineTo(100,50);
ctx.lineWidth = 3;
ctx.strokeStyle = 'green'
ctx.stroke();

3.2 矩形

在Canvas中,矩形分为两种,“描边”矩形和“填充”矩形。
3.2.1 “描边”矩形

cxt.strokeStyle = 属性值;//取值有三种,颜色值、渐变色和图案
cxt.strokeRect(x, y, width, height);//x和y为矩形最左上角的坐标

3.2.2 “填充”矩形

cxt.fillStyle = 属性值;//取值有三种,颜色值、渐变色和图案
cxt.fillRect(x, y, width, height);//x和y为矩形最左上角的坐标

3.2.3 rect()方法

cxt.rect(x, y, width, height);

只有在使用rect()方法之后再调用stroke()或者fill()方法,才会把矩形绘制出来。

3.2.4 清空矩形

cxt.clearRect(x, y, width, height);//清空指定区域的矩形
cxt.clearRect(0, 0, cnv.width, cnv.height);//清空整个Canvas
example
const c = document.getElementById("myCanvas");
const ctx = c.getContext("2d");
ctx.fillStyle = "#FF0000";
ctx.fillRect(0, 0, 150, 75);

4. 曲线图形

4.1 圆形

cxt.beginPath();//开始一个新路径
//x和y表示圆心坐标,开始角度和结束角度都是以“弧度”为单位
//anticlockwise为true时,表示逆时针方向绘制;为false时,表示顺时针方向绘制
cxt.arc(x, y, 半径, 开始角度, 结束角度, anticlockwise);
cxt.closePath();//关闭当前路径

对于开始角度和结束角度,推荐写法:度数*Math.PI/180,例如:

120*Math.PI/180 //120°
150*Math.PI/180 //150°

4.2 “描边”圆

//状态描述
cxt.beginPath();
cxt.arc(x, y, 半径, 开始角度, 结束角度, anticlockwise);
cxt.closePath();
//描边
cxt.strokeStyle = '颜色值';
cxt.sroke();

4.3 “填充”圆

//状态描述
cxt.beginPath();
cxt.arc(x, y, 半径, 开始角度, 结束角度, anticlockwise);
cxt.closePath();
//填充
cxt.fillStyle = '颜色值';
cxt.fill();

4.4 arc()画弧线

//状态描述
cxt.beginPath();
cxt.arc(x, y, 半径, 开始角度, 结束角度, anticlockwise);
//描边
cxt.strokeStyle = '颜色值';
cxt.sroke();

arc()画弧线不使用closePath()来关闭路径,closePath()方法的作用在于关闭路径、连接起点和终点。

4.5 arcTo()画弧线

//(cx, cy)表示控制点的坐标
//(x2, y2)表示结束点的坐标
//radius表示圆弧的半径
cxt.artTo(cx, cy, x2, y2, radius);

画一条弧线需要提供三个点的坐标,开始点、控制点和结束点,一般由moveTo()和lineTo()提供开始点,arcTo()提供控制点和结束点。
arcTo()方法就是利用开始点、控制点和结束点这三个点所形成的夹角,然后绘制一段与夹角的两边相切并且半径为radius的圆弧。
arcTo()方法绘制的弧线是两个切点之间长度最短的那个圆弧。

4.6 二次贝塞尔曲线

//(cx, cy)表示控制点的坐标
//(x2, y2)表示结束点的坐标
cxt.quadraticCurveTo(cx, cy, x2, y2);

4.7 三次贝塞尔曲线

//(cx1, cy1)表示控制点1的坐标
//(cx2, cy2)表示控制点2的坐标
//(x2, y2)表示结束点的坐标
cxt.bezierCurveTo(cx1, cy1, cx2, cy2, x, y)

绘制一条三次贝塞尔曲线需要提供四个点的坐标,开始点、控制点1、控制点2和结束点,一般由moveTo()和lineTo()提供开始点,由bezierCurveTo()提供控制点1、控制点2和结束点。
三次贝塞尔曲线有两个控制点,而二次贝塞尔曲线只有一个控制点。

example
const c=document.getElementById("myCanvas");
const ctx=c.getContext("2d");
ctx.beginPath();
ctx.arc(95,50,40,0,2*Math.PI);
ctx.stroke();

image

      const circleX = 300;const circleY = 300;const data = [80, 65, 98, 50, 60, 90, 55, 32];const total = 80 + 65 + 98 + 50 + 60 + 90 + 55 + 32;let startArc = 0;data.forEach((t) => {ctx.beginPath();ctx.moveTo(circleX, circleY);const endArc = startArc + Math.PI * 2 * (t / total);ctx.arc(300, 300, 100, startArc, endArc, false);ctx.fillStyle = randomColor();startArc = endArc;ctx.fill();});// 随机颜色function randomColor() {const r = Math.floor(Math.random() * 256);const g = Math.floor(Math.random() * 256);const b = Math.floor(Math.random() * 256);return `rgb(${r},${g},${b})`;}

5. 线条操作

5.1 线条操作属性

5.1.1 lineWidth(定义线条宽度)

//默认值为1,默认单位为px
cxt.lineWidth = 整数;

5.1.2 lineCap(定义线帽样式)

//属性值
//Butt:默认值,无线帽,每条线的头端和尾端都是长方形,即不做任何处理
//Round:圆形线帽,每条线的头和尾都增加一个半圆,半圆的直径为线宽长度
//Square:正方形线帽,每条线的头和尾都增加一个长方形,长方形的长度为线宽的一半,高度保持为线宽高度
cxt.lineCap = '属性值';

5.1.3 lineJoin(定义两个线条交接处样式)

//属性值
//miter:默认值,尖角,线段在交接处延伸直至交于一点
//round:圆角,连接处是一个圆角,圆角所在圆的直径等于线宽长度
//bevel:斜角,连接处是一个斜角,斜角所在正方形的对角线长等于线宽长度
cxt.lineJoin = '属性值';

5.2 线条操作方法

setLineDash()(定义线条的虚实样式)

//参数array是一个数组组合,常见的数组组合有:
//[10, 5], [5, 5], [10, 5, 5, 5], [2, 2]
//数组[10, 5]表示的是“10px实线”和“5px空白”重复拼凑组合而成的线型
//数组[10, 5, 5, 5]表示的是“10px实线、5px空白、5px实线、5px空白”重复拼凑组合而成的线型,以此类推
cxt.setLineDash(array);

6. 文本操作

6.1 文本操作方法

6.1.1 fillText()(绘制“填充”文本)

//text:一个字符串文本
//x:表示文本最左边的坐标
//y:表示文本最下边的坐标
//maxWidth:可选,表示允许的最大文本的宽度(单位为px)
cxt.fillText(text, x, y, maxWidth);

6.1.2 strokeText()(绘制“描边”文本)

//text:一个字符串文本
//x:表示文本最左边的坐标
//y:表示文本最下边的坐标
//maxWidth:可选,表示允许的最大文本的宽度(单位为px)
cxt.strokeText(text, x, y, maxWidth);

6.1.3 measureText()(用于获取文本的长度)

//text:一个字符串文本
//该方法返回文本的长度,单位为px
let textWidth = cxt.measureText(text).width;

6.2 文本操作属性

6.2.1 font(定义文本字体样式,大小、粗细等)

//默认值为10px sansserif
cxt.font = 'font-style font-weight font-size/line-height font-family';

6.2.2 textAlign(定义文本水平对齐方式)

//属性值
//start:文本在指定的横坐标开始
//end:文本在指定的横坐标结束
//left:文本左对齐(类似start)
//right:文本右对齐(类似end)
//center:文本的中心被放置在指定的横坐标
cxt.textAlign = '属性值';

6.2.3 textBaseline(定义文本垂直对齐方式)

//alphabetic:文本基线是普通英文字母的基线
//top:文本基线是em方框的顶端
//middle:文本基线是em方框的中心
//bottom:文本基线是em方框的底端
cxt.textBaseline = '属性值';

6.2.4 fillStyle(定义画笔“填充”路径的样式)

cxt.fillStyle = '颜色值';

6.2.5 strokeStyle(定义画笔“描边”路径的颜色)

cxt.strokeStyle = '颜色值';
example
const c=document.getElementById("myCanvas");
const ctx=c.getContext("2d");
ctx.font="30px Arial";
ctx.fillText("Hello World",10,50);

7. 渐变

渐变可以填充在矩形, 圆形, 线条, 文本等等, 各种形状可以自己定义不同的颜色。
以下有两种不同的方式来设置Canvas渐变:
createLinearGradient(x,y,x1,y1) - 创建线条渐变
createRadialGradient(x,y,r,x1,y1,r1) - 创建一个径向/圆渐变
当我们使用渐变对象,必须使用两种或两种以上的停止颜色。
addColorStop()方法指定颜色停止,参数使用坐标来描述,可以是0至1.
使用渐变,设置fillStyle或strokeStyle的值为 渐变,然后绘制形状,如矩形,文本,或一条线。

7.1 使用 createLinearGradient():

// 创建一个线性渐变。使用渐变填充矩形:
const c=document.getElementById("myCanvas");
const ctx=c.getContext("2d");
// 创建渐变
const grd=ctx.createLinearGradient(0,0,200,0);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
// 填充渐变
ctx.fillStyle=grd;
ctx.fillRect(10,10,150,80);

7.2 使用 createRadialGradient():

// 创建一个径向/圆渐变。使用渐变填充矩形:
const c=document.getElementById("myCanvas");
const ctx=c.getContext("2d");
// 创建渐变
const grd=ctx.createRadialGradient(75,50,5,90,60,100);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
// 填充渐变
ctx.fillStyle=grd;
ctx.fillRect(10,10,150,80);

7. 图像

把一幅图像放置到画布上, 使用以下方法:
drawImage(image,x,y,width,height)
img :规定要使用的图像、画布或视频。 x:在画布上放置图像的x坐标轴位置。 y:在画布上放置图像的y坐标轴位置。
width:显示在画布上图片的宽度。 height:显示在画布上图片的高度。

const c=document.getElementById("myCanvas");
const ctx=c.getContext("2d");
const img=document.getElementById("scream");
ctx.drawImage(img,10,10, 120, 100);

end. 总结

// 绘图上下文
getContext('2d'):获取2D绘图上下文对象(ctx),所有绘图操作通过该对象执行。若浏览器不支持Canvas,返回null// 路径绘制方法
stroke() 绘制路径线条 
beginPath():开启新路径,隔离当前图形与之前的路
moveTo(x, y):移动画笔到指定坐标(不绘制)
lineTo(x, y):从当前点绘制线段到目标坐标
closePath():闭合路径(连接当前点与起点)
arc(x, y, r, startAngle, endAngle, anticlockwise):绘制圆弧或圆形,参数包括圆心坐标、半径、起始/结束角度(弧度)、是否逆时针
rect(x, y, width, height):创建矩形路径,需配合stroke()或fill()显式化// 样式与颜色
fillStyle:定义填充颜色/样式,支持颜色值、渐变或图案
strokeStyle:定义描边颜色/样式,用法同fillStyl
lineWidth:线段宽度,默认1px
lineCap:线段端点样式(butt平角、round圆角、square方角,默认butt)
lineJoin:线段连接处样式(miter尖角、round圆角、bevel斜角,默认miter)// 矩形操作
strokeRect(x, y, width, height):直接绘制描边矩形
fillRect(x, y, width, height):直接绘制填充矩形
clearRect(x, y, width, height):清空指定区域的矩形(如clearRect(0,0,canvas.width,canvas.height)清空整个画布)
fill() 填充// 文本绘制
fillText(text, x, y, [maxWidth]):绘制填充文字,需先设置font、textAlign等样式属性
strokeText(text, x, y, [maxWidth]):绘制描边文字,用法同fillText// 注意事项
动态修改width或height会清空画布
角度参数需转换为弧度(如90°对应Math.PI/2)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/963530.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MATLAB小波分析工具包进行时间序列的小波功率谱分析

MATLAB的小波分析工具包(Wavelet Toolbox)提供了强大的功能,用于分析和处理信号与图像。使用MATLAB小波分析工具包进行时间序列的小波功率谱分析的详细步骤。 1. 加载数据 首先,加载需要分析的时间序列数据。假设数…

CPU softlockup(软锁定)

CPU softlockup(软锁定)是 Linux 内核 watchdog 机制报出的“某颗 vCPU 在内核态连续 20 s(默认)没有发生任务切换”的异常。本质是:内核线程/中断上下文长时间关抢占(或死循环),导致该核上的 watchdog 线程得…

再次出山!!

如今,时隔多年,又准备开始重新写博客了!!! 今天先看看效果

营口西林瓶灌装机资质齐全,含医疗器械生产许可与行情报价

近年来,西林瓶灌装机市场受原材料价格波动、核心零部件进口成本变化及区域供需关系影响,整体呈现温和上涨趋势。据行业数据显示,2024年第四季度至2025年第三季度期间,西林瓶灌装设备的终端售价平均涨幅约为6.8%。其…

Tita 项目管理软件:驱动互联网企业高效运营与战略落地新引擎

在当今快节奏的互联网行业中,许多企业虽拥有创新产品与业务蓝图,却常因内部管理机制滞后而陷入发展瓶颈。尤其是中型互联网公司,在业务覆盖软件开发、线上营销与平台运营等多板块时,传统的管理模式往往导致目标断层…

完整教程:Java 反射机制核心类详解:Class、Constructor、Method、Field

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Problems

Done QOJ #970 Best Subsequence $ _{6.3}$定义 \(f(\{a\},k)\) 为最小的 x 使得存在一个 \(a\) 的长度为 \(k\) 的子序列首尾相接以后每两个相邻向之和均 \(\le x\)。 给定数组 \(a\) 和 \(q\) 组询问,每组询问给定 …

vue网站禁止右键以及禁止打开控制台,检测到控制台停止运行

App.vue参考:<template> <div id="app" @contextmenu.prevent="handleContextMenu"> <router-view /> </div></template> <script> export default {…

2025年卡盘式自定心坡口机优质厂家权威推荐榜单:切管机/钢板坡口机/倒角机源头厂家精选

在管道工程与金属加工领域,一台高性能的卡盘式自定心坡口机已成为提升焊接质量与施工效率的关键装备。 本文将基于技术实力、生产能力、产品质量、市场表现及服务体系等多维度核心指标,为您呈现2025年卡盘式自定心坡…

AI元人文:从被动执行到主动探索——基于三值张力的文明演进新范式

AI元人文:从被动执行到主动探索——基于三值张力的文明演进新范式 岐金兰 探索“Ai元人文构想”理论体系 2025年11月12日 摘要: AI元人文理论实现了从"价值对齐"到"价值权衡"的范式革命,通过价…

Java 获取 Excel 中工作表的名称 - 指南

Java 获取 Excel 中工作表的名称 - 指南2025-11-12 15:50 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block …

2025年现代风格卫生间隔断生产厂家权威推荐榜单:易清洁卫生间隔断/欧式卫生间隔断/养老院卫生间隔断源头厂家精选

在公共卫生空间设计日益注重功能与美观并重的今天,现代风格的卫生间隔断已成为商业空间、办公场所和公共建筑的重要配置。 根据建筑装饰行业数据显示,2024年中国公共卫生间隔断市场规模达到87亿元,年增长率稳定在12…

locust-WebSocket压测

连接WS的库有的是支持异步IO的,项目中我们推荐这样的库,但是压测时还是要选择同步的库。 异步 安装 pip install websockets代码示例 import asyncio import websockets import json import randomasync def mytest(…

11.11 CSP-S 模拟赛 T3. square

思路 太猎奇 考虑我们应该会 \(\mathcal{O} (\textrm{障碍物数}^2)\) 的做一次问题 但是这类问题其实还有一种 \(\mathcal{O} (\textrm{面积})\) 的做法 具体的, 令 \(f_{i, j}\) 表示 \((i, j)\) 这个点作为右下角时的…

2025年排渣阀订制厂家权威推荐榜单:陶瓷阀门/搪瓷阀门/铸铁阀门源头厂家精选

在电力、矿山、冶金等工业领域,排渣阀作为输送磨损性、腐蚀性介质的关键设备,其性能直接影响整个生产系统的稳定性和运营成本。 本文将基于企业实力、技术能力、产品质量、市场表现及服务体系等多维度核心指标,为您…

locust常用类和方法解析

from locust import HttpUser, task, between# 相当于模拟一个用户 class WebUser(HttpUser):# 服务器的地址host = http://localhost:8000# 下一个任务执行之前等待的时间,用于模式用户的思考时间wait_time = betwee…

locust高级特性详解

事件系统深度应用 全局事件监听 Locust的事件系统就像是一个"消息广播站",可以在特定时机执行自定义逻辑:@events.test_start.add_listener @events.test_stop.add_listener @events.user_error.add_liste…

Aoao Round 2 比赛总结

分数: \(100 + 25 + 20 + 0 = 145\) 好一个神秘 seq 赛。 T1 不难发现,一个符合要求的序列需要是连续的,且其中比 \(b\) 大的数和比 \(b\) 小的数数量相等。 因此,我们可以以 \(b\) 为起点,分别向两侧扫描,把比 …

基于遗传算法的PID控制器参数整定方法详解

基于遗传算法的PID控制器参数整定方法详解一、算法原理与核心流程 1. 遗传算法优化框架2. 关键参数编码染色体结构:采用实数编码直接表示Kp、Ki、Kd参数取值范围: Kp ∈ [0.1, 100], Ki ∈ [0, 50], Kd ∈ [0, 20] …

QT项目复盘:如何在有限资源下把桌面端做成‘高端应用’?

QT项目复盘:如何在有限资源下把桌面端做成‘高端应用’?项目背景:资源困境与“高端”诉求的矛盾 兰亭妙微曾接手某工业数据分析桌面应用开发,核心诉求是“高端化”——既要满足工程师对数据处理的高性能需求,又要…