当前位置: 首页 > news >正文

学习Canvas过程中2D的方法、注释及感悟一(通俗易懂)

1.了解Canvas:

        Canvas是前端一个很重要的知识点,<canvas>标签用于创建画布绘制图形,通过JavaScript进行操作。它为开发者提供一个动态绘制图形的区域,用于创建图标、游戏动画、图像处理等。

        对于能够熟练使用Canvas的开发者来说,能够创建出很多令人惊奇的效果,因为我也是刚学了一半,所以对于Canvas要实现的真实目标还不是特别了解,但是对于初学者或者急需使用一些简单方法的同学来说还是会有一些帮助的。Canvas有2D画布和3D画布,目前我学习的仅是2D。

2.学习过程中对Canvas方法的认识

        对于一个图形来说,有两种绘制方式,一种是路径(stroke),另一种是填充(fill)。以长方形为例,路径就是只描绘出长方形的轮廓,脱俗来说就是画一个空心长方形;填充就是指这个长方形区域内都属于该长方形,通俗来说就是画一个实心长方形。这两个概念对于了解PS的同学应该会很容易了解,不了解PS的同学也不用着急,继续往下看,按照下面的方法写一下就可以感受到路径和填充的区别。规律一对于Canvas中所有带有stroke/fill的方法基本都可以使用fill/stroke进行替换,用来切换绘制路径或者绘制填充

        在绘制图形时,有些图形的方法可以使用“绘制方法+图形(图形首字母大写)”来表示,例如对于绘制矩形来说:fillRect就是绘制填充矩形,strokeRect就是绘制路径矩形。但是并不是所有的图形都可以这样写,比如绘制弧线(arc),也就时圆形,当弧度为2PI时就是一个圆,它就不可以使用fillArc或者strokeArc来绘制。但是所有图形都可以分开写,依然以矩形为例:

//参数先不写,下面会详细说
ctx.rect()
ctx.fill()//绘制填充矩形
ctx.stroke()//绘制路径矩形

 规律二Canvas中绘制图形都可以通过分开来写,但是并不是所有都可以使用简写

3.基本代码解释

//HTML
<!-- id:标识元素的唯一性width:画布的宽度height:画布的宽度-->
<canvas id="c1" width="500" height="500" style="border: 1px solid;"></canvas>//JS
//获取画布
let c1 = document.getElementById('c1')
//获取2D画笔,上下文对象,该对象一般使用ctx表示
let ctx = c1.getContext('2d')

 上面展示的代码中是使用2Dcanvas的必写步骤,第一行代码中的style表示给画布一个边框,方便我们观察画布和图形的具体位置和大小,第三行表示的就是获取2D画笔。

值得一说的是:因为我目前对canvas理解还不是特别深刻,所以没办法理解只在CSS中设置宽高或者不设置宽高的绘制方法,但是如果都设置的话就会出现一定的问题——如果在CSS中为canvas标签设置宽高,如果设置的和canvas标签中的相同,那么就没有影响;如果在CSS中设置的宽高与canvas标签中设置的不同,那么绘制出来的图形也会按照canvas标签中的宽/高与CSS中宽/高之比进行一定的变化,导致即使画出的时正方形,那么绘制出来也不是正方形。因此得出规律三一般情况下只在canvas中设置宽高

