学习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: Canvas是前端一个很重要的知识点,<canvas>标签用于创建画布绘制图形,通过JavaScript进行操作。它为开发者提供一个动态绘制图形的区域,用于创建图标、游戏动画、图像处理等。 对于能够熟练使用Canvas的开发者…...

《TCP/IP网络编程》(第十三章)多种I/O函数(2)
使用readv和writev函数可以提高数据通信的效率,它们的功能可以概括为**“对数据进行整合传输及发送”**。 即使用writev函数可以将分散在多个缓冲中的数据一并发送,使用readv函数可以由多个缓冲分别接受,所以适当使用他们可以减少I/O函数的调…...

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

度小满金融大模型的应用创新
XuanYuan/README.md at main Duxiaoman-DI/XuanYuan GitHub...

Android WebView上传文件/自定义弹窗技术,附件的解决方案
安卓内核开发 其实是Android的webview默认是不支持<input type"file"/>文件上传的。现在的前端页面需要处理的是: 权限 文件路径AndroidManifest.xml <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE"/&g…...
selenium 输入框、按钮,输入点击,获取元素属性等简单例子
元素操作 nput框 输入send_keys, input框 清除clear(), 按钮 点击click() 按钮 提交submit() 获取元素 tag_name、 class属性值、 坐标尺寸 """ input框 输入1次,再追加输入一次, 清除, 再重新输入&…...
结构体构造函数
【知识点:结构体构造函数】下面两段代码等价。 (1)结构体构造函数写法 struct LinkNode {int data;LinkNode* next;LinkNode(int x):data(x),next(NULL) {} }; LinkNode* Lnew LinkNode(123); (2)非结构体构造函数写…...
基于单片机的电子万年历设计
摘要: 本设计以 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盘才能开机
前言 有个小伙伴提出了这样一个问题:能不能把U盘制作成电脑开机的钥匙? 小白稍微思考了一下,便做了这样一个回复:可以。 至于为什么要思考一下,这样会显得我有认真思考他提出的问题。 Windows7或以上系统均支持UEF…...

【计算机网络基础知识】
首先举一个生活化的例子,当你和朋友打电话时,你可能会使用三次握手和四次挥手的过程进行类比: 三次握手(Three-Way Handshake): 你打电话给朋友:你首先拨打你朋友的电话号码并等待他接听。这就…...

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

程序猿大战Python——pycharm软件的使用
基础配置 目标:了解PyCharm软件的基础配置处理。 修改背景颜色: Appearance -> Theme 修改字体大小: 搜索font -> Font 例如,一起完成背景、字体大小的修改。 总结: (1)如果要对PyChar…...

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

【数据结构】排序——插入排序,选择排序
前言 本篇博客我们正式开启数据结构中的排序,说到排序,我们能联想到我之前在C语言博客中的冒泡排序,它是排序中的一种,但实现效率太慢,这篇博客我们介绍两种新排序,并好好深入理解排序 💓 个人主…...
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 主要内容 很多同学在发文章时候最犯愁的就是创新点创新点创新点(重要的事情说三遍),对于采用智能算法的模型,可以采用算法改进的方式来达到提高整个文章创新水平的目的&…...

31|HTTP3:甩掉TCP、TLS 的包袱,构建高效网络
前面两篇文章我们分析了HTTP/1和HTTP/2,在HTTP/2出现之前,开发者需要采取很多变通的方式来解决HTTP/1所存在的问题,不过HTTP/2在2018年就开始得到了大规模的应用,HTTP/1中存在的一大堆缺陷都得到了解决。 HTTP/2的一个核心特性是…...

2 程序的灵魂—算法-2.2 简单算法举例-【例 2.3】
【例 2.3】判定 2000 — 2500 年中的每一年是否闰年,将结果输出。 润年的条件: 1. 能被 4 整除,但不能被 100 整除的年份; 2. 能被 100 整除,又能被 400 整除的年份; 设 y 为被检测的年份,则算法可表示如下…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...

【iOS】 Block再学习
iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...