如何使用 fabric.js 创建自定义笔刷?

How to create custom brush paint with fabric.js?

我一直在尝试使用 fabric JS . I have tried using the fabric.PatternBrush 使用图像文件创建自定义画笔绘画,但这并不是我要找的东西,因为这会创建一种背景图案绘画,而我正是试图做的是在拖动鼠标的任何地方重复图像。

任何人都可以指引我走向正确的道路吗?我可以切换到任何其他能满足我要求的绘图库。

我找到了解决这个问题的方法。我们可以使用 fabric.BaseBrush 创建自定义画笔,如下所示:

  fabric.SprayBrush = fabric.util.createClass(fabric.BaseBrush, {

    opacity: .2,
    width: 30,

    _baseWidth: 5,
    _drips: [],
    _dripThreshold: 15,
    _inkAmount: 0,
    _interval: 20,
    _lastPoint: null,
    _point: null,
    _strokeId: 0,
    brush: null,
    brushCol : '/static/img/creation_room/textures/texture2.png',

    initialize: function(canvas, opt) {
      var context = this;
      opt = opt || {};

      this.canvas = canvas;
      this.width = opt.width || canvas.freeDrawingBrush.width;
      this.opacity = opt.opacity || canvas.contextTop.globalAlpha;
      this.color = opt.color || canvas.freeDrawingBrush.color;

      this.canvas.contextTop.lineJoin = "round";
      this.canvas.contextTop.lineCap = "round";

      this._reset();

      fabric.Image.fromURL(this.brushCol, function(brush) {
        console.log(brush);
        context.brush = brush;
        context.brush.filters = [];
        context.changeColor(context.color || this.color);
      }, { crossOrigin: "anonymous" });
    },

    changeColor: function(color) {
      this.color = color;
      this.brush.filters[0] = new fabric.Image.filters.Tint({ color: color });
      this.brush.applyFilters(this.canvas.renderAll.bind(this.canvas));
    },

    changeOpacity: function(value) {
      this.opacity = value;
      this.canvas.contextTop.globalAlpha = value;
    },

    onMouseDown: function(pointer) {
      this._point = new fabric.Point(pointer.x, pointer.y);
      this._lastPoint = this._point;

      this.size = this.width + this._baseWidth;
      this._strokeId = +new Date();
      this._inkAmount = 0;

      this.changeColor(this.color);
      this._render();
    },

    onMouseMove: function(pointer) {
      this._lastPoint = this._point;
      this._point = new fabric.Point(pointer.x, pointer.y);
    },

    onMouseUp: function(pointer) {
    },

    _render: function() {
      var context = this;

      setTimeout(draw, this._interval);

      function draw() {
        var point, distance, angle, amount, x, y;

        point = new fabric.Point(context._point.x || 0, context._point.y || 0);
        distance = point.distanceFrom(context._lastPoint);
        angle = point.angleBetween(context._lastPoint);
        amount = (100 / context.size) / (Math.pow(distance, 2) + 1);

        context._inkAmount += amount;
        context._inkAmount = Math.max(context._inkAmount - distance / 10, 0);
        if (context._inkAmount > context._dripThreshold) {
          context._drips.push(new fabric.Drip(context.canvas.contextTop, point, context._inkAmount / 2, context.color, context._strokeId));
          context._inkAmount = 0;
        }

        x = context._lastPoint.x + Math.sin(angle) - context.size / 2;
        y = context._lastPoint.y + Math.cos(angle) - context.size / 2;
        context.canvas.contextTop.drawImage(context.brush._element, x, y, context.size, context.size);

        if (context.canvas._isCurrentlyDrawing) {
          setTimeout(draw, context._interval);
        } else {
          context._reset();
        }
      }
    },

    _reset: function() {
      this._drips.length = 0;
      this._point = null;
      this._lastPoint = null;
    }
  });

现在,我们只需要在canvas中使用这个画笔即可。

var canvas = new fabric.Canvas('canvas');
canvas.freeDrawingBrush = new fabric.SprayBrush(canvas, { width: 70,opacity: 0.6, color: "transparent" });