fabric.js实现canvas的画笔同步

指左边的画布写什么内容, 邮编的画布出现同样的内容


  1. 在首先想到的解决方案是, 监听canvas move的事件, 进行画布同步, 但是同步后, 相对是有延时性的, 而且需要同时监听 mouse:down, 和mouse:move时间, 相对性能页不是那么优雅.
  2. 监听 path:created 事件, path:created触发之后进行canvas 同步, 但是path:created 触发后,左边的内容已经绘制完了右边才开始同步, 左边画的越久,右边同步越慢

以上的2条途径都宣告失败了

最后在寻找 查找 PencilBrush 对像, 发现可以查看主动去出发 PencilBrush对象的 mouseDown, mouseMove, mouseUp, 这样就可以直接画出同步无延迟的画出左边的内容了,

这个时候在找到了一个现成的mode  https://codepen.io/moshfeu/pen/ZEGQEBO, 正常运行, 自己按照他的写法后, 居然失败了,不能按照这个运行, 查看了一下,这个demo使用的1.3.7版本, 现在fabric.已经是5.3的版本了, 应该有和版本有关, 看了下fabric.js 的文档,  这3个方法都是有的, 运行的时候会报错,
https://github.com/fabricjs/fabric.js/issues/7430

接下来翻看了下fabric.js 的源码, onMouseDown, 和onMouseDown 分别需要传递2个参数, 这里应该是文档没有及时更新导致



就这样, fabric.js 最新的版本也可以实现画笔的无延迟同步绘画了

import { useEffect } from 'react';
import fabric from '@/pages/customize/utils/newFabric';
import './index.scss';

let canvas = null;
const Fabric = () => {
  useEffect(() => {
    canvas = new fabric.Canvas(document.getElementById('canvasId'), {
      controlsAboveOverlay: true,
      enableRetinaScaling: true,
      selection: false
    });
    canvas.isDrawingMode = true;
    canvas.freeDrawingBrush.width = 5;
    canvas.freeDrawingBrush.color = '#00aeff';

    let isDrawing = false;
    canvas
      .on('mouse:down', function (options) {
        isDrawing = true;
        onMouseDown(options);
      })
      .on('mouse:up', function (options) {
        isDrawing = false;
        onMouseUp(options);
      })
      .on('mouse:move', function (options) {
        if (isDrawing) {
          const pointer = canvas.getPointer(options.e);
          drawRealTime(options, pointer);
        }
      });

    var canvas2 = new fabric.Canvas(document.getElementById('canvasId2'), {
      controlsAboveOverlay: true,
      enableRetinaScaling: true,
      selection: false
    });
    canvas2.isDrawingMode = true;
    canvas2.freeDrawingBrush.width = 5;
    canvas2.freeDrawingBrush.color = '#00aeff';

    function onMouseDown(options) {
      const pointer = canvas.getPointer(options.e);
      canvas2.freeDrawingBrush.onMouseDown(pointer, options);
    }

    function onMouseUp(options) {
      const pointer = canvas.getPointer(options.e);
      canvas2.freeDrawingBrush.onMouseUp(options);
    }

    function drawRealTime(options, pointer) {
      canvas2.freeDrawingBrush.onMouseMove(pointer, options);
    }
  }, []);
  return (
    <div>
      <canvas id='canvasId'></canvas>
      <canvas id='canvasId2'></canvas>
    </div>
  );
};

export default Fabric;


但是, 这个双 canvas 画笔同步的功能并不支持移动端进行同步, 因为在移动端无法主动去触发出 mouse 的鼠标事件,