canvas学习总结三之绘制路径-线段


Posted in HTML / CSS onJanuary 31, 2019

Canvas绘图环境中有些属于立即绘制图形方法,有些绘图方法是基于路径的。

立即绘制图形方法仅有两个strokeRect(),fillRect(),虽然strokezText(),fillText()方法也是立即绘制的,但是文本不算是图形。

基于路径的绘制系统 

大多数绘制系统,如:SVG(Scalable Verctor Graphics, 可缩放的矢量图形),Adobe Illustrator等,都是基于路径的,

使用这些绘制系统时,你需要先定义一个路径,然后再对其进行描边或填充,也可以描边加填充这样图形才能显示出来。

Canvas中的三种绘制方式:

canvas学习总结三之绘制路径-线段

绘制一条线段

Canvas绘图环境中,线段也是基于路径绘制的,称为线性路径,创建线性路径的方法:moveTO()与lineTo(),在创建路径之后调用stroke()方法,才能在Canvas中画出线段出来。

这就是前面我们所说的基于路径的绘制方法,必须对其进行描边或者填充;

通常两点连一线因此绘制线段非常简单,通过moveTO()指定线的起点,通过lineTo()移动到另一个点。

function drawLine(){
    cxt.moveTo(50, 50);
    cxt.lineTo(100, 100);
}

然而这样我们在画布中是看不见线段的,前面我们说到基于路径的绘制方法,必须要描边或者填充。所以要想看到结果,我们必须还要使用stroke()方法。

因此我们把方法修改成下面这样就会绘制出一条线段

function drawLine(){
    cxt.moveTo(50, 50);
    cxt.lineTo(200, 200);
    cxt.stroke();
}

canvas学习总结三之绘制路径-线段

我们只使用lineTo()也是能在画布中绘制出线段的,我们把上面的代码改成如下面所示,效果也是一样的

function drawLine(){
    cxt.lineTo(50, 50);
    cxt.lineTo(200, 200);
    cxt.stroke();
}

总结下moveTo()与lineTo()的用法

  • moveTo(x,y): 将笔触移动到指定的坐标x以及y上,向当前路径中增加一条子路径,该方法不会清除当前路径中的任何子路径。
  • lineTo(x,y): 绘制一条从当前位置到指定x以及y位置的直线,如果当前路径中没有子路径,那么这个方法的行为与moveTo()一样。如果当前路径中存在子路径,此方法会将你所指定的这个点加入子路径中。

改变线段的样式

改变线段的宽度

function= 14;
    cxt.lineTo(50, 50);
    cxt.lineTo(200, 200);
    cxt.stroke();
}

canvas学习总结三之绘制路径-线段

改变线段的颜色

function drawLine(){
    cxt.lineWidth = 14;
    cxt.strokeStyle = 'green';
    cxt.lineTo(50, 50);
    cxt.lineTo(200, 200);
    cxt.stroke();
}

canvas学习总结三之绘制路径-线段 

我们还可以利用CanvasGradient对象或者CanvasPattern对象给线段添加渐变色或图案

function drawLine(){
    cxt.lineWidth = 14;
    var gradient = cxt.createLinearGradient(0, 0, canvas.width/2, canvas.height/2);
    gradient.addColorStop(0, 'blue');
    gradient.addColorStop(0.5, 'purple');
    gradient.addColorStop(1, 'yellow');
    cxt.strokeStyle = gradient;
    cxt.lineTo(50, 50);
    cxt.lineTo(200, 200);
    cxt.stroke();
}

canvas学习总结三之绘制路径-线段

 beginPath()与closePath()

从上面canvas中的三种绘制方式中我们可以看出,第二行的弧形路径是开放路径,最后一行的弧形是封闭路径。那么封闭的路径是怎么实现的呢?

下面我们来看看canvas中路径绘制中两个比较重要的方法

  • beginPath(): 清除当前所有子路径,以此来重置当前路径,重新规划一条路径。
  • closePath(): 用于封闭某段开放路径。不是必需的,如果图形是已经闭合了的,即当前点为开始点,该函数什么也不做。

先绘制出一条折线

function drawLine(){
    cxt.strokeStyle = 'green';
    cxt.lineWidth = 2;
    cxt.moveTo(50, 50);
    cxt.lineTo(50, 150);
    cxt.lineTo(150, 150);
    cxt.stroke();
}

canvas学习总结三之绘制路径-线段

修改上面例子中的代码在代码中添加beginPath()与closePath()方法

function drawLine(){
    //描边三角形
    cxt.strokeStyle = 'green';
    cxt.lineWidth = 2;
    cxt.beginPath();
    cxt.moveTo(50, 50);
    cxt.lineTo(50, 150);
    cxt.stroke();
    cxt.beginPath();
    cxt.lineTo(150, 150);
    cxt.lineTo(150, 250);
    cxt.stroke();
cxt.closePath();
}

canvas学习总结三之绘制路径-线段

可以看出我们在画布中绘制了两条路径

