我就不信,你不知道这些 Canvas 线条属性

线条样式

前言

"唰","唰","唰",还记得学习素描的时候,我们会用不同的笔来绘制各种各样的线条,有粗有细,有虚有实,有深有浅,有平行有相交。这一节我们将拿起画笔,就单纯的画画线,打打底子。那么在 Canvas 中,是通过什么属性或者方法来定义线条的样式呢?

为了本文讲解,本文中所有的 Canvas 上下文用 ctx 对象来表示

lineWidth 属性

js 复制代码
ctx.lineWidth = 整数;

Linewidth 属性取值为整数,默认为1,单位 px。

这个属性前面的文章也用过,没有做任何的讲解,但是我想大家应该看了就知道这就是线宽的设置,通过文本意义应该一目了然。

js 复制代码
<template>
  <canvas ref="cnv" width="200" height="150" style="border: 1px dashed gray"></canvas>
</template>

<script setup>
import {ref, onMounted} from "vue";
const cnv = ref();

const drawLine = () => {
  const ctx = cnv.value.getContext('2d');

  ctx.lineWidth = 10;
  ctx.strokeStyle = "hotpink";
  ctx.moveTo(20, 30);
  ctx.lineTo(180, 30);
  ctx.stroke();

  ctx.beginPath();
  ctx.lineWidth = 5;
  ctx.moveTo(20, 70);
  ctx.lineTo(180, 70);
  ctx.stroke();

  ctx.beginPath();
  ctx.moveTo(20, 120);
  ctx.lineTo(180, 120);
  ctx.stroke();
}

onMounted(() => {
  drawLine();
});
</script>

我们结合图和代码来看一下,第二条线和第三条线为啥线宽是一样的 5px 呢?那是因为在每一次绘制的时候,Canvas 会检测整个代码定义的样式,如果在新的路径中没有定义样式,则会延用原来定义样式。

我们再来看一下这种情况:

js 复制代码
<template>
  <canvas ref="cnv" width="200" height="150" style="border: 1px dashed gray"></canvas>
</template>

<script setup>
import {ref, onMounted} from "vue";
const cnv = ref();

const drawLine = () => {
  const ctx = cnv.value.getContext('2d');

  ctx.lineWidth = 10;
  ctx.strokeStyle = "hotpink";
  ctx.moveTo(20, 30);
  ctx.lineTo(180, 30);
  ctx.stroke();

  ctx.beginPath();
  ctx.lineWidth = 5;
  ctx.moveTo(20, 70);
  ctx.lineTo(180, 70);
  ctx.stroke();

  ctx.beginPath();
  ctx.lineWidth = 15;
  ctx.moveTo(20, 120);
  ctx.lineTo(180, 120);
  ctx.stroke();
}

onMounted(() => {
  drawLine();
});
</script>
js 复制代码
<template>
  <canvas ref="cnv" width="200" height="150" style="border: 1px dashed gray"></canvas>
</template>

<script setup>
import {ref, onMounted} from "vue";
const cnv = ref();

const drawLine = () => {
  const ctx = cnv.value.getContext('2d');

  ctx.lineWidth = 10;
  ctx.strokeStyle = "hotpink";
  ctx.moveTo(20, 30);
  ctx.lineTo(180, 30);
  ctx.stroke();

  ctx.lineWidth = 5;
  ctx.moveTo(20, 70);
  ctx.lineTo(180, 70);
  ctx.stroke();

  ctx.lineWidth = 15;
  ctx.moveTo(20, 120);
  ctx.lineTo(180, 120);
  ctx.stroke();
}

onMounted(() => {
  drawLine();
});
</script>

当我们删掉 ctx.beginPath(); 时,三条线变成了一样的线宽,怎么回事呢?那是因为在同一个路径中,Canvas 会使用最后一次定义的样式,也就是说想使用不同的样式时,需要以开始一条新路(ctx.beginPath)径来重新定义线条的样式属性。

lineCap 属性

lineCap 属性用于显示线条开始处与结尾处线帽样式;

js 复制代码
ctx.lineCap = "Butt";
// 取值为: 
// "Butt": 默认值,无线帽
// "Round": 圆形线帽
// "Square": 方形线帽

对应的属性值大小写都可以,我们来用实际对比代码来看看这几个属性值有啥区别:

js 复制代码
<template>
  <canvas ref="cnv" width="200" height="150" style="border: 1px dashed gray"></canvas>
</template>

<script setup>
import {ref, onMounted} from "vue";
const cnv = ref();

const drawLine = () => {
  const ctx = cnv.value.getContext('2d');

  ctx.lineWidth = 1;
  ctx.strokeStyle = "#cccccc";
  ctx.moveTo(10, 0);
  ctx.lineTo(10, 150);
  ctx.moveTo(180, 0);
  ctx.lineTo(180, 150);
  ctx.stroke();

  ctx.beginPath();
  ctx.lineWidth = 20;
  ctx.lineCap = "butt";
  ctx.strokeStyle = "hotpink";
  ctx.moveTo(10, 30);
  ctx.lineTo(180, 30);
  ctx.stroke();

  ctx.beginPath();
  ctx.lineCap = "round";
  ctx.moveTo(10, 70);
  ctx.lineTo(180, 70);
  ctx.stroke();

  ctx.beginPath();
  ctx.lineCap = "square";
  ctx.moveTo(10, 120);
  ctx.lineTo(180, 120);
  ctx.stroke();
}

