当前位置: 首页 > 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;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...