关于beginPath()和closePath()的关系>>canvas的beginPath和closePath分析总结,包括多段弧的情况
今天查了一下beginPath()和closePath()关于区域的划分问题,发现到一篇解释得很明白的文章,我就直接转载到这里了。
原文请看:canvas的beginPath和closePath分析总结,包括多段弧的情况,作者是:妙音天女
先看两个例子
> 例1:
<canvas id="myCanvas" width="300" height="300" style="border:1px solid #000000;">
您的浏览器不支持 HTML5 canvas 标签。
</canvas>
<script>
var ctx = document.getElementById("myCanvas").getContext('2d');
ctx.beginPath();
ctx.moveTo(100.5,20.5);
ctx.lineTo(200.5,20.5);
ctx.strokeStyle = 'black';//默认strokeStyle='black', lineWidth=1, 此处可省略
ctx.stroke();
ctx.beginPath();
ctx.moveTo(100.5,40.5);
ctx.lineTo(200.5,40.5)
ctx.strokeStyle = 'red';
ctx.stroke();
</script>
结果:

> 例2:去掉第2个beginPath()
<canvas id="myCanvas" width="300" height="300" style="border:1px solid #000000;">
您的浏览器不支持 HTML5 canvas 标签。
</canvas>
<script>
var ctx = document.getElementById("myCanvas").getContext('2d');
ctx.beginPath();
ctx.moveTo(100.5,20.5);//①
ctx.lineTo(200.5,20.5);//②
ctx.strokeStyle = 'black';//默认strokeStyle='black', lineWidth=1, 此处可省略
ctx.stroke();
ctx.moveTo(100.5,40.5);//③
ctx.lineTo(200.5,40.5)//④
ctx.strokeStyle = 'red';
ctx.stroke();
</script>
结果:

> beginPath
- canvas中的绘制方法(如stroke, fill),都会以“上一次beginPath”之后的所有路径为基础进行绘制。比如例2中stroke了两次,都是以第一次beginPath后的所有路径为基础画的。
- 第一次stroke:画①②,黑色
- 第二次stroke:画①②③④,红色(其中①②红色覆盖之前的黑色)
- 不管你用moveTo把画笔移动到哪里,只要不beginPath,那你一直都是在画一条路径(注:此处『一条路径』并非指连在一起)
- fillRect与strokeRect这种直接画出独立区域的函数,也不会打断当前的path.
> beginPath
- closePath的意思不是结束路径,而是关闭路径,它会试图从当前路径的终点连一条路径到起点,让整个路径闭合起来。但是,这并不意味着它之后的路径就是新路径了
- 与beginPath几乎没有关系:不要企图通过闭合现有路径来开始一条新路径,而开始一条新路径,以前的路径也不会闭合。
对于绘制多段弧,看下面几个例子:
> 例3:
var context = document.getElementById("myCanvas").getContext('2d');
context.strokeStyle="#005588";
for (var i = 0; i < 10; i ++){
context.beginPath();
context.arc(50 + i*100,60,40,0,2*Math.PI*(i+1)/10);
context.closePath();
context.stroke();
}
结果:

> 例4:在例3的基础上只去掉closePath()
var context = document.getElementById("myCanvas").getContext('2d');
context.strokeStyle="#005588";
for (var i = 0; i < 10; i ++){
context.beginPath();
context.arc(50 + i*100,60,40,0,2*Math.PI*(i+1)/10);
//context.closePath();
context.stroke();
}
结果:

> 例5:在例3的基础上去掉beginPath()和closePath()
var context = document.getElementById("myCanvas").getContext('2d');
context.strokeStyle="#005588";
for (var i = 0; i < 10; i ++){
//context.beginPath();
context.arc(50 + i*100,60,40,0,2*Math.PI*(i+1)/10);
//context.closePath();
context.stroke();
}
结果:

可见,在这种情况下,每个弧画完都会连到下一个弧的起点
> 例6:在例3的基础上只去掉beginPath()
var context = document.getElementById("myCanvas").getContext('2d');
context.strokeStyle="#005588";
for (var i = 0; i < 10; i ++){
//context.beginPath();
context.arc(50 + i*100,60,40,0,2*Math.PI*(i+1)/10);
context.closePath();
context.stroke();
}
结果:
这样看不太清晰,我们将i < 10改为i < 3,只显示前三个:

可见,在这种情况下,每个弧画完都会先回到第一个弧的起点,然后再连到下一个弧的起点
> 例7:在例3的基础上将stroke()改为fill()
var context = document.getElementById("myCanvas").getContext('2d');
context.fillStyle="#005588";
for (var i = 0; i < 10; i ++){
context.beginPath();
context.arc(50 + i*100,60,40,0,2*Math.PI*(i+1)/10);
//context.closePath();
context.fill();
}
结果:

> 例8:在例7的基础上去掉closePath()
var context = document.getElementById("myCanvas").getContext('2d');
context.fillStyle="#005588";
for (var i = 0; i < 10; i ++){
context.beginPath();
context.arc(50 + i*100,60,40,0,2*Math.PI*(i+1)/10);
context.closePath();
context.fill();
}
结果:

