今天查了一下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分析总结,包括多段弧的情况的更多相关文章

  1. canvas的beginPath和closePath分析总结,包括多段弧的情况

    参考博文: Html5 canvas画图教程17:论beginPath的重要性 先看两个例子 例1: <canvas id="myCanvas" width="30 ...

  2. HTML5 CANVAS画图 beginPath和closePath

    beginPath这个canvas函数我很早就讲过了,他的作用很简单,就是开始一段新路径,我们先来看下面的一小段代码: var ctx = document.getElementById('cvs') ...

  3. canvas的beginPath和closePath

    https://www.cnblogs.com/xuehaoyue/p/6549682.html https://segmentfault.com/a/1190000010330319 https:/ ...

  4. 基于canvas的陈列订货的分析

    订货会软件中又新增了进行陈列订货,即一杆衣服订的显示出来,没订的不显示出来 主要遇到的问题是如何呈现,原先老是想着定位,left,top但是花出来的图容易出现原先的数据填写错误导致后期的图片的呈现出现 ...

  5. UI基础:UI中类的继承关系图,最基本的视图分析

    首先,UI中常用的UIwindow.UILabel.UIButton.UITextField属于UIView的子类.UITextField和UILabel和UIwindow自身没有初始化方法,需要使用 ...

  6. AJAX请求真的不安全么?谈谈Web安全与AJAX的关系。

    开篇三问 AJAX请求真的不安全么? AJAX请求哪里不安全? 怎么样让AJAX请求更安全? 前言 本文包含的内容较多,包括AJAX,CORS,XSS,CSRF等内容,要完整的看完并理解需要付出一定的 ...

  7. 在矩池云使用Disco Diffusion生成AI艺术图

    在 Disco Diffusion 官方说明的第一段,其对自身是这样定义: AI Image generating technique called CLIP-Guided Diffusion.DD ...

  8. 基于canvas实现物理运动效果与动画效果(一)

    一.为什么要写这篇文章 某年某月某时某种原因,我在慕课网上看到了一个大神实现了关于小球的抛物线运动的代码,心中很是欣喜,故而写这篇文章来向这位大神致敬,同时也为了弥补自己在运动效果和动画效果制作方面的 ...

  9. html5 canvas时钟

    基础知识点:                canvas标签只是图形容器,您必须使用脚本来绘制图形. getContext() 方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性.——获取上 ...

随机推荐

  1. leetcode-49-字母异位词分组(神奇的哈希)

    题目描述: 给定一个字符串数组,将字母异位词组合在一起.字母异位词指字母相同,但排列不同的字符串. 示例: 输入: ["eat", "tea", "t ...

  2. JVM调优总结 -Xms -Xmx -Xmn -Xss(转自:iteye unixboy)

    堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系统的可用虚拟内存限制:系统的可用物理内存限制.32位系统下,一般限制在1.5G~2G:64为操作 ...

  3. 安装vuecli和使用elememtUi

    首先需要下载node.js,这里只需要一步步的安装就可以,无需要做其他的事, 第二步:安装vue 第三步:安装脚手架 第四步: 由于国内访问npm比较慢,可以按照cnpm npm install -g ...

  4. 常见 CentOS 7 安装问题

    问题一: 解决办法:网上安装文章推荐的的刻录工具多是 ultraiso,有时候可能会出现错误,这时候最简单的解决办法是换由RedHat推荐的刻录工具,fedora media writer,不过这个工 ...

  5. SVN解决冲突的方法

    SVN管理代码工具在群组合作开发的过程中,若多人同时修改一个文件,就会出现冲突的情况. 冲突演示: 有A.B两个用户,他们各自从svn服务器中检出了file.txt文件,此时A.B.服务器三个地方的f ...

  6. (转)LVS安装使用详解

    原文:https://www.cnblogs.com/MacoLee/p/5856858.html 简介 LVS是Linux Virtual Server的简称,也就是Linux虚拟服务器, 是一个由 ...

  7. hibernate3.3.2搭建log4j日志环境

    日志的框架有很多,hibernate3.3.2用的是slf4j,slf4j简单理解为一个接口,标准.具体的实现可以是不同的实现(如slf4j自己的实现,log4j等).slf就像JDBC,JPA.自己 ...

  8. Tomcat8-启动脚本分析

    1. Tomcat也是一个java程序 最终的入口启动文件:org.apache.catalina.startup.Bootstrap 最后一条命令: start "Tomcat" ...

  9. js中字符串的替换

    定义和用法 replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串. 语法 stringObject.replace(regexp/substr,replac ...

  10. docker上安装nginx服务

    环境     1.开启一个容器,安装nginx,略过   2.假如第一步新启动没映射端口的话,重新把容器保存为镜像然后再重新运行一个新容器,不建议在一个正在运行的容器上做端口映射 docker run ...