隐居以求其志,行义以达其道
fabric 自定义video元素
fabric 自定义video元素

fabric 自定义video元素

  // 假设你有一个自定义的 fabric.Video 类
  fabric.Video = fabric.util.createClass(fabric.Object, {
    type: 'video',

    initialize: function (options) {
      options = options || {};
      this.callSuper('initialize', options);

      this.videoEl = document.createElement('video');
      this.videoEl.src = options.src;
      this.videoEl.loop = options.loop || false;
      this.videoEl.controls = options.controls || false;
      this.videoEl.crossOrigin = 'anonymous'; // 解决 CORS 问题
      this.videoEl.onload = this.videoEl.play;
      this.videoEl.onended = this.videoEl.play;

      if (options.autoplay) {
        this.videoEl.play();
      }
      this.on('removed', this.dispose.bind(this));
    },

    _render: function (ctx) {
      this.update = () => {
        if (this.videoEl) {
          ctx.drawImage(this.videoEl, -this.width / 2, -this.height / 2, this.width, this.height);
          canvasEditor.fabricCanvas?.requestRenderAll();
          requestAnimationFrame(this.update);
        }
      };
      this.update();
    },

    dispose: function () {
      // 停止绘制视频帧
      cancelAnimationFrame(this.update);

      // 释放视频元素资源
      if (this.videoEl) {
        this.videoEl.pause();
        this.videoEl.src = ''; // 清空 src 属性,释放资源
        (this.videoEl as HTMLVideoElement).load(); // 确保浏览器释放资源
        this.videoEl = null; // 解除引用
      }
      // 调用父类的 dispose 方法(如果存在)

      if (this.callSuper) {
        this.callSuper('dispose');
      }
    },

    toObject: function () {
      return fabric.util.object.extend(this.callSuper('toObject'), {
        src: this.videoEl.src,
        loop: this.videoEl.loop,
        controls: this.videoEl.controls,
        autoplay: this.videoEl.autoplay,
      });
    },
  });

  // 注册自定义对象类型
  fabric.Video.fromObject = function (object, callback) {
    const video = new fabric.Video(object);
    callback(video);
  };