0

0

如何绘制路径-线段

PHP中文网

PHP中文网

发布时间:2017-06-20 14:00:45

|

3263人浏览过

|

来源于php中文网

原创

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

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

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

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

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();
}

我们只使用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();
}

 

改变线段的颜色

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

 

我们还可以利用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();
}

 

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();
}

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

Lenso.ai
Lenso.ai

AI反向图像搜索

下载
cxt.strokeStyle = 'green'= 250, 5050, 150150, 150150, 250  cxt.closePath();
}

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

注意:调用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();
}

从上面的例子我们可以看出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();
}

 

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

 

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

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

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

 

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

 

网格的绘制

既然我们已经明白了如何绘制真正的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);

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

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

 

总结

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

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

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

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

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

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

616

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

194

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

91

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

20

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

54

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

29

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

15

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

598

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

56

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Canvas 绘制时钟
Canvas 绘制时钟

共7课时 | 1.6万人学习

HTML5新特性基础视频教程
HTML5新特性基础视频教程

共18课时 | 3.3万人学习

HTML5 Canvas 动画实战教程
HTML5 Canvas 动画实战教程

共28课时 | 6.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号