iT邦幫忙

2021 iThome 鐵人賽

DAY 8
1
Modern Web

Canvas 小錦囊系列 第 8

Day 8 - 用 canvas 復刻 小畫家 繪製圓形/橢圓形

圓形

嘗試ellipse

按照搜尋結果,我們一開始可能很直覺的會想到使用 ellipse

ellipse 是 Canvas 2D API 添加橢圓路徑的方法。橢圓的圓心在(x,y)位置,半徑分別是radiusX 和 radiusY ,按照anticlockwise(默認順時針)指定的方向,從 startAngle 開始繪製,到 endAngle 結束。

void ctx.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);

然後我們就按照文檔,將內容都帶上

  case "ellipse":
      clearCanvas();
      restore();
      ctx.strokeStyle = activeColor;
      ctx.ellipse(
        initialPoint.x,
        initialPoint.y,
        Math.abs(width),
        Math.abs(height),
        0,
        2 * Math.PI,
        false
      );
      ctx.stroke();
  break;



看來不是我們要的效果,再試試別的參數

貝茲曲線

bezierCurveTo 是 Canvas 2D API 繪製三次貝賽爾曲線路徑的方法。該方法需要三個點。第一、第二個點是控制點,第三個點是結束點。起始點是當前路徑的最後一個點,繪製貝賽爾曲線前,可以通過調用 moveTo() 進行修改

void ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);

雖然我們對貝茲曲線不熟,但根據文檔,似乎可以嘗試看看帶入我們所擁有的值。

思考

貝茲曲線是拿來繪製曲線的,一般來說,橢圓與圓形的構成就是利用兩個弧線,所以我們是不是只要拼接出兩個半圓弧線,就可以完成一個圓?
看看程式碼怎麼寫:

...
case "ellipse":
  clearCanvas();
  restore();
  ctx.strokeStyle = activeColor;
  drawOval(
    ctx,
    initialPoint?.x,
    initialPoint?.y,
    point?.x,
    point?.y
  );
break;
...
          
          
/** 繪製橢圓 **/
const drawOval = (
  ctx: any,
  startX: number,
  startY: number,
  x: number,
  y: number
) => {
  ctx.beginPath();
  ctx.moveTo(startX, startY + (y - startY) / 2);
  ctx.bezierCurveTo(startX, startY, x, startY, x, startY + (y - startY) / 2);
  ctx.bezierCurveTo(x, y, startX, y, startX, startY + (y - startY) / 2);
  ctx.closePath();
  ctx.stroke();
};


酷!成功啦!!


上一篇
Day 7 - 用 canvas 復刻 小畫家 繪製矩形與圓角矩形
下一篇
Day 9 - 用 canvas 復刻 小畫家 曲線
系列文
Canvas 小錦囊30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言