4.方法详解

        3.1.绘制方法(因为分开写是通用的,所以以分开为例):

                3.1.1.绘制矩形:

                        ctx.rect(左上角x坐标,左上角y坐标,矩形宽,矩形高)

                3.1.2.绘制弧形:

                        ctx.arc(圆心x坐标,圆心y坐标,开始时弧度位置,结束时弧度位置,[顺/逆时针绘制])        //开始/结束时弧度位置使用的时弧度制,弧度的单位是:Math.PI,1Math.PI=180°,初始0弧度是x轴正方向。最后一个参数是布尔类型,可以省略的,默认是false(顺时针),可以修改为true(逆时针)。

                3.1.3.绘制线段

                        ctx.moveTo(落笔点x坐标,落笔点y坐标)        //众所周知,大家在写字时,是通过不断抬笔、落笔画出的一条条线段组成的文字,在画布上时也相当于这样,该方法就是类似抬笔并且将笔放到指定的位置,如果不使用该方法,那么无论画出来的图形还是线端,都会“连笔”,显得不好看,而在绘制线段中的作用就是设置线段出事的落笔点。

                        ctx.lineTo(结束点x坐标,结束点y坐标)        //如果再次调用该方法,并且使第二个结束点坐标与moveTo设置的落笔点和上一个落笔点不处于一条直线,那么就可以绘制出一条折线。

                3.1.4.第二种绘制弧形的方法

                        ctx.arcTo(夹角点x坐标,夹角点y坐标,第三个点x坐标,第三个点y坐标,半径)

                        //该方法同样需要使用moveTo()来设置第一个点,该方法的原理如下:连接第一个点和夹角点,连接第三个点和夹角点,此时三个点组成一个以夹角点为顶点的角,此时的圆心就是向两条边做垂线,当两边长度都是设置的半径时,此时以两条边焦点为圆心,垂直两条边的两个点画圆弧,得到的就是该方法获得的圆弧。因为该方法使用较为困难并且使用场景较少,因此,一般情况下使用arc即可。

                3.1.5.关于二次贝塞尔曲线和三次贝塞尔曲线

                都需要使用ctx.moveTo()来设置初始位置,二次贝塞尔曲线和三次贝塞尔曲线都是用来画不规则曲线的,二次贝塞尔曲线是用一个控制点加开始点和结束点来绘制弧形,三次贝塞尔曲线是用两个控制点加开始点和结束点来绘制弧形,因此三次贝塞尔曲线可以画出更复杂精确的弧线。

                二次贝塞尔曲线

                        ctx.quadratcCurveTo(控制点x坐标,控制点y坐标,结束点x坐标,结束点y坐标)        具体原理如下图:这个理解起来不好说,只能去看视频自己理解了。

                三次贝塞尔曲线

                        ctx.bezierCurveTo(控制点1x坐标,控制点1y坐标,控制点2x坐标,控制点2y坐标,结束点x坐标,结束点y坐标)        //具体的画图原理同样不是特别理解,这需要同学们自己观看这一块来学习了。原理如下图:

 

        3.2.样式方法:

                3.2.1.设置颜色:

                        ctx.fillStyle='颜色'        //设置填充颜色,引号内参数“颜色”可以使用单词、rgb格式、rgba格式或者十六进制格式都可以。根据规律一,可以将fill换成stroke表示设置路径颜色。

                3.2.2.路径分段:

                        在上面大家应该看到了对moveTo()的注释,moveTo()的作用是一个抬笔并落笔到指定点的操作,而路径分段则相当于直接告诉canvas——接下来绘制的东西和上一个没关系了。于是canvas就会自动抬笔,从而实现取消“连笔”的效果。

                        语法:

                                ctx.beginPath()        //分段开始

                                ...                        //内容

                                ctx.closePath()        //分段结束

                        而路径分段有一些注意点:在路径分段内,可以定义本段路径的属性,比如每段都可以设置自己的颜色等。注意:在不同的路径分段中,定义的属性会向下一个分区传播,但是不会向上一个分区传播。同一分区中的属性以绘制前最后一次定义为主;不仅是在分段中,即使不分段也会是这样,规律四在canvas的属性设置中,以绘制前最后一次定义为主,即使在分段中也是一样。如下:

ctx.fillStyle='red'//分段外设置红色
ctx.fillRect(100, 100, 100, 100)//红色矩形
ctx.beginPath()//分段开始
ctx.arc(300,300,100,0,Math.PI*2)//定义一个圆
ctx.fillStyle='black'//设置黑色
ctx.fill()//绘制上面定义的所有图形,黑色,如果没有上一行的颜色设置那么就是红色
ctx.fillStyle="yellow"//设置黄色,因为是在绘制之后设置的,所以对本分段内图形无影响,只能影响下方绘制的图形
ctx.closePath()

就在刚才,我得到了规律五在canvas中,一旦获取画笔之后,所有的方法(除了图片加载结束)都需要加上画笔变量“ctx”(因为我在写分段的时候没有加ctx,所以一直绘制不成功qwq)。

                3.2.3.设置透明度

                        语法:ctx.globlAlpha="值"        //值为0~1,可以设置全局,rgba只能设置单个。

       因时间问题,先不继续写了,下次该讲解渐变。

附带Canvas文档:Canvas 教程 - Web API | MDN (mozilla.org)

相关文章:

学习Canvas过程中2D的方法、注释及感悟一(通俗易懂)

1.了解Canvas&#xff1a; Canvas是前端一个很重要的知识点&#xff0c;<canvas>标签用于创建画布绘制图形&#xff0c;通过JavaScript进行操作。它为开发者提供一个动态绘制图形的区域&#xff0c;用于创建图标、游戏动画、图像处理等。 对于能够熟练使用Canvas的开发者…...

