Canvas 基础使用

news2025/7/22 5:25:27

一、基本的画布功能

创建 <canvas>元素时至少要设置 width 和 height 属性,这样才能告诉浏览器在多大面积上绘图。出现在标签包裹里的内容会在浏览器不支持 <canvas>元素时显示。比如:

<canvas id="drawing" width="200" height="200">A drawing of something.</canvas>

1.1 绘图上下文

使用 getContext() 方法可以获取对绘图上下文的引用。对于平面图形,需要给这个方法传入参数“2d”,表示要获取 2D 上下文对象:

const drawing = document.getElementById('drawing')
// 确保浏览器支持 canvas 
if (drawing.getContext) {
  const canvas = drawing.getContext('2d')
  // 其他代码
}

可以使用 toDataURL() 方法导出<canvas>元素上的图像。这个方法接收一个参数:要生成图像的 MIME 类型(与用来创建图形的上下文无关)。例如,从画布上导出一张 PNG格式的图片:

const drawing = document.getElementById('drawing')
// 确保浏览器支持 canvas 
if (drawing.getContext) {
  // 取得图像的数据 URI
  const imageURI = drawing.toDataURL('image/png')
  
  // 显示图片
  const image = document.creatElement('img')
  image.src = imageURI
  document.body.appendChild(image)
}

1.2 填充和描边

填充以指定样式(颜色、渐变或图像)自动填充形状,而描边只为图形边界着色。显示效果取决于两个属性:fillStyle 和 strokeStyle。

这两个属性可以是字符串、渐变对象或图案对象,默认值都为“#000000”。字符串表示颜色值,可以是 CSS 支持的任一格式:名称、十六进制代码、rgb、rgba、hsl 或 hsla。比如:

const drawing = document.getElementById('drawing')
// 确保浏览器支持 canvas 
if (drawing.getContext) {
  const canvas = drawing.getContext('2d')
  canvas.fillStyle = 'red'
  canvas.strokeStyle = '#0000ff'
}

1.3 绘制矩形

方法有3个:fillRect()、strokeRect() 和 clearRect()。这些方法都接收4个参数:矩形 x 坐标、矩形 y 坐标、矩形宽度和矩形高度。

1.3.1 fillRect

const drawing = document.getElementById('drawing')

if (drawing.getContext) {
  const canvas = drawing.getContext('2d')

  // 绘制红色矩形
  canvas.fillStyle = '#ff0000'
  canvas.fillRect(10, 10, 50, 50)

  // 绘制半透明蓝色矩形
  canvas.fillStyle = 'rgba(0, 0, 255, 0.5)'
  canvas.fillRect(30, 30, 50, 50)
}

绘制效果如下:
在这里插入图片描述

1.3.2 strokeRect

const drawing = document.getElementById('drawing')

if (drawing.getContext) {
  const canvas = drawing.getContext('2d')

  // 绘制红色轮廓的矩形
  canvas.strokeStyle = '#ff0000'
  canvas.strokeRect(10, 10, 50, 50)

  // 绘制半透明蓝色轮廓的矩形
  canvas.strokeStyle = 'rgba(0, 0, 255, 0.5)'
  canvas.strokeRect(30, 30, 50, 50)
}

绘制效果如下:
在这里插入图片描述

描边宽度由 lineWidth 属性控制,它可以是任意整数值。类似地,lineCap 属性控制线条端点的形状[“butt”(平头)、“round”(出圆头)或“square”(出方头)],而 lineJoin 属性控制线条交点的形状[“round”(圆转)、“bevel”(取平)或“miter”(出尖)]。

1.3.3 clearRect

擦除画布中某个区域

const drawing = document.getElementById('drawing')

if (drawing.getContext) {
  const canvas = drawing.getContext('2d')

  // 绘制红色矩形
  canvas.fillStyle = '#ff0000'
  canvas.fillRect(10, 10, 50, 50)

  // 绘制半透明蓝色矩形
  canvas.fillStyle = 'rgba(0, 0, 255, 0.5)'
  canvas.fillRect(30, 30, 50, 50)

  // 在前两个矩形重叠的区域上擦除一个矩形区域
  canvas.clearRect(40, 40, 10, 10)
}

绘制效果如下:
在这里插入图片描述

1.4 绘制路径

