【fabric.js】理解viewportTransform

249 阅读2分钟

viewportTransform

与画布变换矩阵相关的方法

// 画布矩阵各参数
martix = [scaleX, skewx, skewY, scaleY, translateX, translateY];
// 聚焦视口的变换(Canvas 2D API 变换矩阵)
canvas.viewportTransform(martix);
// 设置视口的变换,使得画布之外的元素可见
canvas.setViewportTransform(martix);

使用示例

场景

鼠标实现自由绘画。当鼠标移动时按下alt键时,从自由绘画模式切换为画布移动, 鼠标松开恢复自由绘画模式。

fabric 实现的逻辑分析

  1. 设置初始画布为自由绘画模式
  2. 鼠标移动时按下alt键关闭自由绘画模式,并标记为移动画布模式
  3. 鼠标移动,在移动画布模式下记录移动距离,根据鼠标移动距离更新画布变换矩阵
  4. 鼠标松开,恢复为自由绘画模式

代码实现

  (function () {
    let isDragging = false;
    let pos = [];
    const canvas = new fabric.Canvas("c", {
      width: 300,
      height: 300,
      isDrawingMode: true, // 开启自由绘画模式
    });
    // 自由绘画模式是由鼠标向上和鼠标向下触发的,原始的mousedown 事件仅执行一次,然后被删除
    // 所以在before事件中由移动画布模式更改为自由绘画模式
    canvas.on("mouse:down:before", () => {
      canvas.isDrawingMode = true;
    });
    canvas.on("mouse:down", (options) => {
      const evt = options.e;
      if (evt.altKey === true) {
        canvas.isDrawingMode = false;
        // 标记移动画布模式
        isDragging = true;
        // 记录下初始位置
        pos = [evt.clientX, evt.clientY];
      }
    });
    canvas.on("mouse:move", (options) => {
      const evt = options.e;
      // 在移动画布模式下做以下操作
      if (isDragging) {
        // 更新画布的变换矩阵
        const vpt = canvas.viewportTransform;
        vpt[4] += evt.clientX - pos[0];
        vpt[5] += evt.clientY - pos[1];
        canvas.requestRenderAll();
        // 更新鼠标位置
        pos = [evt.clientX, evt.clientY];
      }
    });
    // 在鼠标松开时关闭移动画布模式
    canvas.on("mouse:up", (options) => {
      // 更新视口的变换,使得画布之外的元素可见
      canvas.setViewportTransform(canvas.viewportTransform);
      // 关闭移动画布模式
      isDragging = false;
    });
    // 在鼠标移动时松开alt键也需要关闭移动画布模式
    document.addEventListener("keyup", (e) => {
      if (e.keyCode === 18) {
        canvas.setViewportTransform(canvas.viewportTransform);
        isDragging = false;
      }
    });
  })();