《TCP/IP网络编程》(第十三章)多种I/O函数(2)

使用readv和writev函数可以提高数据通信的效率&#xff0c;它们的功能可以概括为**“对数据进行整合传输及发送”**。 即使用writev函数可以将分散在多个缓冲中的数据一并发送&#xff0c;使用readv函数可以由多个缓冲分别接受&#xff0c;所以适当使用他们可以减少I/O函数的调…...

Java集合汇总

Java中的集合框架是Java语言的核心部分&#xff0c;提供了强大的数据结构来存储和操作对象集合。集合框架位于java.util包中&#xff0c;主要可以分为两大类&#xff1a;Collection&#xff08;单列集合&#xff09;和Map&#xff08;双列集合&#xff09;。下面是对它们的总结…...

度小满金融大模型的应用创新

XuanYuan/README.md at main Duxiaoman-DI/XuanYuan GitHub...

Android WebView上传文件/自定义弹窗技术,附件的解决方案

安卓内核开发 其实是Android的webview默认是不支持<input type"file"/>文件上传的。现在的前端页面需要处理的是&#xff1a; 权限 文件路径AndroidManifest.xml <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE"/&g…...

selenium 输入框、按钮,输入点击,获取元素属性等简单例子

元素操作 nput框 输入send_keys&#xff0c; input框 清除clear()&#xff0c; 按钮 点击click() 按钮 提交submit() 获取元素 tag_name、 class属性值、 坐标尺寸 """ input框 输入1次&#xff0c;再追加输入一次&#xff0c; 清除&#xff0c; 再重新输入&…...

结构体构造函数

【知识点&#xff1a;结构体构造函数】下面两段代码等价。 &#xff08;1&#xff09;结构体构造函数写法 struct LinkNode {int data;LinkNode* next;LinkNode(int x):data(x),next(NULL) {} }; LinkNode* Lnew LinkNode(123); &#xff08;2&#xff09;非结构体构造函数写…...

基于单片机的电子万年历设计

摘要: 本设计以 AT89C51 单片机为主控器,使用 DS1302 时钟芯片、DS18B20 温度芯片、LCD1602 显示模块,利用Proteus 仿真软件和 Keil 编译软件进行了基于单片机的电子万年历仿真,设计的万年历可以在液晶上显示时间,同时还具有时间校准、温度显示等功能。 关键词 :单片机…...

大厂真实面试题(一)

滴滴大数据sql 取出累计值与1000差值最小的记录 1.题目 已知有表t_cost_detail包含id和money两列,id为自增,请累加计算money值,并求出累加值与1000差值最小的记录。 2.分析 本题主要是想找到累加值域1000差距最小的记录,也就是我们要对上述按照id进行排序并且累加,并…...

Docker搭建ELKF日志分析系统

Docker搭建ELKF日志分析系统 文章目录 Docker搭建ELKF日志分析系统资源列表基础环境一、系统环境准备1.1、创建所需的映射目录1.2、修改系统参数1.3、单击创建elk-kgc网络桥接 二、基于Dockerfile构建Elasticsearch镜像2.1、创建Elasticsearch工作目录2.2、上传资源到指定工作路…...

把系统引导做到U盘,实现插上U盘才能开机

前言 有个小伙伴提出了这样一个问题&#xff1a;能不能把U盘制作成电脑开机的钥匙&#xff1f; 小白稍微思考了一下&#xff0c;便做了这样一个回复&#xff1a;可以。 至于为什么要思考一下&#xff0c;这样会显得我有认真思考他提出的问题。 Windows7或以上系统均支持UEF…...

【计算机网络基础知识】

首先举一个生活化的例子&#xff0c;当你和朋友打电话时&#xff0c;你可能会使用三次握手和四次挥手的过程进行类比&#xff1a; 三次握手&#xff08;Three-Way Handshake&#xff09;&#xff1a; 你打电话给朋友&#xff1a;你首先拨打你朋友的电话号码并等待他接听。这就…...

个股场外期权个人如何参与买卖?

个股场外期权作为一种金融衍生品&#xff0c;为个人投资者提供了多样化的投资选择和风险管理工具。想要参与个股场外期权的买卖&#xff0c;以下是一些关键步骤和考虑因素。 文章来源/&#xff1a;财智财经 第一步&#xff1a;选择合适的金融机构 首先&#xff0c;个人投资者需…...

程序猿大战Python——pycharm软件的使用