onMounted(() => {
  drawLine();
});
</script>

我们可以从图片与代码中看到,"round" 和 "square" 的长度比 "butt" 更长,要长多少?从代码中我们能看到,长一个 lineWidth 的长度,两头平分,总结一下:有线帽的比没线帽的长一个线宽的长度

lineJoin 属性

在 Canvas 中,lineJoin 属性定义两个线条交接处的样式。

js 复制代码
ctx.lineJoin = "miter";
// 取值为: 
// "miter": 默认值,尖角
// "round": 圆角
// "bevel": 斜角

我们具体来看看 lineJoin 属性分别有什么区别:

js 复制代码
<template>
  <canvas ref="cnv" width="200" height="150" style="border: 1px dashed gray"></canvas>
</template>

<script setup>
import {ref, onMounted} from "vue";
const cnv = ref();

const drawLine = () => {
  const ctx = cnv.value.getContext('2d');

  ctx.lineWidth = 20;
  ctx.strokeStyle = "hotpink";

  ctx.beginPath();
  ctx.lineJoin = "miter";
  ctx.moveTo(10, 20);
  ctx.lineTo(180, 20);
  ctx.lineTo(180, 40);
  ctx.stroke();

  ctx.beginPath();
  ctx.lineJoin = "round";
  ctx.moveTo(10, 70);
  ctx.lineTo(180, 70);
  ctx.lineTo(180, 100);
  ctx.stroke();

  ctx.beginPath();
  ctx.lineJoin = "bevel";
  ctx.moveTo(10, 120);
  ctx.lineTo(180, 120);
  ctx.lineTo(180, 140);
  ctx.stroke();
}

onMounted(() => {
  drawLine();
});
</script>

从上图及代码中我们可以总结出三者的区别:

  • mitter: 线条直接延伸交于点,为默认值;
  • round:交接处是一个圆角,圆角所在圆直径等于线宽;
  • bevel:交接处是一个斜角,斜角所在正方形的对角线长等于线宽。

setLineDash() 方法

在 Canvas 中,用setLineDash() 方法来设置线条虚实样式。

js 复制代码
ctx.setLineDash(array);
// array 是一个数组组合

我们来看看具体怎么使用:

js 复制代码
<template>
  <canvas ref="cnv" width="200" height="150" style="border: 1px dashed gray"></canvas>
</template>

<script setup>
import {ref, onMounted} from "vue";
const cnv = ref();

const drawLine = () => {
  const ctx = cnv.value.getContext('2d');

  ctx.lineWidth = 2;
  ctx.strokeStyle = "hotpink";

  ctx.beginPath();
  ctx.moveTo(10, 20);
  ctx.lineTo(180, 20);
  ctx.setLineDash([2, 2]);
  ctx.stroke();

  ctx.beginPath();
  ctx.moveTo(10, 60);
  ctx.lineTo(180, 60);
  ctx.setLineDash([5, 5]);
  ctx.stroke();

  ctx.beginPath();
  ctx.moveTo(10, 80);
  ctx.lineTo(180, 80);
  ctx.setLineDash([10, 5]);
  ctx.stroke();

  ctx.beginPath();
  ctx.moveTo(10, 120);
  ctx.lineTo(180, 120);
  ctx.setLineDash([20, 5, 5, 5]);
  ctx.stroke();
}

onMounted(() => {
  drawLine();
});
</script>

从上面的图我们可以总结出参数的规则:

  • setLineDash() 方法接受一个整数数组;
  • 数组索引偶数为实线长度,奇数为虚线间隔距离;
  • 如果设置虚线绘制,即使使用 beginPath()方法也不能重置绘制的线为实线,需手动设置参数为[] 或 [num, 0]。

总结

本节内容很简单,主要就是针对线条的样式的设定,样式的设定给单调的线条有增多各种展示与应用的可能性。

相关推荐
anyup_前端梦工厂2 小时前
了解几个 HTML 标签属性,实现优化页面加载性能
前端·html
前端御书房2 小时前
前端PDF转图片技术调研实战指南:从踩坑到高可用方案的深度解析
前端·javascript
2301_789169542 小时前
angular中使用animation.css实现翻转展示卡片正反两面效果
前端·css·angular.js
风口上的猪20153 小时前
thingboard告警信息格式美化
java·服务器·前端
程序员黄同学3 小时前
请谈谈 Vue 中的响应式原理,如何实现?
前端·javascript·vue.js
爱编程的小庄4 小时前
web网络安全:SQL 注入攻击
前端·sql·web安全
宁波阿成5 小时前
vue3里组件的v-model:value与v-model的区别
前端·javascript·vue.js
柯腾啊5 小时前
VSCode 中使用 Snippets 设置常用代码块
开发语言·前端·javascript·ide·vscode·编辑器·代码片段
Jay丶萧邦5 小时前
el-select:有关多选,options选项值不包含绑定值的回显问题
javascript·vue.js·elementui
weixin_535854225 小时前
oppo,汤臣倍健,康冠科技,高途教育25届春招内推
c语言·前端·嵌入式硬件·硬件工程·求职招聘