首页 > 解决方案 > 没有fragmentSource的FabricJS图像过滤器?

问题描述

我有一个与 WebGL 不兼容的过滤器。有没有办法跳过编写片段源?我尝试在过滤器子类上覆盖 fabric.Image.filters.BaseFilter applyTo 以仅调用this.applyTo2d(options);但我没有得到任何图像数据。

applyTo: function(options) {
    if (options.webgl) {
      if (options.passes > 1 && this.isNeutralState(options)) {
        // avoid doing something that we do not need
        return;
      }
      this._setupFrameBuffer(options);
      this.applyToWebGL(options);
      this._swapTextures(options);
    }
    else if (!this.isNeutralState()) {
      this.applyTo2d(options);
    }
  },

标签: fabricjs

解决方案


我能够在 webgl_backend.class.js 中使用最少的代码以非优化方式完成此任务。

首先,webgl 后端需要非 webgl 过滤器的后备:

this.fallback2dBackend = new fabric.Canvas2dFilterBackend();

然后,而不是运行所有过滤器:fabric.filterBackend.applyFilters(filters, this._originalElement, sourceWidth, sourceHeight, this._element, this.cacheKey);

做这个:

  var newSource = fabric.util.createCanvasElement();
  newSource.width = sourceWidth;
  newSource.height = sourceHeight;
  var newSourceCtx = newSource.getContext('2d');
  newSourceCtx.drawImage(this._originalElement, 0, 0, sourceWidth, sourceHeight);

  filters.forEach(function(filter) {
    if (!filter) {
      return;
    }
    var backend = fabric.filterBackend;
    if (filter.fragmentSource === null) {
      backend = backend.fallback2dBackend;
    }

    backend.applyFilters(
      [filter], newSource, sourceWidth, sourceHeight, this._element);

    newSourceCtx.clearRect(0, 0, sourceWidth, sourceHeight);
    newSourceCtx.drawImage(this._element, 0, 0, sourceWidth, sourceHeight);

  }, this);

我已经发布了一个 fork,以防有人想将其重构为 PR。


推荐阅读