iT邦幫忙

2024 iThome 鐵人賽

DAY 22
0
Modern Web

一起來玩圖像編輯器:Fabric.js 的實戰修煉系列 第 22

Day22-手機雙指觸控畫布也 ok!- Fabric.js 中實現手機畫布多點觸控支持

  • 分享至 

  • xImage
  •  

今天來實現如何在手機上也可以順利跟你的畫布互動!
其實手機上本來就可以運行,只是在手機上使用者習慣的觸控行為跟滑鼠控制的方式蠻不一樣的,例如:如果想放大一張圖片,我們可能會想用兩指把圖片拉大,而非像電腦上的指把一個角往外拉

雙指縮放圖片大小

主要的差別在於使用不同的事件處理不同裝置的事件。
在這邊我們使用 touch:gesture 處理觸控裝置事件,而 mouse:up 來處理電腦滑鼠事件。


const handelGestureScale = () => {

// 監聽 touch:gesture 手勢行為事件,處理 "雙指觸控"
	canvas.on('touch:gesture', () => {
		const activeObj = canvas.getActiveObject();
		if (activeObj) {
		
		// 鎖定 x, y 來達成雙指縮放圖片大小
			activeObj.set({
				lockMovementX: true,
				lockMovementY: true,
			});
		}
	});
	
	// 讓在使用滑鼠時,不會鎖定 x, y 移動
	canvas.on('mouse:up', () => {
		const activeObj = canvas.getActiveObject();
		if (activeObj) {
			activeObj.set({
				lockMovementX: false,
				lockMovementY: false,
			});
		}
	});
	canvas.off('touch:gesture');
	canvas.off('mouse:up');
};

如何在手機上實現畫面縮放或是橫移畫面功能

此承 Day18-fabric.js 畫布縮放與平移:實現畫布的縮放和拖動功能(像 illustrator 一樣!),今天來寫在手機裝置上要如何達成這件事~

把要達成的事拆成3部分,可以讓使用者在手機上進行以下操作:

  • 使用單指拖動來平移畫布
  • 使用雙指捏合來縮放畫布
  • 使用雙指旋轉來旋轉畫布(新增一個旋轉功能!)

步驟

  1. 首先,我們需要添加觸控事件監聽器:
  • 監聽 'touch:gesture' 事件處理雙指觸控,實現縮放和旋轉功能。
  • 監聽 touch:drag 事件處理單指觸控,實現平移功能。
canvas.on('touch:gesture', function(opt) {
  var e = opt.e;
  if (e.touches && e.touches.length == 2) {
    // 處理縮放和旋轉
    var point = new fabric.Point(opt.self.x, opt.self.y);
    if (opt.self.state == "start") {
      zoomStartScale = canvas.getZoom();
    }
    var delta = zoomStartScale * opt.self.scale;
    canvas.zoomToPoint(point, delta);
    if (opt.self.rotation !== 0) {
      canvas.viewportTransform[4] = e.offsetX;
      canvas.viewportTransform[5] = e.offsetY;
      canvas.rotateAroundPoint(point, opt.self.rotation);
    }
  }
});

canvas.on('touch:drag', function(opt) {
  var e = opt.e;
  if (e.touches && e.touches.length == 1) {
    // 處理平移
    var vpt = canvas.viewportTransform;
    vpt[4] += e.touches[0].clientX - lastPosX;
    vpt[5] += e.touches[0].clientY - lastPosY;
    canvas.requestRenderAll();
    lastPosX = e.touches[0].clientX;
    lastPosY = e.touches[0].clientY;
  }
});
  1. 然後,我們需要禁用瀏覽器的預設觸摸行為:
  • 防止在操作畫布時出現意外的頁面滾動或縮放。
canvas.upperCanvasEl.addEventListener('touchstart', function (e) {
  if (e.touches.length > 1) {
    e.preventDefault();
  }
}, {passive: false});

canvas.upperCanvasEl.addEventListener('touchend', function (e) {
  if (e.touches.length > 1) {
    e.preventDefault();
  }
}, {passive: false});

canvas.upperCanvasEl.addEventListener('touchmove', function (e) {
  if (e.touches.length > 1) {
    e.preventDefault();
  }
}, {passive: false});
  1. 接著,我們需要更新縮放和平移函數以支持觸控操作:
  • 更新後的 zoomCanvaspanCanvas 函數可以更好地支持觸控操作。
function zoomCanvas(delta, point) {
  var zoom = canvas.getZoom();
  zoom *= 0.999 ** delta;
  if (zoom > 20) zoom = 20;
  if (zoom < 0.01) zoom = 0.01;
  canvas.zoomToPoint(point, zoom);
}

function panCanvas(deltaX, deltaY) {
  var vpt = canvas.viewportTransform;
  vpt[4] += deltaX;
  vpt[5] += deltaY;
  canvas.requestRenderAll();
}
  1. 最後,我們需要在畫布初始化時設置一些觸控相關的選項:
  • 啟用了觸控滾動Retina 縮放支持
var canvas = new fabric.Canvas('canvas', {
  allowTouchScrolling: true, //**觸控滾動**
  enableRetinaScaling: true // **Retina 縮放支持**
});

上一篇
Day21- [相關介紹] 視覺互動向量圖界的運算強者- Paper.js
下一篇
Day23-fabric.js進階組合技!- 實作path線段控制&多邊形
系列文
一起來玩圖像編輯器:Fabric.js 的實戰修煉30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言