// 假设你有一个自定义的 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);
};