iT邦幫忙

2021 iThome 鐵人賽

DAY 29
0
Modern Web

前端藏寶圖系列 第 29

來畫一個視力檢查表吧!

前言

今天要來研究的是 canvas~ 踩下去才發現是一個大坑XD,以下先從最基本的開始認識起,最後再來嘗試畫出自己的視力檢查表/images/emoticon/emoticon37.gif

codepen實作

canvas 基本認識

  • 是 HTML 元素,和<img> 類似,但沒有srcalt屬性,可透過 JS 操作來繪圖
  • 預設尺寸為 300 px × 150 px
  • 只有兩個屬性:widthheight,沒有指定大小就會是上述的預設尺寸
  • 可以用 DOM 操作給予屬性
  • 初始狀態是透明的,必須透過腳本取得畫布再用語法畫圖
  • canvas 使用的語法參數 x 及 y 都是相對於畫布左上角(0,0)位置的距離(對照下圖會比較清楚)

codepen

建立畫布的方式很簡單,就是在 HTML 輸入<canvas>標籤

<canvas class=".canvas" width="150" height="150"></canvas>

再用操作 DOM 元素方式取得 canvas 元素後,使用getContext方法取得渲染環境,這個方法接受一個參數來指定是幾維度的繪圖

const canvas = document.querySelector('.canvas'); const ctx = canvas.getContext('2d');

有了基本的設定後就可以來繪製圖型了~

繪製矩形

  • 以下三個方式會立即將矩形繪製到畫布上
  • ctx.fillRect(x, y, width, height): 繪製填滿的矩形
  • ctx.strokeRect(x, y, width, height): 繪製空白矩形
  • ctx.clearRect(x, y, width, height): 清除矩形區域

透過這些語法和更改線條樣式的語法就可以畫出下面的圖樣

可以用codepen觀察會比較清楚每個方法做到的效果

需要注意的地方是,如果要改變顏色,改變顏色的語法必須在繪製方法前喔!

繪製弧形

ctx.arc(x, y, radius, startAngle, endAngle [, counterclockwise])

弧形的語法需要五個參數,x,y代表圓心在畫布上的位置,根據radius為半徑畫圓,可以利用startAngleendAngle指定開始和結束的位置,counterclockwise是個非必要的參數,接受布林值,預設是 false,代表順時針繪製,true 則為逆時針繪製

MDN 特別註記: arc()方法用的是弧度(radians)而非角度(degrees),如果要在弧度與角度間換算,需要經過轉換,轉換的語法如下

radians = (Math.PI/180)* degrees


圖片來源:HTML5 Canvas Line Tutorial

小小練習

看著 MDN 示範弧形操作時,聯想到了視力檢查會出現的C型環,於是有了以下的練習,在開始前先認識一下 C 型視力表的設計

C 型視力表,又名蘭氏環形視力表(Landolt C),由瑞士眼科醫生Edmund Landolt 於19世紀發明,主要特色為:

  1. 有8個開口方向(E字視力表只有四個方向)
  2. 筆畫粗細以及開口大小是直徑的五分之一

開始練習~

步驟1: 在 HTML 建立 canvas

<canvas width="400px" height="600px"></canvas>

步驟2: 建立一個可以重複畫C型環的函式

  1. 因為筆畫粗細和直徑是 1:5 的關係,而arc()接受的參數是半徑,所以這裡有做一下轉換
  2. 考量開口的方向會有八個角度,這裡的想法是先固定開口距離,再換算開始和結束的角度
function drawC(x, y, lineWidth, gapDirection) {
  const ctx = canvas.getContext('2d');
  ctx.lineWidth = lineWidth;
  const radius = ctx.lineWidth * 2.5;
  const gap = 12;
  const startAngle = (gapDirection + gap) * (Math.PI/180);
  const endAngle =  (gapDirection - gap) * (Math.PI/180);
  
  ctx.beginPath();
  ctx.arc(x,y,radius,startAngle,endAngle);
  ctx.stroke();
}

步驟3: 使用函式畫出六排的 C 型環

// 第一排
drawC(100, 80, 20, 180);
drawC(300, 80, 20, 0);

// ...略 (前三排都先直接輸入數值)

// 第四排以後
const rotationDegree = 45; 

for (let x = 50; x <= 350; x+= 60) {
  const rotationRatio = Math.floor((Math.random() * 9));
  const direction = 0 + rotationRatio * rotationDegree;
  drawC(x, 320, 4, direction);
}

完成~

結語

每天盯著電腦工作又寫鐵人賽的大家記得要定期檢查視力喔~
/images/emoticon/emoticon41.gif

參考資料:

MDN
Landolt C


上一篇
來做一個跟屁蟲鎂光燈
下一篇
前端藏寶圖 - 寶藏在哪兒?
系列文
前端藏寶圖30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
wendy
iT邦新手 2 級 ‧ 2021-10-14 20:35:05

創意的佳萱

Chiahsuan iT邦新手 4 級 ‧ 2021-10-14 21:41:14 檢舉

都是受到你們的啟發~~~/images/emoticon/emoticon41.gif

0
南國安迪
iT邦新手 3 級 ‧ 2021-10-14 21:43:28

推推!

Chiahsuan iT邦新手 4 級 ‧ 2021-10-15 10:23:06 檢舉

/images/emoticon/emoticon41.gif

我要留言

立即登入留言