【勉勉强强】搞懂 Canvas 中 arc,arcTo 方法绘制弧线
Canvas 弧线绘制
arc 方法绘制弧线
经过上一章的学习,我们知道了怎么利用 Canvas 绘制一个圆,回顾一下绘制的方法
ctx.arc(x, y, r, startAngle, endAngle, counterclockwise);
我们知道 arc 这个单词的意思就是弧线的意思,那么 arc 方法不仅可以绘制圆形,也可以用来绘制弧线,这一节我们将用 arc 方法来绘制弧线。用法跟绘制圆形是一样的。
我们直接来看例子:
<template>
<canvas ref="cnv" width="710" height="400" style="border: 1px dashed gray"></canvas>
</template>
<script setup>
import {ref, onMounted} from "vue";
import { coordinateSystem } from '../../../assets/js/drawTools.js'
const cnv = ref();
const drawArc = (cnv, ctx) => {
ctx.lineWidth = 4;
ctx.beginPath();
ctx.arc(cnv.width / 2, cnv.height / 2, 100, 210 * Math.PI / 180, 240 * Math.PI / 180, false);
ctx.strokeStyle = "hotpink";
ctx.stroke();
}
onMounted(() => {
const ctx = cnv.value.getContext('2d');
drawArc(cnv.value, ctx);
});
</script>
绘制出来的结果就是上图粉红色的部分,为了便于理解,我把绘制过程的辅助线都一起绘制出来了。值得我们注意的是,绘制弧线时,切记不能使用 closePath 方法,之前也提到过这个方法,如果使用了就会形成一个闭合的图形。
arcTo 方法绘制弧线
在 Canvas 中,我们除了使用 arc 方法绘制弧线外,还可以用 arcTo 方法绘制弧线,我们来看一下arcTo 方法的语法:
ctx.arcTo(controlX, controlY, endX, endY, radius);
- (controlX, controlY): 控制点坐标;
- (endX, endY): 结束点坐标 利用语法,我们先来绘制一段圆弧,然后通过绘制结果来类推结论:
<template>
<canvas ref="cnv" width="710" height="400" style="border: 1px dashed gray"></canvas>
</template>
<script setup>
import {ref, onMounted} from "vue";
import { coordinateSystem } from '../../../assets/js/drawTools.js'
const cnv = ref();
const drawArc = (cnv, ctx) => {
ctx.lineWidth = 4;
ctx.beginPath();
ctx.moveTo(cnv.width / 2, cnv.height / 2);
ctx.arcTo(cnv.width / 2 + 100, cnv.height / 2 - 100, cnv.width / 2 + 100, cnv.height / 2 , 100)
ctx.strokeStyle = "hotpink";
ctx.setLineDash([1, 0]);
ctx.stroke();
}
onMounted(() => {
const ctx = cnv.value.getContext('2d');
coordinateSystem(cnv.value, ctx);
drawArc(cnv.value, ctx);
});
</script>
明明绘制的是一个弧线,这是啥?怎么还多出来一截线段,而且感觉结束点也不是图上绘制的结束点啊?我们带着这些疑问来看一下分析图:
从上述代码中,我们可以看到,起始点一般有 moveTo 或者 lineTo 方法带出,然后才是调用 arcTo 方法,这个方法中我们需要知道控制点坐标,结束点坐标,以及圆弧半径长度。从分析图中,我们可以看到圆弧S'E'分别与直线SC,直线EC两条线相切相交于控制点C,那么可以定义出 arcTo 方法的原理:
arcTo方法:利用开始点,控制点和结束点连接相交于控制点所形成的夹角,绘制一段形成夹角的两边相切且半径为 radius 的圆弧。
我们从上图中可以看到,弧线的起始点与结束点是两条切线的切点,且跟我们绘制时提供的起始点与结束点均不一致,所以我们可以得出结论:开始点坐标与结束点坐标不一定是弧线的起止点坐标。 那什么时候这四个点坐标分别重合呢?我想一下,以正方形的一个顶点作为圆心,以边长作为半径绘制一个圆的时候,切点是不是就是圆心旁边两个正方形顶点啊?而剩下的那个顶点是不是就是控制点的坐标了呢?我们又可以得出结论:当起点与结束点和控制点形成的夹角为直角且半径等于两点与控制点的距离时,起止点与弧线的起止点重合,且绘制图形为一个1/4圆弧。
多出来的线段SS'其实是 arcTo 绘制出来的,因为如果起始点不是弧线起点,则 arcTo 方法会将起始点与弧线起点用直线段连接起来。
arc 方法与 arcTo 方法都可以绘制弧线,在开发中使用哪个来绘制更好呢?这就要看哪个方法的参数获取更简单就用哪个了呗。我们在CSS中经常碰到的样式圆角,现在我们也可以在 Canvas 中实现啦,jym ,感兴趣的小伙伴可以自己动动手,绘制一下圆角矩形哦!
总结
- arc 方法绘制弧线:
ctx.arc(x, y, r, startAngle, endAngle, counterclockwise);
- arcTo 方法绘制弧线:
ctx.arcTo(controlX, controlY, endX, endY, radius);
- 开始点坐标与结束点坐标不一定是弧线的起止点坐标;
- 当起点与结束点和控制点形成的夹角为直角且半径等于两点与控制点的距离时,起止点与弧线的起止点重合,且绘制图形为一个1/4圆弧;
- 如果起始点不是弧线起点,则 arcTo 方法会将起始点与弧线起点用直线段连接起来。
转载自:https://juejin.cn/post/7272196864509624377