马黑黑 发表于 2022-2-28 12:01

HTML5画布canvas:画直线

本帖最后由 马黑黑 于 2022-2-28 12:10 编辑

画布,canvas,可能是大家比较陌生的HTML元素,此元素以成对的标签出现,代码样式如下:

<canvas id="cvas" width="300" height="200"></canvas>

作为画布,canvas是一块矩形区域,提供给用户在其上作画,作画的工具是JS。我们知道,JS通过 document.getElementById() 来识别指定元素,所以canvas最好定义id标识,以便让JS获得画布的操作句柄。画布的尺寸也可以在CSS中定义,但CSS不能完全像操控div那样操控canvas画布,比如 margin: auto 的设定无法令画布居中。

这里,先介绍如何在画布中画直线。这里面会用到好几个概念和方法,请耐心一一领会:

一、获取画布操作标识:

var cv = document.getElementById('cvas');

这句话大家应该能理解,之前的诸多示例里都见过它的芳容。这是获得画布操作句柄,就是说,JS通过 cv 变量识别画布并获取对画布的操作权限。

二、创建画笔

var ct = cv.getContext('2d');

这句,getContext('2d') 是选取 2d 即二维的上下文对象作为画笔渲染方式,换言之,创建一个 2d 的画笔,并授权给了变量 ct,ct 将是画笔的身份,由它来作画。

三、给画笔定义颜色

ct.strokeStyle = "red";

stroke 是击打的意思,这里可以理解为画画动作,有一锤定音之意(后面会理解到),是一个概念也是一个方法;strokeStyle 指画画使用的颜色、线条等样式,注意驼峰书写格式(下同);这里我们只定义一个颜色值。缺省值是黑色,就是说,没有这句设定,则画笔使用黑色作画。

四、定义线条的粗细

ct.lineWidth = 0.8;

line是线条之意,Width值宽度。这个缺省值是 1,就是说,如果没有这句,默认线条粗细为 1 个单位。

五、画笔定位

ct.moveTo(10,10);

此句是从何处开始下笔之意,就是(xy)坐标值。moveTo是移动到的意思,属于自然语言的表述风格。

六、定义直线路径

ct.lineTo(100,10);

lineTo() 方法,画直线到某处。某处用(xy)坐标值表示,(100,10) 是直线末端处的 xy坐标值,原来的起笔处(xy)坐标值是 (10,10),则这条直线水平方向的,长度为90px。

lineTo 方法在这里可以继续使用,下一条线的起点是上一条线的终点,如此类推。

七、一锤定音

ct.stroke();

stroke() 方法将前面设定的直线,包括颜色、粗细、从哪儿开始画、画到哪里,“一击定画”——计算机画画的方法就是与众不同,人家啥都设计好之后,一锤定音,不像俺们那样一笔一笔地去画。

完整代码(这里我多画了两条线):

<canvas id="cvas" width="300" height="200"></canvas>

<script>

var cv = document.getElementById('cvas'); // 画布操作句柄:识别画布
var ct = cv.getContext('2d'); // 创建上下文2d渲染对象(画笔)

// 画直线
ct.strokeStyle = "red"; // 画笔颜色
ct.lineWidth = 0.8; // 线条宽度
ct.moveTo(10,10); // 定义起笔处
ct.lineTo(100,10); // 画直线,在(100,10)处止笔
ct.lineTo(5,90); //接着画折线,在(5,90)处停笔
ct.lineTo(120,90); // 再画一条
ct.stroke(); // 绘制已定义的线条

</script>

马黑黑 发表于 2022-2-28 12:01

本帖最后由 马黑黑 于 2022-2-28 12:03 编辑 <br /><br /><canvas id="cvas" width="300" height="200"></canvas>

<script>

var cv = document.getElementById('cvas'); // 画布操作句柄:识别画布
var ct = cv.getContext('2d'); // 创建上下文2d渲染对象(画笔)

// 画直线
ct.strokeStyle = "red"; // 画笔颜色
ct.lineWidth = 0.8; // 线条宽度
ct.moveTo(10,10); // 定义起笔处
ct.lineTo(100,10); // 画直线,在(100,10)处止笔
ct.lineTo(5,90); //接着画折线,在(5,90)处停笔
ct.lineTo(120,90); // 再画一条
ct.stroke(); // 绘制已定义的线条路径

