Skip to content

Instantly share code, notes, and snippets.

@cmawhorter
Created June 26, 2014 04:54
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cmawhorter/a4f9b3638018f000f174 to your computer and use it in GitHub Desktop.
Save cmawhorter/a4f9b3638018f000f174 to your computer and use it in GitHub Desktop.
The only way I could generate real-time thumbnails of a fabricjs canvas
// see mawhorter.net for full post
// Put this in an after:render event handler.
// Be warned: Ripped out of working code and renamed variables without testing.
var fabricMain = new fabric.Canvas('main')
, fabricThumb = new fabric.Canvas('screenshot')
, ctxThumbnail = $('canvas#thumbnail')[0].getContext('2d');
// first things first, let's clear the previous thumb contents
fabricThumb.clear().renderAll();
// get all the fabric.Objects added to fabricMain
var objs = fabricMain.getObjects();
// and this is where it starts getting weird...
// getObjects() works great as long as you have one or less objects selected
// if you have more, your selection turns into the "ActiveGroup".
// what does that mean? pretty much those objects are now useless.
// so we have to check and see if there is an ActiveGroup
var hasActiveGroup = fabricMain.getActiveGroup();
// now we can step through all the objects we retrieved earlier
for (var i=0; i < objs.length; i++) {
// don't use objs[i].clone() -- it won't work... no idea why
var obj = fabric.util.object.clone(objs[i]);
// if there is an active group and this obj is active, assume
// it's in the activegroup (is this a safe assumption? no idea.)
if (hasActiveGroup && obj.get('active')) {
// one of the things an activegroup does is render all the fabric.Objects
// coords in it inaccurate. they've now all been turned into offsets
// (relative to the active groups x/y)
// ...so let's fix that
obj.set({
active: false // make sure it doesn't get added selected
, left: hasActiveGroup.left + obj.get('left') // adjust offsets
, top: hasActiveGroup.top + obj.get('top')
});
}
fabricThumb.add(obj); // add it to our thumbnail canvas
}
// now, let's be absolutely sure nothing is selected by
// deactivateAll(), and then of course renderAll after, otherwise it won't work
fabricThumb.deactivateAll().renderAll();
// side rant... you have to call "renderAll" ALL. THE. TIME. i'm assuming this was
// done for perf reasons, but it failed. it has become.. 1) do something in
// fabric. 2) did it work? no? try calling renderAll (and setCoords if renderAll didn't work)
// get the element for our fabricThumb, so that we can copy it
var srcCanvas = document.getElementById('screenshot');
// all the shtuff for context.drawImage: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D#drawImage()
// you don't have to be this fancy...
var dx = 0
, dy = 0
, dw = 100
, dh = 120
, sx = 200
, sy = 0
, sw = 200
, sh = 240;
// clear out previous contents
ctxThumbnail.clearRect(0, 0, 100, 120);
// this copies a small portion of our fabricThumb canvas, resizes it and puts it in our thumbnail canvas
ctxThumbnail.drawImage(srcCanvas, dx, dy, dw, dh, sx, sy, sw, sh);
@anbiniyar
Copy link

Thank you for taking a stab at this issue. Seems like a lot has changed in two years.

For future wanderers, I was able to solve this issue by simply using http://fabricjs.com/docs/fabric.StaticCanvas.html#toDataURL. It seems fairly straight forward and it doesn't show the controls or anything. Just a straight thumbnail.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment