在使用變形效果以前,通常會先儲存畫布,以下為畫布的儲存和復原方法:
方法 | 描述 |
---|---|
save() |
儲存現階段畫布狀態 |
restore() |
復原最近一次儲存的畫布狀態 |
每一次呼叫save()
,畫布狀態就會存進一個stack中,畫布的狀態包含:
strokeStyle
, fillStyle
, globalAlpha
, lineWidth
, lineCap
, lineJoin
, miterLimit
, shadowOffsetX
, shadowOffsetY
, shadowBlur
, shadowColor
, globalCompositeOperation
屬性的屬性值而每一次呼叫restore()
,最近一次儲存的畫布便會從堆疊中被取出,然後還原到此畫布狀態。
可以想像成是移動、旋轉、縮放畫布上的座標軸
方法 | 描述 |
---|---|
translate(x, y) |
移動網格上的畫布,將畫布原點(0,0)移到(x,y),其中x代表水平距離、y代表垂直距離 |
rotate(x) |
以畫布原點為中心,順時針旋轉畫布x弧度(弧度 = Math.PI * 角度 / 180) |
scale(x, y) |
x代表縮放畫布水平網格單位x倍,y代表縮放畫布垂直網格單位y倍,輸入1.0不會造成縮放。如果輸入負值會造成座標軸鏡射。 |
transform(a, b, c, d, e, f) |
上面三個變形效果都是設定在這個變形矩陣,呼叫Transform會拿目前的變形矩陣,a 代表水平縮放圖像,b 代表水平偏移圖像,c 代表垂直偏移圖像,d 代表垂直縮放圖像,e 代表水平移動圖像,f 代表垂直移動圖像 |
setTransform(a, b, c, d, e, f) |
將目前矩陣當作恆等矩陣,也就是設成預設矩陣 |
最好在做變形效果前儲存畫布狀態,如果要恢復先前狀態,只要呼叫restore()就能恢復畫布狀態,如忘記儲存和恢復畫布狀態,繪圖區域很容易超出邊界,發生圖案不見的狀況。
因為怕自己以後忘記transform的矩陣是怎麼來的,在此紀錄一下:
a
代表水平縮放圖像,影響在縮放或旋轉影像時沿X軸的像素定位b
代表水平偏移圖像,影響在旋轉或傾斜影像時沿Y軸的像素定位c
代表垂直偏移圖像,影響在旋轉或傾斜影像時沿X軸的像素定位d
代表垂直縮放圖像,影響在縮放或旋轉影像時沿Y軸的像素定位e
代表水平移動圖像,沿X軸移動f
代表垂直移動圖像,沿Y軸移動ctx.translate(150,150) //移動畫布原點至(150,150)
for(let i=1; i<12; i++){ //畫12圈
ctx.save() //儲存畫布狀態
ctx.fillStyle='rgb('+(25*i)+',255,'+ (255-25*i)+')' //決定每一圈填滿顏色
for(let j=0;j<i*6;j++){ //決定每一圈畫幾個矩形
ctx.rotate(Math.PI*2/(i*6)) //旋轉畫布
ctx.beginPath()
ctx.rect(0,i*12.5,6,6) //畫每一圈矩形
ctx.fill()
}
ctx.restore() //恢復一開始畫布還沒旋轉狀態,讓下一圈的也從頭畫
}
最後成果:
~如有疑問或是錯誤,歡迎不吝指教~
參考來源:
[1]https://developer.mozilla.org/zh-TW/docs/Web/API/Canvas_API/Tutorial/Transformations
[2]https://www.w3school.com.cn/tags/html_ref_canvas.asp
[3]https://www.runoob.com/w3cnote/html5-canvas-intro.html
[4]https://www.twle.cn/l/yufei/canvas/canvas-basic-geometric-transform.html