注意:调用beginPath()之后,或者canvas刚建的时候,第一条路径构造命令通常被视为是moveTo()。所以我们在绘制图形的时候一定要先使用beginPath()。

我们继续修改我们的代码

function drawLine(){
    //描边三角形
    cxt.strokeStyle = 'green';
    cxt.lineWidth = 2;
    cxt.beginPath();
    cxt.moveTo(50, 50);
    cxt.lineTo(50, 150);
    cxt.lineTo(150, 150);
    cxt.closePath();
    cxt.stroke();
    //折线
    cxt.translate(150, 0);
    cxt.strokeStyle = 'red';
    cxt.lineWidth = 2;
    cxt.beginPath();
    cxt.moveTo(50, 50);
    cxt.lineTo(50, 150);
    cxt.lineTo(150, 150);
    cxt.stroke();
    cxt.closePath();
    //绿色填充三角形
    cxt.translate(150, 0);
    cxt.fillStyle = 'green';
    cxt.lineWidth = 2;
    cxt.beginPath();
    cxt.moveTo(50, 50);
    cxt.lineTo(50, 150);
    cxt.lineTo(150, 150);
    cxt.fill();
    cxt.closePath();
    //红色填充三角形
    cxt.translate(150, 0);
    cxt.fillStyle = 'red';
    cxt.lineWidth = 2;
    cxt.beginPath();
    cxt.moveTo(50, 50);
    cxt.lineTo(50, 150);
    cxt.lineTo(150, 150);
    cxt.closePath();
    cxt.fill();
}

canvas学习总结三之绘制路径-线段

从上面的例子我们可以看出closePath()的位置不同,也会影响我们的图形

注意:当你调用fill()函数时,所有没有闭合的形状都会自动闭合,所以此时closePath()函数不是必须的。

但是调用stroke():如果你在stroke()方法之前只用closePath()会形成闭合路径,如果在stroke()方法之后调用closePath()方法,此时图形已经绘制完成,当前的绘制路径已经关闭,所以closePath()方法不起作用。

线段与像素边界

先来看一个例子

function drawLine(){
    //描边三角形
    cxt.lineWidth = 1;
    cxt.beginPath();
    cxt.moveTo(50, 50);
    cxt.lineTo(450, 50);
    cxt.stroke();
    cxt.beginPath();
    cxt.moveTo(50.5, 150.5);
    cxt.lineTo(450.5, 150.5);
    cxt.stroke();
}

canvas学习总结三之绘制路径-线段

从图中我们可以看出,我们将两条线段的lineWidth都是设置为1像素,但是上面的线段画出的却是两像素。 

如果你在某2个像素的边界处绘制一条1像素宽的线段,那么该线段实际会占据2个像素的宽度;

因为当你在像素边界处绘制一条1像素宽度的垂直线段时,canvas的绘图环境对象会试着将半个像素画在边界中线的右边,将另外半个像素画在边界中线的左边。

然而,在一个整像素的范围内绘制半个像素宽的线段是不可能的,所以在左右两个方向上的半个像素都被扩展为1个像素。

另外一方面,绘制在两个像素之间,这样的话,中线左右两端的那半个像素就不会延伸,它们结合起来恰好占据1个像素的宽度。所以说,如果要绘制一条真正1像素宽度的线段,你必须将该线段绘制在某两个像素之间

canvas学习总结三之绘制路径-线段

网格的绘制

既然我们已经明白了如何绘制真正的1像素的线段,那我们就开始绘制网格

function drawLine(stepx, stepy){
    cxt.lineWidth = 0.5;
    cxt.strokeStyle = 'green';
    //绘制竖线
    for(var i= stepx + 0.5; i< cxt.canvas.width; i+= stepx){
        cxt.beginPath();
        cxt.moveTo(i, 0);
        cxt.lineTo(i, cxt.canvas.height);
        cxt.stroke();
    }
    //绘制横线
    for(var i= stepy + 0.5; i< cxt.canvas.height; i+= stepy){
        cxt.beginPath();
        cxt.moveTo(0, i);
        cxt.lineTo(cxt.canvas.width, i);
        cxt.stroke();
    }
}
drawLine(10, 10);

canvas学习总结三之绘制路径-线段

上面例子中我们将线段绘制在两个像素之间的像素上,而且绘制出来的线段仅有0.5像素宽,

虽说canvas规范没有明文规定,不过所有浏览器的Canvas实现都使用了“抗锯齿”技术,以便创建出“亚像素”线段的绘制效果来

总结

本节内容主要讲解canvas中路径中线性路径的绘制方法,主要是利用 moveTo()定义起点,lineTo()定义终点,stroke()描绘当前路径。这三个方法绘制线段

canvas中绘制路径有两个重要的方法,beginPath()与closePath()。绘制图形之前先调用beginPath()是绘制多个图形必要的步骤。

closePath()在使用fill()时是可以省略的,而且还要注意closePath()方法的调用位置。