要绘制路径,必须首先调用 beginPath() 方法以表示要开始绘制新路径。然后,再调用下列方法来绘制路径:

  • arc(x, y, radius, startAngle, endAngle, counterclockwise)
    • x: x 坐标
    • y: y 坐标
    • radius: 半径
    • startAngle: 起始角度
    • endAngle: 结束角度
    • counterclockwise: 可选的Boolean值,如果为 true,逆时针绘制圆弧,反之,顺时针绘制
  • arcTo(x1, y1, x2, y2, radius): 以给定半径 radius,经由 (x1, y1) 绘制一条从上一点到 (x2, y2) 的弧线
  • bezierCurveTo(c1x, c1y, c2x, c2y, x, y): 以 (c1x, c1y) 和 (c2x, c2y) 为控制点,绘制一条从上一点到 (x, y) 的弧线(三次贝塞尔曲线)
  • lineTo(x, y): 绘制一条从上一点到 (x, y) 的直线
  • moveTo(x, y): 不绘制线条,只把绘制光标移动到 (x, y)
  • quadraticCurveTo(cx, cy, x, y): 以 (cx, cy) 为控制点,绘制一条从上一点到 (x, y) 的弧线(二次贝塞尔曲线)
  • rect(x, y, width, height): 以给定宽度和高度在坐标点 (x, y) 绘制一个矩形。这个方法与 fillRect() 和 strokeRect() 的区别在于,它创建的是一条路径,而不是独立的图形

创建路径之后,可以使用 closePath() 方法绘制一条返回起点的线

const drawing = document.getElementById('drawing')

if (drawing.getContext) {
  const canvas = drawing.getContext('2d')

  // 创建路径
  canvas.beginPath()

  // 绘制外圆
  canvas.arc(100, 100, 99, 0, 2 * Math.PI)

  // 绘制内圆
  canvas.moveTo(194, 100)
  canvas.arc(100, 100, 94, 0, 2 * Math.PI)

  // 绘制分针
  canvas.moveTo(100, 100)
  canvas.lineTo(100, 15)

  // 绘制时针
  canvas.moveTo(100, 100)
  canvas.lineTo(35, 100)

  // 描画路径
  canvas.stroke()
}

绘制效果如下:
在这里插入图片描述

1.5 绘制文本

提供了 fillText() 和 strokeText() 两个方法。都接收4个参数:要绘制的字符串、x 坐标、y 坐标和可选的最大像素宽度。而且,这两个方法最终绘制的结果都取决于以下3个属性:

  • font: 以 CSS 语法指定的字体样式、大小、字体族等,比如“10px Arial”
  • textAlign: 指定文本的对齐方式,可能的值包括“start”、“end”、“left”、“right”和“center”。推荐使用“start”和“end”,不使用“left”和“right”
  • textBaseLine: 指定文本的基线,可能的值包括“top”、“hanging”、“middle”、“alphabetic”、“ideographic”和“bottom”

这些属性都有相应的默认值,因此没必要每次绘制文本时都设置它们。fillText() 方法使用 fillStyle 属性绘制文本,而 strokeText() 方法使用 strokeStyle 属性

// 正常
canvas.font = '14px Arial'
canvas.textAlign = 'center'
canvas.textBaseLine = 'middle'
canvas.fillText('12', 100, 20)

// 与开头对齐
canvas.textBaseLine = 'start'
canvas.fillText('12', 100, 40)

// 与末尾对齐
canvas.textBaseLine = 'end'
canvas.fillText('12', 100, 60)

1.6 变换

  • rotate(angle): 围绕原点把图像旋转 angle 弧度
  • scale(scaleX, scaleY): 通过在 x 轴乘以 scaleX、在 y 轴乘以 scaleY 来缩放图像
  • translate(x, y): 把原点移动到(x, y)。执行这个操作后,坐标(0, 0)就会变成(x, y)
  • transform(m1_1, m1_2, m2_1, m2_2, dx, dy): 像下面这样通过矩形乘法直接修改矩阵
    m1_1 m2_1 dx
    m1_2 m2_2 dy
    0 0 1
  • setTransform(m1_1, m1_2, m2_1, m2_2, dx, dy): 把矩形重置为默认值,再以传入的参数调用 transform()

1.7 阴影

可以根据以下属性值自动为已有形状或路径生成阴影

  • shadowColor: CSS 颜色值,表示要绘制的阴影颜色,默认为黑色
  • shadowOffsetX: 阴影 x 坐标偏移量
  • shadowOffsetY: 阴影 y 坐标偏移量
  • shadowBlur: 像素,表示阴影的模糊量
canvas.shadowColor = 'rgba(0, 0, 0, 0.5)'
canvas.shadowOffsetX = 5
canvas.shadowOffsetY = 5
canvas.shadowBlur = 4

