在canvas中,我们经常需要绘制线段,主要使用moveTo和lineTo两个方法,moveTo移动至线段起始点,lineTo将线段绘制至终点。同时,绘制线段时可以指定线段的宽度,使用lineWidth属性,lineWidth默认为1,必须大于0

moveTo(x, y): 移动至坐标x,y

lineTo(x, y): 线段终点坐标x,y

简单绘制代码如下:

var context = document.getElementById('canvas').getContext('2d');
context.lineWidth = 2; //设置线宽
context.beginPath(); //开始绘制路径
context.moveTo(0, 50); //移动至起始点
context.lineTo(50, 50); //移动至终点
context.stroke(); //绘制

Done, 绘制出了一条线宽为2的线段,就这么简单

那我们再绘制一条线宽为1的线段

context.lineWidth = 1;
context.beginPath();
context.moveTo(50, 50);
context.lineTo(100, 50);
context.stroke();

我勒个去,怎么跟线宽2的宽度是一样的,宽度也是2,只是颜色稍浅。

那我们换个思路,刚才绘制的Y轴左边为50,我们改成50.5呢,分别再绘制两条线宽分别是2和1的线段

context.lineWidth = 2;
context.beginPath();
context.moveTo(0, 70.5);
context.lineTo(50, 70.5);
context.stroke(); context.lineWidth = 1;
context.beginPath();
context.moveTo(0, 80.5);
context.lineTo(50, 80.5);
context.stroke();

从上至下分别称为线段1,2,3,4

显然,线段3比1,2都要宽,实际为3px,线段4实际为1px

线段1:绘制线宽2, 实际宽度2

线段2:绘制宽度1, 实际宽度2

线段3:绘制宽度2, 实际宽度3

线段4:绘制宽度1: 实际宽度1

只有1和4才是我们想要的结果

为什么呢?

其实,这跟canvas的绘制逻辑有关,当我们试图绘制一个线段时,canvas会读取lineWidth,,然后尝试将在坐标处两边各绘制一半的lineWidth,比如我们下图:

我们在坐标3处画一条宽为1的横线,canvas会以3为中轴线,在两边各画0.5像素,深蓝色就是我们期望的效果(2.5-3.5,1个像素),但实际上,浅蓝色也会被绘制出来,因为canvas无法在整个像素宽内只绘制半个像素,所以坐标轴上下两个方向都都会被扩展至整个像素宽度内(2-4,两个像素),但是扩展的像素实际的值并不是原值相同,而是取其一半,所以最直接的视觉感受是:线条比预想的变宽了,但是颜色浅了很多。

还是以宽为1的横线为例,我们如果将其绘制在纵坐标2.5处呢,即以半像素作为中轴线

同样浏览器进行绘制时,在2.5上下各绘制0.5的像素宽度,但与上面的例子不同的是,图像边界正好落在整数像素边界内,合起来正好为1个像素,这个时候,就不需要向两边扩展,而是我们预期的(2-3)的1个像素宽度。

同理,我们分别使用两种方式绘制宽度为2的线段时,效果恰恰相反,在坐标3处绘制的时候,像素正好扩展至2-4,即2个像素,符合我们的预期;而在坐标2.5处绘制时,像素扩展至1.5-3.5,未到边界,需要补足,就变成了1-4,即3个像素。

建议

在实际应用中,如果想得到更好的体验,精确的像素值,如果线段的宽度是奇数像素,绘制时以n.5,即半数像素作为中轴线,如果线段的宽度为偶数像素,绘制时以n.0,即整数像素作为中轴线

canvas总结:线段宽度与像素边界的更多相关文章

  1. Canvas入门06-线段与像素边界

    我们知道,使用以下2个API可以绘制一条线段: moveTo(x, y) 向当前路径中增加一条子路径,该子路径只包含一个点,此为线段的起始点 lineTo(x, y) 将线段的下一个点加入子路径中 c ...

  2. 理解Canvas像素边界

    大家看下面的例子 var context = document.getElementById('canvas').getContext('2d'); context.lineWidth = 1; co ...

  3. JavaScript 基于HTML5 canvas 获取文本占用的像素宽度

    基于HTML5 canvas 获取文本占用的像素宽度   by:授客 QQ:1033553122 直接上代码   // 获取单行文本的像素宽度 getTextPixelWith(text, fontS ...

  4. pcl-设置多线段宽度和颜色

    显示点云有使用vtk的,有使用 ros 中riz ?库的,使用pcl显示点云数据比较方便,但是对于一些模型形状只能固定特定的效果,比如说直线段,只能绘制点到点两点之间的线段.但是项目需要绘制点1到点2 ...

  5. canvas 制作flappy bird(像素小鸟)全流程

    flappy bird制作全流程: 一.前言 像素小鸟这个简单的游戏于2014年在网络上爆红,游戏上线一段时间内appleStore上的下载量一度达到5000万次,风靡一时, 近年来移动web的普及为 ...

  6. HTML5 canvas图像绘制方法与像素操作属性和方法

    图像绘制方法 drawImage()        向画布上绘制图像.画布或视频 像素操作属性和方法 width                                返回 ImageData ...

  7. HTML5 Canvas中实现绘制一个像素宽的细线

    正统的HTML5 Canvas中如下代码 ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(10, 100); ctx.lineTo(300,100); c ...

  8. 【canvas学习笔记八】像素操作

    ImageData对象 ImageData对象包含了一个区域内的canvas的像素信息.它包含以下可读属性: width canvas的宽度,单位是像素. height canvas的高度,单位是像素 ...

  9. canvas 计算文字宽度(常用于文字换行)

    var c=document.getElementById("myCanvas"); var ctx=c.getContext("2d"); ctx.font= ...

随机推荐

  1. commands - `tar`

    remove files after pack: tar --remove-files -cf all.tar * compression: -j: bzip2 -z: gzip add file t ...

  2. onclick用法 超链接简单弹出窗口实例

    问题 需要异步处理不同状态 1. onclick用法 if判断弹出窗口 解题思路 1. onclick用法 if判断弹出窗口 注意.. <a href="javascript:void ...

  3. 一个简化的printf函数

    <C和指针>第7章第5道编程题: 实现一个简化的printf函数,它能够处理%d.%f.%s 和 %c 格式码,根据ANSI标准的原则,其他格式码的行为是未定义的.你可以假定已经存在函数 ...

  4. WPF GroupBox 样式分享

    原文:WPF GroupBox 样式分享 默认样式 GroupBox 样式分享" title="WPF GroupBox 样式分享"> 添加样式后 GroupBox ...

  5. 在PHP中处理表单之—Checkbox

    原文翻译自:http://www.html-form-guide.com/php-form/php-form-checkbox.html 单个checkbox  形如: <form action ...

  6. Silence.js高效开发移动Web前端类库

    基于Zepto的轻量级移动Web前端JavaScript类库. 编写这个类库原因及目的: 采用MVC设计模式,使代码工程化结构化. 使用RouterJS,提升前端交互性能,延长页面使用时间,并通过Aj ...

  7. 《Java解惑》书摘

    例子1:关于char数组的输出 System.out.println("H" + "a");//输出:Ha System.out.println('H' + ' ...

  8. OC基础6:多态、动态类型和动态绑定

    "OC基础"这个分类的文章是我在自学Stephen G.Kochan的<Objective-C程序设计第6版>过程中的笔记. 1.关于SEL类型的数据: (1).SEL ...

  9. 面向对象继承实例(a如何继承b)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  10. A. Anton and Letters

    time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...