绘制线段时我们可以使用 lineWidth改变线段的宽度,strokeStyle改变线段的颜色。

弄清楚线段的像素边界,这样我们才能绘制出真正的1像素线宽的线段。

对canvas绘制图形感兴趣的同学,请持续关注后续更新,如有不对的地方也请指出并多多交流。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

HTML / CSS 相关文章推荐
使用CSS实现阅读进度条
Feb 27 HTML / CSS
纯CSS实现右侧底部悬浮效果(悬浮QQ、微信、微博、邮箱等联系方式)
Apr 24 HTML / CSS
详解HTML5通讯录获取指定多个人的信息
Dec 20 HTML / CSS
html5自带表单验证体验优化及提示气泡修改功能
Sep 12 HTML / CSS
html5 input元素新特性_动力节点Java学院整理
Jul 06 HTML / CSS
HTML5实现QQ聊天气泡效果
Jun 26 HTML / CSS
谈一谈HTML5本地存储技术
Mar 02 HTML / CSS
HTML5 Canvas 旋转风车绘制
Aug 18 HTML / CSS
canvas 橡皮筋式线条绘图应用方法
Feb 13 HTML / CSS
Canvas环形饼图与手势控制的实现代码
Nov 08 HTML / CSS
Canvas实现放大镜效果完整案例分析(附代码)
Nov 26 HTML / CSS
POST提交数据常见的四种方式
Jan 18 HTML / CSS
移动端Html5中百度地图的点击事件
Jan 31 #HTML / CSS
Html5页面内使用JSON动画的实现
Jan 29 #HTML / CSS
HTML5拍照和摄像机功能实战详解
Jan 24 #HTML / CSS
解锁canvas导出图片跨域的N种姿势小结
Jan 24 #HTML / CSS
详解canvas绘制多张图的排列顺序问题
Jan 21 #HTML / CSS
canvas因为图片资源不在同一域名下而导致的跨域污染画布的解决办法
Jan 18 #HTML / CSS
canvas绘制圆角头像的实现方法
Jan 17 #HTML / CSS
You might like
为什么夜间收到的中波电台比白天多
2021/03/01 无线电
php更改目录及子目录下所有的文件后缀的代码
2010/09/24 PHP
php 代码优化之经典示例
2011/03/24 PHP
PHP实现动态压缩js与css文件的方法
2018/05/02 PHP
基于thinkphp5框架实现微信小程序支付 退款 订单查询 退款查询操作
2020/08/17 PHP
javascript 写的一个简单的timer
2009/07/30 Javascript
jquery1.10给新增元素绑定事件的方法
2014/03/06 Javascript
javascript屏蔽右键代码
2014/05/15 Javascript
javascript 实现map集合
2015/04/03 Javascript
js控制文本框只能输入中文、英文、数字与指定特殊符号的实现代码
2016/09/09 Javascript
手机端实现Bootstrap简单图片轮播效果
2016/10/13 Javascript
微信小程序 连续旋转动画(this.animation.rotate)详解
2017/04/07 Javascript
jQuery ajax请求struts action实现异步刷新
2017/04/19 jQuery
在原生不支持的旧环境中添加兼容的Object.keys实现方法
2017/09/11 Javascript
基于cropper.js封装vue实现在线图片裁剪组件功能
2018/03/01 Javascript
Vue.js实现可配置的登录表单代码详解
2018/03/29 Javascript
Layui数据表格 前后端json数据接收的方法
2019/09/19 Javascript
微信小程序返回上一级页面的实现代码
2020/06/19 Javascript
js通过canvas生成图片缩略图
2020/10/02 Javascript
Django发送html邮件的方法
2015/05/26 Python
Scrapy-redis爬虫分布式爬取的分析和实现
2017/02/07 Python
Python字符串逆序输出的实例讲解
2019/02/16 Python
浅析pip安装第三方库及pycharm中导入第三方库的问题
2020/03/10 Python
基于python实现FTP文件上传与下载操作(ftp&amp;sftp协议)
2020/04/01 Python
matplotlib设置颜色、标记、线条,让你的图像更加丰富(推荐)
2020/09/25 Python
教你如何用python操作摄像头以及对视频流的处理
2020/10/12 Python
Python Selenium XPath根据文本内容查找元素的方法
2020/12/07 Python
Jacadi Paris美国官方网站:法国童装品牌
2017/10/15 全球购物
JD Sports马来西亚:英国领先的运动鞋和运动服饰零售商
2018/03/13 全球购物
亚洲最大的眼镜批发商和零售商之一:Glasseslit
2018/10/08 全球购物
如何写出高质量、高性能的MySQL查询
2014/11/17 面试题
学雷锋活动总结范文
2014/04/25 职场文书
学习普通话的体会
2014/11/07 职场文书
参观邀请函范文
2015/02/02 职场文书
清明节文明祭祀倡议书
2015/04/28 职场文书
2015年秋季运动会加油稿
2015/07/22 职场文书