iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 21
2
Modern Web

Fabricjs 筆記系列 第 21

Day 21 - Fabricjs Zoom in & Zoom out

  • 分享至 

  • xImage
  •  

今天來做 Fabricjs 的縮放畫布

Zoom

只要透過修改 Zoom 值,就能夠讓畫布做到縮放的效果,fabricjs 會主動幫我們調整物件的大小。

  • 預設 zoom 值 1,為縮放倍率。

下圖可以我們透過將 rect.getBoundingRect() 印出來看到其實 fabricjs 在縮放時將大小放大了。

不過 scaleX 和 scaleY 都不會變還是 1

  • getZoom 可取得 Zoom 值
  • setZoom 設定 Zoom 值
    這邊先做 getZoom 拿到目前的 zoom 後,改變縮放倍率後,再透過 setZoom 設定新的縮放倍率。
function setZoom (zoom) {
  // zoom 為 +-0.1
  const newZoom = canvas.getZoom() + zoom
  const center = canvas.getCenter()
  canvas.setZoom(newZoom)
  // showZoom 為 input element
  showZoom.value = `${Math.round(newZoom * 100)}%`
}

到這裡做起來相當直覺又相當簡單就能夠操作 canvas 的縮放了,但是這樣子縮放都是依照最左上角來縮放,並沒有辦法縮放某個我們想要的點。如下圖。

zoomToPoint

這時候我們就會需要用到 zoomToPoint 這個方法囉,這個方法可以讓我們設定要依哪個座標來當作中心位置做縮放。

只要把上面那個範例的 canvas.setZoom 改成 canvas.zoomToPoint({x: center.left, y: center.top}, newZoom) 後,就能夠依據中心來縮放了!

透過滑鼠滾輪縮放

剛剛我們實作了使用按鈕來控制縮放,現在我們配合滑鼠來做縮放,使用 canvas on mousewheel 這個事件,能夠達到我們所想要的要求。

deltaY 屬性

mousewheel 事件中有一個 deltaY 這個滾輪的垂直移動值,我們可以透過這個屬性去決定要縮還放。

這邊我稍微改了一下讓原本 setZoom 方法還能夠傳入座標。這樣我們就能輕鬆地做到跟著鼠標縮放囉!

canvas.on('mouse:wheel', (e) => {
  const deltaY = e.e.deltaY
  const newZoom = deltaY / 1000
  setZoom(newZoom, {x: e.e.offsetX, y: e.e.offsetY})
})

既然現在我們都能夠透過滑鼠位置縮放了,接下來就再來做能讓者用者在放大時,還能夠移動想要看的位置吧。

讓使用者案住 alt 在拖曳畫布能夠移動可視範圍

  • 設定 isDragging 變數判斷是否正在配拖曳
  • 為了計算移動多少距離,給定兩個變數 lastX lastY
const moveCanvasInfo = {
  isDragging: false,
  lastX: 0,
  lastY: 0
}

設定 mouse down 事件,mouse down 時若有點擊 alt 鍵時,將進入 dragging 模式,將 dragging = true,並且記錄目前滑鼠的座標。

canvas.on('mouse:down', (e) => {
  if (e.e.altKey) {
    moveCanvasInfo.isDragging = true
    canvas.selection = false
    moveCanvasInfo.lastX = e.e.clientX
    moveCanvasInfo.lastY = e.e.clientY
  }
})

當滑鼠被移動時,我們判斷使用者是否使用了 alt 來做拖曳,所以先判斷 isDragging 變數,接下來動態的去計算每次移動時的移動量,透過 canvas.viewportTransform 來改變中心起始座標,造成視覺上的移動效果。

canvas.viewportTransform 用法同原生 canvas.transform()
w3chool canvas transform

canvas.on('mouse:move', function(e) {
  if (moveCanvasInfo.isDragging) {
    // 同 canvas transform method
    // 計算移動量
    canvas.viewportTransform[4] += e.e.clientX - moveCanvasInfo.lastX
    canvas.viewportTransform[5] += e.e.clientY - moveCanvasInfo.lastY
    canvas.requestRenderAll()
    moveCanvasInfo.lastX = e.e.clientX
    moveCanvasInfo.lastY = e.e.clientY
  }
})

最後在 mouse up 解除 isDragging,isDragging = false

canvas.on('mouse:up', function(opt) {
  moveCanvasInfo.isDragging = false
  moveCanvasInfo.selection = true
})

結果

本日小結

今天學習怎麼控制 fabricjs 的 zoom 值,以及做了相關的應用練習。

結合滑鼠中心和滾輪來修改 zoom 值。

配合 canvas 事件來做出這些效果。

參考資料

Day 8 - Fabricjs 事件

w3chool canvas transform

本日完整程式 & demo


上一篇
Day 20 - Fabricjs 實作網格系統
下一篇
Day 22 - Fabricjs 圖形裁切基礎介紹
系列文
Fabricjs 筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
advancedor96
iT邦新手 5 級 ‧ 2018-11-05 20:47:27

何時才會有廢文出現?

Nono iT邦新手 5 級 ‧ 2018-11-05 22:53:33 檢舉

真的每天都有發廢文的衝動QQ

我要留言

立即登入留言