> 比较例7和例8可知:
无论是否closePath(),结果都一样。
因为closePath()对于fill()是没有用的:无论是否closePath(),调用fill()时,canvas会自动把没有封闭的路径首尾相连,之后进行填充。
关于beginPath()和closePath()的关系>>canvas的beginPath和closePath分析总结,包括多段弧的情况的更多相关文章
- canvas的beginPath和closePath分析总结,包括多段弧的情况
参考博文: Html5 canvas画图教程17:论beginPath的重要性 先看两个例子 例1: <canvas id="myCanvas" width="30 ...
- HTML5 CANVAS画图 beginPath和closePath
beginPath这个canvas函数我很早就讲过了,他的作用很简单,就是开始一段新路径,我们先来看下面的一小段代码: var ctx = document.getElementById('cvs') ...
- canvas的beginPath和closePath
https://www.cnblogs.com/xuehaoyue/p/6549682.html https://segmentfault.com/a/1190000010330319 https:/ ...
- 基于canvas的陈列订货的分析
订货会软件中又新增了进行陈列订货,即一杆衣服订的显示出来,没订的不显示出来 主要遇到的问题是如何呈现,原先老是想着定位,left,top但是花出来的图容易出现原先的数据填写错误导致后期的图片的呈现出现 ...
- UI基础:UI中类的继承关系图,最基本的视图分析
首先,UI中常用的UIwindow.UILabel.UIButton.UITextField属于UIView的子类.UITextField和UILabel和UIwindow自身没有初始化方法,需要使用 ...
- AJAX请求真的不安全么?谈谈Web安全与AJAX的关系。
开篇三问 AJAX请求真的不安全么? AJAX请求哪里不安全? 怎么样让AJAX请求更安全? 前言 本文包含的内容较多,包括AJAX,CORS,XSS,CSRF等内容,要完整的看完并理解需要付出一定的 ...
- 在矩池云使用Disco Diffusion生成AI艺术图
在 Disco Diffusion 官方说明的第一段,其对自身是这样定义: AI Image generating technique called CLIP-Guided Diffusion.DD ...
- 基于canvas实现物理运动效果与动画效果(一)
一.为什么要写这篇文章 某年某月某时某种原因,我在慕课网上看到了一个大神实现了关于小球的抛物线运动的代码,心中很是欣喜,故而写这篇文章来向这位大神致敬,同时也为了弥补自己在运动效果和动画效果制作方面的 ...
- html5 canvas时钟
基础知识点: canvas标签只是图形容器,您必须使用脚本来绘制图形. getContext() 方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性.——获取上 ...
随机推荐
- iOS --UIScrollView的学习(二)
1.接着上一次的说:http://www.cnblogs.com/fengzhihao/p/5287734.html,这次讲一下UISCrollView的缩放功能. 2.当用户在UIScrollVie ...
- iOS9下UICollectionViewCell的awakeFromNib问题
最近项目测试出一个隐藏已久的bug,经过多番测试,发现在iOS9下自定义的一个UICollectionViewCell只走一次awakeFromNib. 具体情况是,项目中有一个控制器用到了自定义的U ...
- 集合之六:Map接口
Map接口概述 Map接口中的集合和Collection接口中的集合在存储数据的格式上有很大的不同,Map接口下的内容是以<K , V> ,键值对的形式存储的,我们查询API,Map接口的 ...
- C++类的构造函数及定义
定义一个普通的类时,一定要定义它自己的构造函数.原因有三:第一个原因是编译器只有在发现类不包含任何构造函数的情况下才会替我们生成一个默认的构造函数,一旦我们定义了一些其他的构造函数,那么除非我们再定义 ...
- ZJOI2019 day2 游记
应该是打的最没有信仰的一次比赛了 然后这个垃圾水平居然还拿了170,真是有毒 我的语文并不好所以还是写流水账吧 day-2 到了余姚,发现附近并没有什么好吃的,于是直接去kfc了 另外潮湿的空气对呼吸 ...
- SPOJ Lexicographical Substring Search 求字典序第k大子串 后缀自动机
题目传送门 思路:按字典序,小的字符优先选取.对于一个字符,如果以这个字符开头的子串大于等于k个,那说明这个字符是应该选的,并且选完之后,可能还要继续选.如果以这个字符开头的子串小于k个,说明这个字符 ...
- dotnet core webapi +vue 搭建前后端完全分离web架构(一)
架构 服务端采用 dotnet core webapi 前端采用: Vue + router +elementUI+axios 问题 使用前后端完全分离的架构,首先遇到的问题肯定是跨域访问.前后端可 ...
- sql中COUNT(*)、COUNT(字段名)的区别
数据表:其中IT002的Fname是null. 执行sql: ) FROM T_Employee 结果: 结论:COUNT(*)统计的是结果集的总条数,而COUNT(FName)统计的则是除了结果集中 ...
- redis持久化之 aof日志
aof就是把执行的命令写到文本文件里面 aof使用过程 第一步: 修改配置文件,并启动server 第二步, 当前目录下面会生成一个 appendonly.aof文件,但是是空的 去客户端 开始操作后 ...
- media(适配)
媒体类型 1.all 所有媒体 2.braille 盲文触觉设备 3.embossed 盲文打印机 4.print 手持设备 5.projection 打印预览 ...