</script>

马黑黑 发表于 2022-2-28 12:11

画布画出来的可是一张图片哈,可以另存为的{:4_170:}

红影 发表于 2022-2-28 16:17

马黑黑 发表于 2022-2-28 12:11
画布画出来的可是一张图片哈,可以另存为的

真神奇,代码画出来的并不仅仅是展示内容,而是直接成了图片{:4_199:}

红影 发表于 2022-2-28 16:19

canvas元素第一次接触。只能连续画么,要是不连续的,需要重新定义起点的吧。

红影 发表于 2022-2-28 16:40


<canvas id="hy" width="300" height="100"></canvas>

<script>

var cv = document.getElementById('hy'); // 画布操作句柄:识别画布
var ct = cv.getContext('2d'); // 创建上下文2d渲染对象(画笔)

// 画直线
ct.strokeStyle = "red"; // 画笔颜色
ct.lineWidth = 0.9; // 线条宽度
ct.moveTo(60,10); // 定义起笔处
ct.lineTo(60,90); // 画直线
ct.moveTo(60,46); // 定义起笔处
ct.lineTo(90,46); // 画直线
ct.moveTo(90,10); // 定义起笔处
ct.lineTo(90,90); // 画直线

ct.moveTo(130,10); // 定义起笔处
ct.lineTo(145,40); // 画直线
ct.lineTo(145,90); // 接着原位置画直线
ct.moveTo(160,10); // 定义起笔处
ct.lineTo(145,40); // 画直线
ct.stroke(); // 绘制已定义的线条

</script>

红影 发表于 2022-2-28 16:41

画了个我的名字缩写,好玩。这个只能画直线么?遇到Q这样的字母怎么模拟呢{:4_173:}

红影 发表于 2022-2-28 16:43

我那个画得不好看,Y有点瘦,还得再调调。先去回帖了,空了再玩{:4_189:}

红影 发表于 2022-2-28 16:43

黑黑又带来新知识,好棒{:4_187:}

马黑黑 发表于 2022-2-28 17:00

<p>线帽:lineCap<br></p><p><br></p>
<p>canvas.lineCap = "butt | round | square"</p><p><br></p>
<p>butt -&nbsp;线条每一个末端的边缘平直</p>
<p>round -&nbsp;线条每一个末端的为圆形线帽</p>
<p>square -&nbsp;线条每一个末端的为方形线帽</p><p><br></p><p>非&nbsp;butt&nbsp;样式的线帽,线条长度略有加长。以下是代码和效果——</p><p><br></p><p>代码:</p><p><br></p><p>&lt;canvas id="mycanv" width="300" height="200"&gt;&lt;/canvas&gt;</p><p><br></p><p>&lt;script&gt;</p><p><br></p><p>var mycv = document.getElementById('mycanv');</p><p>var myct = mycv.getContext('2d');</p><p>myct.lineWidth = 10;</p><p>myct.strokeStyle = "darkgreen";</p><p><br></p><p>myct.beginPath();</p><p>myct.lineCap = "butt";</p><p>myct.moveTo(10,10);</p><p>myct.lineTo(200,10);</p><p>myct.stroke();</p><p>myct.closePath();</p><p><br></p><p>myct.beginPath();</p><p>myct.lineCap = "round";</p><p>myct.moveTo(10,30);</p><p>myct.lineTo(200,30);</p><p>myct.stroke();</p><p>myct.closePath();</p><p><br></p><p>myct.beginPath();</p><p>myct.lineCap = "square";</p><p>myct.moveTo(10,50);</p><p>myct.lineTo(200,50);</p><p>myct.stroke();</p><p>myct.closePath();</p><p><br></p><p>&lt;/script&gt;</p><p><br></p><p>效果:</p><p><br></p><p><br></p>


<canvas id="mycanv" width="300" height="200"></canvas>

<script>

var mycv = document.getElementById('mycanv');
var myct = mycv.getContext('2d');
myct.lineWidth = 10;
myct.strokeStyle = "darkgreen";

myct.beginPath();
myct.lineCap = "butt";
myct.moveTo(10,10);
myct.lineTo(200,10);
myct.stroke();
myct.closePath();

myct.beginPath();
myct.lineCap = "round";
myct.moveTo(10,30);
myct.lineTo(200,30);
myct.stroke();
myct.closePath();