1.8 渐变

调用上下文的 createLinearGradient() 方法。这个方法接收4个参数:起点 x 坐标、起点 y 坐标、终点 x 坐标和终点 y 坐标。调用之后,会以指定大小创建一个新的 CanvasGradient 对象并返回实例

有了 gradient 对象后,接下来要使用 addColorStop() 方法为渐变指定色标。这个方法接收两个参数:色标位置和 CSS 颜色字符串。色标位置通过 0 ~ 1 范围内的值表示,0 是第一种颜色,1 是最后一种颜色。比如:

const gradient = canvas.createLinearGradient(30, 30, 70, 70)
gradient.addColorStop(0, 'white')
gradient.addColorStop(1, 'black')

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

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

相关文章

PumpkinBook Reading(一)

绪论 基本术语 “算法”是指从数据中学得“模型”的具体方法&#xff0c;“算法”产出的结果称为“模型”&#xff0c;通常是具体的函数或者可抽象地看作为函数。 样本&#xff1a;也称为“示例”&#xff0c;是关于一个事件或对象的描述。因为要想让计算机能对现实生活中的事…

【Python开发】Flask开发实战:个人博客(三)

Flask开发实战&#xff1a;个人博客&#xff08;三&#xff09;在【Python开发】Flask开发实战&#xff1a;个人博客&#xff08;一&#xff09; 中&#xff0c;我们已经完成了 数据库设计、数据准备、模板架构、表单设计、视图函数设计、电子邮件支持 等总体设计的内容。 在【…

公众号裂变拉新,以婴儿辅食为诱饵,实现低成本获客!

大家好~我是娜娜 今天来给大家拆解一个关于食品行业精选公众号增长案例&#xff0c;通过公众号裂变拉新&#xff0c;任务拉新人数5000&#xff0c;留存率达到85%&#xff0c;活动裂变率达到1100.86%。活动数据也还在持续的上升当中。 该公众号的目标人群是新手爸妈&#xff0…

【Java】SpringBoot应用简单示例

SpringBoot应用简单示例SpringBoot应用简单示例HelloWorld搭建项目ResponseBody的作用ComponentScan排除扫描beanSpringBoot集成日志SpringBoot日志初始化原理消息转换器拦截器过滤器操作数据库Spring Data JpaDruid数据源Mybatis-Plus事务处理操作缓存AOP相关概念栗子定时任务…

C语言解析JSON源码

它与 XML 的地位差不多&#xff0c;但就笔者而言&#xff0c;笔者更喜欢 JSON 的风格&#xff0c;因为它更符合我们的思维习惯&#xff0c;同样一份数据&#xff0c;JSON 格式的就是比 XML 要清晰明了一些。 最近笔者需要在 C语言 上解析 JSON 格式&#xff0c;在网上一顿找&am…

XC5VLX30T-2FF323I Virtex-5 LXT FPGA IC 产品参数

概述 Virtex-5 FPGA有-3&#xff0c;-2&#xff0c;-1速度等级&#xff0c;其中-3具有最高的性能。Virtex-5 FPGA直流和交流特性指定为商业和工业级别。除工作温度范围外&#xff0c;除非另有说明&#xff0c;所有直流和交流电气参数对于特定转速等级是相同的(即-1转速等级的工…

一夜登顶GitHub!字节内网数据结构与算法刷题笔记,看完直呼卧槽

网络上流传着一句段子“程序员两条腿&#xff0c;一条是算法&#xff0c;一条是英文&#xff0c;想跑的更远&#xff0c;这两条腿都不能弱”。英文&#xff0c;我们暂且不谈&#xff0c;我们先来谈谈算法。 算法之难&#xff0c;在于将精巧的逻辑&#xff0c;通过合适的数据结…

2 分钟,教你用 Serverless 每天给女朋友自动发土味情话

作者&#xff1a;安可 Serverless 简介 Serverless&#xff0c;中文意思是 “无服务器”&#xff0c;所谓的无服务器并非是说不需要依靠服务器等资源&#xff0c;而是说开发者再也不用过多考虑服务器的问题&#xff0c;可以更专注在产品代码上&#xff0c;同时计算资源也开始…

如何根据自己的SCI论文,匹配适合的期刊? - 易智编译EaseEditing

如何选择合适的目标期刊是需要慎重对待的问题&#xff0c;它决定了你论文的发表速度和被认可度。 可以遵循以下几个步骤来考虑&#xff1a; 1、从你论文的参考文献中选择合适的期刊&#xff08;如果引用文献较少&#xff0c;也可以从引文的参考文献中进行筛选&#xff09;&…

