Fabric.js custom object properties and work with video element
Posted on: 1/7/2025 4:41:00 PM
Table of contents
Here is some tips when i work with fabricjs to build Canva-like editor.
Custom object properties
For saving some custom properties when work with fabricjs, you need to add a custom attribute to fabric object, for doing this you need to override fabric Object toObject
method.
import { Object as FabricObject } from 'fabric'
//whatever properties you want to save
const _properties = ['video_src', 'animationType', 'hyperlink'];
FabricObject.prototype.toObject = (function (toObject) {
return function (propertiesToInclude) {
propertiesToInclude = (propertiesToInclude || []).concat(_properties);
return toObject.apply(this, [propertiesToInclude]);
};
})(FabricObject.prototype.toObject);
Save and re-render video element
As original example: https://fabricjs.com/demos/video-element/ You can add video element to canvas. But how about if you want to export, then import data from JSON?

First, this is some code to render video element to our canvas
import { Object as FabricObject, util, Image as FabricImage, Canvas } from "fabric";
function createVideoElement(url) {
var videoE = document.createElement('video');
videoE.width = 530;
videoE.height = 298;
videoE.muted = true;
videoE.crossOrigin = "anonymous";
var source = document.createElement('source');
source.src = url;
source.type = 'video/mp4';
videoE.appendChild(source);
return videoE;
}
var canvas = new FabricCanvas('c');
var url_mp4 = '/path/to/video.mp4';
var videoE = createVideoElement(url_mp4);
var fab_video = new FabricImage(videoE, {left: 0, top: 0});
fab_video.set('video_src', url_mp4); // <========= set custom property to save video src
canvas.add(fab_video);
fab_video.getElement().play();
util.requestAnimFrame(function render() {
canvas.renderAll();
util.requestAnimFrame(render);
});
You can see a line:
fab_video.set('video_src', url_mp4); // <========= set custom property to save video src
==> Read Custom object properties trick above, and add video_src
property.
Now, we can export to json by call method:
canvas.toJSON();
Ok, now we can load saved json by call this method:
canvas.loadFromJSON(json_data)
//loadFromJSON method used to convert JSON object to actual fabric object and load them to canvas.
The question now is how it will recognize the custom attribute video_src
. The answer is, it won’t. We need to create a video element and render it manually.
function canvasLoaded(){
canvas.renderAll.bind(canvas);
var objs = data['objects'];
for(var i=0; i< objs.length; i++){
const elm = objs[i];
if(objs[i].hasOwnProperty('video_src')){
var videoE = createVideoElement(elm['video_src']);
videoE.addEventListener("loadeddata", () => {
videoE.width = videoE.videoWidth;
videoE.height = videoE.videoHeight;
elm.setElement(videoE);
elm.getElement().play();
});
util.requestAnimFrame(function render() {
canvas.renderAll();
util.requestAnimFrame(render);
});
}
}
}
//load saved json data to canvas, then process to display video element.
var canvas = canvas.loadFromJSON(json_data).then(canvasLoaded);
Tip: In method canvasLoaded
above, we check if object has video_src
, then create a html video element then using setElement
method to mount it to existed image element we added before, so all saved properties is not changed.
References
Disclaimer: The opinions expressed in this blog are solely my own and do not reflect the views or opinions of my employer or any affiliated organizations. The content provided is for informational and educational purposes only and should not be taken as professional advice. While I strive to provide accurate and up-to-date information, I make no warranties or guarantees about the completeness, reliability, or accuracy of the content. Readers are encouraged to verify the information and seek independent advice as needed. I disclaim any liability for decisions or actions taken based on the content of this blog.