myct.beginPath();
myct.lineCap = "square";
myct.moveTo(10,50);
myct.lineTo(200,50);
myct.stroke();
myct.closePath();

</script>

马黑黑 发表于 2022-2-28 17:05

10#代码中,我们画了三条不同线帽的直线,因此使用了开启路径(beginPath())和关闭路径(closePath())两个方法,每画一条线之前线开启路径,画完后关闭路径,每条如此。同时,stroke() 也独立存在于每一条线的代码模块中,不能到最好才用,否则后面的设置会覆盖前面的设置,线条的线帽都是一样的

马黑黑 发表于 2022-2-28 17:06

红影 发表于 2022-2-28 16:43
黑黑又带来新知识,好棒

canvas直线还有一些其他知识,都在本帖中一一介绍

马黑黑 发表于 2022-2-28 17:08

红影 发表于 2022-2-28 16:41
画了个我的名字缩写,好玩。这个只能画直线么?遇到Q这样的字母怎么模拟呢

有一个更简便的方法,不急,因为canvas的知识体系还是挺大的,慢慢来吧

马黑黑 发表于 2022-2-28 17:08

红影 发表于 2022-2-28 16:40
var cv = document.getElementById('hy'); // 画布操作句柄:识别画布
var ct = cv.getContext( ...

挺不错额

马黑黑 发表于 2022-2-28 17:34

lineJoin :设置或返回两条线交汇时的拐角类型<p></p><div><br></div><div>canvas.lineJoin = "bevel | round | miter";</div><div><br></div><div>bevel :&nbsp;斜角</div><div>round :&nbsp;圆角</div><div>miter :&nbsp;尖角(默认)</div><div><br></div><div>代码:</div><div><br></div><div><div>&lt;canvas id="guai"&gt;&lt;/canvas&gt;</div><div><br></div><div>&lt;script&gt;</div><div><br></div><div>var guai = document.getElementById('guai');</div><div>var ctx = guai.getContext('2d');</div><div><br></div><div>ctx.lineWidth = 12;</div><div>ctx.strokeStyle = "tomato";</div><div><br></div><div>ctx.beginPath();</div><div>ctx.lineJoin = "round";</div><div>ctx.moveTo(10,20);</div><div>ctx.lineTo(200,90);</div><div>ctx.lineTo(160,150);</div><div>ctx.stroke();</div><div>ctx.closePath</div><div><br></div><div>&lt;/script&gt;</div></div><div><br></div><div>效果:</div><div><br></div><div><br></div>

<canvas id="guai"></canvas>

<script>

var guai = document.getElementById('guai');
var ctx = guai.getContext('2d');

ctx.lineWidth = 12;
ctx.strokeStyle = "tomato";

ctx.beginPath();
ctx.lineJoin = "round";
ctx.moveTo(10,20);
ctx.lineTo(200,90);
ctx.lineTo(160,150);
ctx.stroke();
ctx.closePath

</script>

马黑黑 发表于 2022-2-28 17:37

关于canvas画直线,常用的知识差不多讲完了,今后将另开新帖将其他内容的画法,比如矩形、圆形、文本等等

红影 发表于 2022-2-28 19:18

马黑黑 发表于 2022-2-28 17:06
canvas直线还有一些其他知识,都在本帖中一一介绍

嗯嗯,还可以画线帽,貌似增加了一线画线帽的空间呢。

红影 发表于 2022-2-28 19:19

马黑黑 发表于 2022-2-28 17:08
有一个更简便的方法,不急,因为canvas的知识体系还是挺大的,慢慢来吧

看起来里面的内容很多啊,跟着慢慢学习{:4_187:}

马黑黑 发表于 2022-2-28 19:20

红影 发表于 2022-2-28 19:19
看起来里面的内容很多啊,跟着慢慢学习

这个对你来说估计不会太难

红影 发表于 2022-2-28 19:21

马黑黑 发表于 2022-2-28 17:34
lineJoin :设置或返回两条线交汇时的拐角类型canvas.lineJoin = "bevel | round | miter";bevel :&nbsp;斜 ...

ctx.lineWidth = 12 还以为和透明度一样,只能0.1-1.0能,原来可以任意设啊。
页: [1] 2 3 4
查看完整版本: HTML5画布canvas:画直线