成功解决:ModuleNotFoundError: No module named ‘amp_C‘

在使用transformers时&#xff0c;在调用Trainer的时候遇到了这个问题&#xff0c;原因是apex包有问题&#xff0c; 这里有解决apex安装包的多一些教程 https://blog.csdn.net/Xidian185/article/details/122745427 https://blog.csdn.net/weixin_45225975/article/details/119…

倍福TwinCAT3中使用久同伺服

目录 一、测试设备说明 二、伺服通电和参数设置 1、恢复出厂参数设置 2、恢复出厂&#xff0c;重启后 3、伺服自己点动操作 4、增益、刚度调整 5、伺服零位设定 6、伺服转动一圈编码器脉冲量设定 7、参数保存 三、伺服操作面板 四、TwinCAT3工程配置 1、XML文件 2、…

【元宇宙欧米说】打造艺术与技术构建的交互式数字旅程

Web3 to Earn项目如何扩大应用功能和场景&#xff1f;在Web3时代怎么才能以更新颖、有趣的方式追赶潮流&#xff1f;各Web3领域项目及应用如何进行功能外延以满足用户需求&#xff1f; 11月17日晚上九点&#xff0c;ZenCats项目管理员Fred将以“打造艺术与技术构建的交互式数字…

编码格式转换方法

今天项目上遇到了需要将 SJIS(Shift-JIS) 格式与 UTF8 格式相互转换问题。 首先看一个编码格式问题引发的乱码现象&#xff0c;新建下面的文本文档&#xff0c;然后更名为 test.bat。 echo off echo test chinese character view 测试中文字符显示 pause双击运行 用 chcp 查…

正版授权| iObit Uninstaller 12 Pro 专业卸载器工具

前言 专业的Win系统卸载程序&#xff0c;它可以轻松删除不需要的程序&#xff0c;插件和Windows应用程序&#xff0c;还可以对电脑旧的应用一键更新。安装监视器会检测并记录安装中的所有系统更改&#xff0c;以确保在将来彻底卸载时可以还原所有更改。 功能特点 安装监视器 …

1053 Path of Equal Weight

Given a non-empty tree with root R, and with weight Wi​ assigned to each tree node Ti​. The weight of a path from R to L is defined to be the sum of the weights of all the nodes along the path from R to any leaf node L. Now given any weighted tree, you a…

QT获取计算机硬件信息

一、项目介绍 本文介绍利用QProcess获取计算机的CPU、主板、硬盘等电脑相关硬件信息。 windows提供了“wmic”&#xff08;Windows Management Instrumentation&#xff0c;Windows管理工具&#xff09;&#xff0c;提供了从命令行接口和批命令脚本执行系统管理的支持。可以打…

基于多个openEuler物理机执行mugen测试脚本

【原文链接】基于多个openEuler物理机执行mugen测试脚本 mugen脚本中有的脚本执行需要使用多个物理机&#xff0c;针对此场景&#xff0c;这里以需要两个物理机为例&#xff08;用openEuler虚拟机模拟物理机&#xff09; &#xff08;1&#xff09;首先安装两台openEuler虚拟…

【C++】C++基础知识(一)---基本概念

C基础知识&#xff08;一&#xff09;1. 输出“HelloWorld!”2. 添加注释3. 关键字4. 标识符5. 变量6. 常量1. 输出“HelloWorld!” 在visual studio中输出“HelloWorld!”。代码实现如下&#xff1a; #include <iostream> using namespace std;int main() {cout <&…

unity搭建xlua和emmy_lua的debug环境

配置步骤 1 环境 1.1 vscode 安装emmy_lua 1.2 安装对应的lua版本 1.3 安装java8并配置环境 1.4 emmy_lua的github上下载emmy_lua的64位版本&#xff0c;解压放到工程目录client\Tools\EmmyLua\ 下载地址&#xff1a;https://github.com/EmmyLua/EmmyLuaDebugger/release…

「Redis数据结构」动态字符串(SDS)

「Redis数据结构」动态字符串&#xff08;SDS&#xff09; 文章目录「Redis数据结构」动态字符串&#xff08;SDS&#xff09;[toc]一、前言二、概述三、C字符串与SDS的区别获取字符串长度复杂度杜绝缓冲区溢出减少修改字符串时的内存分配次数二进制安全兼容部分C字符串函数参考…