#2 线条属性lineCap, lineJoin以及绘制五角星

上一章学习了 lineWidth 属性, 这一章将继续的学习线条的一些其他的属性。
主要有以下3个知识点:

  • lineCap: 设置线条开端和尾部, butt | square | round
  • 绘制五角星的方法,对其进行封装drawStar()
  • lineJoin: 线条相交处的形状, miter | bevel | round,以及miterLimit属性

lineCap

用于设置一个线条两段的形状, 可选的形状有: butt(默认值) | square | round

这个属性只能用于线段的开始和结尾处,不能用于线段的连接处

效果如下图: 分别是默认效果('butt'),'round', 'square':

图中橘红色的线为基线,作对比用

JSBIN lineCap

绘制五角星

慕课网 canvas绘制五角星

绘制一个五角星,最主要的是分析五角星的各个顶点的坐标,这就要用到数学的知识了。但是浏览器中的坐标系和数学中的坐标系有以下几点不同:

  1. 浏览器中的Y轴是向下的,在x轴上的y坐标需要添加负号
  2. 浏览器中是使用弧度计算角度的,所以需要通过公式将角度转换为弧度, 比如将70°转换为弧度: Math.sin( (70 / 180) * Math.PI )

分析一下:

  • 五角星5个顶点,相连2个顶点之间的夹角为(360° / 5 = 72°)
  • 五角星由内部一个小圆和外部一个大圆构成
  • 以五角星中心为坐标原点,右上角为第1个点,逆时针旋转,外层圆初始角度为18°, 内部小圆初始角度为(18°+36°=54°)
  • 然后不同圆下一个角度都相差72°

这样我们可以将各个顶点坐标用for循环表示出来:

for (var i = 0; i < 5; i++) {
  ctx.lineTo(
    Math.cos( (18 + 72*i)/180 * Math.PI ) * 300 + 400,
    -Math.sin( (18 + 72*i)/180 * Math.PI ) * 300 + 400
  );
  ctx.lineTo(
    Math.cos( (54 + 72*i)/180 * Math.PI ) * 150 + 400,
    -Math.sin( (54 + 72*i)/180 * Math.PI ) * 150 + 400
  );
}
// 其中 300, 150 分别表示大圆的半径R, 小圆的半径r
// (400, 400)为圆心的坐标
# 注意Math.sin前面是负号

然后我们可以对上面的过程进行封装:

/*
 * @param ctx: canvas context
 * @param x, y: 圆心坐标值
 * @param R, r: 大圆,小圆的半径
 */
function drawStar(ctx, x, y, R, r) {
  ctx.beginPath();

  for (var i = 0; i < 5; i++) {
    ctx.lineTo(
      Math.cos ( (18 + i*72) / 180 * Math.PI ) * R + x,
      -Math.sine( (18 + i*72) / 180 * Math.PI ) * R + y
    );
    ctx.lineTo(
      Math.cos ( (54 + i*72) / 180 * Math.PI ) * r + x,
      -Math.sine( (54 + i*72) / 180 * Math.PI ) * r + y
    );
  }

  ctx.closePath();
  ctx.stroke();
}

调用:

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

ctx.lineWidth = 10;

# 调用
drawStar(ctx, 400, 400, 300, 150);

另外我们可以给五角星添加一个旋转角度rotation

# 因为我们是逆时针计算的,所以rotation前面应该添加负数
# 并且给rotation添加一个默认值0
function drawStar(ctx, x, y, R, r, rotation = 0) {
  ctx.beginPath();

  for (var i = 0; i < 5; i++) {
    ctx.lineTo(
      Math.cos ( (18 + i*72 - rotation) / 180 * Math.PI ) * R + x,
      -Math.sine( (18 + i*72 - rotation) / 180 * Math.PI ) * R + y
    );
    ctx.lineTo(
      Math.cos ( (54 + i*72 - rotation) / 180 * Math.PI ) * r + x,
      -Math.sine( (54 + i*72 - rotation) / 180 * Math.PI ) * r + y
    );
  }

  ctx.closePath();
  ctx.stroke();
}

则将五角星旋转50°:

ctx.strokeStyle = 'green';
ctx.lineWidth = 10;
drawStar(ctx, 400, 400, 300, 150, 50);

具体效果 旋转五角星

lineJoin

这个属性表示线条相交部分的形状,这个属性有3个值: miter(尖脚)(默认值) | bevel(平角) | round(圆角)

其效果如下:

1.miter

2.bevel

3.round

注意:

当设置为miter时(当然默认情况也为miter),它有个默认值的属性叫 miterLimit, 默认值为10, 如果2条线相交之后miter的值小于这个miterLimit值, 则 ctx.lineJoin = 'miter' 将自动转换成 ctx.lineJoin = 'bevel'

miterLimit的值的计算如下

我们可以设置这个miterLimit值

ctx.miterLimit = 20

总结

这一章主要是关于线条的一些基本属性,基本用法等。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容