基础配置 目标&#xff1a;了解PyCharm软件的基础配置处理。 修改背景颜色&#xff1a; Appearance -> Theme 修改字体大小&#xff1a; 搜索font -> Font 例如&#xff0c;一起完成背景、字体大小的修改。 总结&#xff1a; &#xff08;1&#xff09;如果要对PyChar…...

Unity Standard shader 修改(增加本地坐标裁剪)

本想随便找一个裁剪的shader&#xff0c;可无奈的是没找到一个shader符合要求&#xff0c;美术制作的场景都是用的都标准的着色器他们不在乎你的功能逻辑需求&#xff0c;他们只关心场景的表现&#xff0c;那又找不到和unity标准着色器表现一样的shader 1.通过贴图的透明通道做…...

【数据结构】排序——插入排序,选择排序

前言 本篇博客我们正式开启数据结构中的排序&#xff0c;说到排序&#xff0c;我们能联想到我之前在C语言博客中的冒泡排序&#xff0c;它是排序中的一种&#xff0c;但实现效率太慢&#xff0c;这篇博客我们介绍两种新排序&#xff0c;并好好深入理解排序 &#x1f493; 个人主…...

2024.6.9刷题记录

目录 一、1103. 分糖果 II 1.模拟 2.数学 二、312. 戳气球 1.递归-记忆化搜索 2.区间dp 三、2. 两数相加 1.迭代 2.递归-新建节点 3.递归-原节点 四、4. 寻找两个正序数组的中位数 1.堆 2.双指针二分 五、5. 最长回文子串 1.动态规划 2.中心扩展算法 六、6. Z…...

Matlab|遗传粒子群-混沌粒子群-基本粒子群

目录 1 主要内容 2 部分代码 3 效果图 4 下载链接 1 主要内容 很多同学在发文章时候最犯愁的就是创新点创新点创新点&#xff08;重要的事情说三遍&#xff09;&#xff0c;对于采用智能算法的模型&#xff0c;可以采用算法改进的方式来达到提高整个文章创新水平的目的&…...

31|HTTP3:甩掉TCP、TLS 的包袱,构建高效网络

前面两篇文章我们分析了HTTP/1和HTTP/2&#xff0c;在HTTP/2出现之前&#xff0c;开发者需要采取很多变通的方式来解决HTTP/1所存在的问题&#xff0c;不过HTTP/2在2018年就开始得到了大规模的应用&#xff0c;HTTP/1中存在的一大堆缺陷都得到了解决。 HTTP/2的一个核心特性是…...

2 程序的灵魂—算法-2.2 简单算法举例-【例 2.3】

【例 2.3】判定 2000 — 2500 年中的每一年是否闰年&#xff0c;将结果输出。 润年的条件: 1. 能被 4 整除&#xff0c;但不能被 100 整除的年份&#xff1b; 2. 能被 100 整除&#xff0c;又能被 400 整除的年份&#xff1b; 设 y 为被检测的年份&#xff0c;则算法可表示如下…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践

在 Kubernetes 集群中&#xff0c;如何在保障应用高可用的同时有效地管理资源&#xff0c;一直是运维人员和开发者关注的重点。随着微服务架构的普及&#xff0c;集群内各个服务的负载波动日趋明显&#xff0c;传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...

机器学习的数学基础:线性模型

线性模型 线性模型的基本形式为&#xff1a; f ( x ) ω T x b f\left(\boldsymbol{x}\right)\boldsymbol{\omega}^\text{T}\boldsymbol{x}b f(x)ωTxb 回归问题 利用最小二乘法&#xff0c;得到 ω \boldsymbol{\omega} ω和 b b b的参数估计$ \boldsymbol{\hat{\omega}}…...

node.js的初步学习

那什么是node.js呢&#xff1f; 和JavaScript又是什么关系呢&#xff1f; node.js 提供了 JavaScript的运行环境。当JavaScript作为后端开发语言来说&#xff0c; 需要在node.js的环境上进行当JavaScript作为前端开发语言来说&#xff0c;需要在浏览器的环境上进行 Node.js 可…...

React父子组件通信:Props怎么用?如何从父组件向子组件传递数据?

系列回顾&#xff1a; 在上一篇《React核心概念&#xff1a;State是什么&#xff1f;》中&#xff0c;我们学习了如何使用useState让一个组件拥有自己的内部数据&#xff08;State&#xff09;&#xff0c;并通过一个计数器案例&#xff0c;实现了组件的自我更新。这很棒&#…...