Printing Canvas Element

Page: 1

Author Post
Member
Registered: Feb 2013
Posts: 11
Hi All,

I am a new Floatbox user and have a question. On one page, I am using Floatbox to show a canvas element with overlapping DIV tags (with text). I am using the JIT library to draw in the canvas element.

When I attempt to use the print feature, the graphics do not print but the text does. When I use the browser's built in feature to print the page, it works well (canvas and overlapping DIVs print correctly).

How would you suggest I get this to print well?

Thanks for your help!

Caleb
Administrator
Registered: Aug 2008
Posts: 3382
Hi Caleb,

I don't think there's a way to get Floatbox's fb.printNode() function to print drawn canvas elements. The printNode function constructs a new window and populates this with html and css copied from the original node. Since the canvas elements in the new window are copies and not the original, they have not been drawn and consist of just the canvas container tags.

There's hope for future Floatbox versions (but not the current release). It is possible to replicate the drawn contents of one canvas element to another and I will see if there's a way to do this for the elements that printNode replicates.

Cheers...
Member
Registered: Feb 2013
Posts: 11
Is there a javascript hook that I can use to populate it myself? Does the beforePrint event occur before or after the copy has been made?

A quick web search yielded this simple routine to clone a canvas element's content.

Caleb
Administrator
Registered: Aug 2008
Posts: 3382
No, there's no hook available. beforePrint is executed before the whole process begins, and can in fact cancel the whole printing thing by returning false. Also, any script elements inside the content to be printed are stripped out of the copy.

I'm actually banging on the code for this right now and have already encountered the stackoverflow article. But thanks!
Member
Registered: Feb 2013
Posts: 11
OK. Thanks for your help.

If I can help with testing, let me know.

Caleb
Administrator
Registered: Aug 2008
Posts: 3382
It is not possible to clone a canvas node across document boundaries such as from the main document to the print window document. IE, and possibly others, will throw an exception on drawImage if the source is foreign. Nor is it possible to use importNode to bring a canvas element and its content into the new document.

A further problem is that canvas emulators for IE pre-9 such as excanvas (which I believe the jit library uses) likely don't support using a canvas element as the source for drawImage.


I've modified the beforePrint callback in the next Floatbox release such that the print window is first populated and the onload event of that window invokes the defined beforePrint function, passing it the print window's window object as a parameter. This allows for pre-processing of the content, such as drawing canvas elements in that content.

An example of this in action can be found at http://floatboxjs.com/misc/canvas. A short walk-through of that simple example might be helpful for your own efforts. Please view source and take a short stroll with me.

There were only two small things I needed to do to get the canvas element rendered before printing.

1) I initially had a drawPicture function which simple drew the canvas element on the main page. I modified that function to accept a 'win' parameter to tell it what window to operate in. The only change that needed to be made to the function was to modify the fb.$() call that fetches the canvas element such that it will use the passed window's document, if provided.

2) I set 'beforePrint:drawPicture' to cause the function to fire when the print window loads.


I'll send you a private message with a link to the 5.7.2 pre-release download. It would be great if you could try it out on your content and see if it meets your needs. (This release also adds -1 handling of the fb.resize() left and top parameters.)
Member
Registered: Feb 2013
Posts: 11
I have tried out the new version you sent to me with mixed results.

1) Resize issue (-1 in the top and left parameters of resize): I am resizing a popup when the user hovers over a div (contained in the popup) -- more specifically, I show two hidden divs and then expand the popup to show them). When I scroll down on the main window so that only part of the popup is shown, hovering over the div will cause the popup to "slide" down off the screen (I would have to scroll down to see it). I have searched my code and cannot find anything I am doing wrong. I have seen this on Safari and Firefox (for OSX) and has been reported to me to happen on IE too.

2) Print Canvas: I am having mixed success. For some reason, it works brilliantly in IE8, but I cannot get it to work anywhere else. This may have something to do with my code so I am still exploring this.

3) Whenever I visit a page that includes floatbox.js in Chrome (on OSX), I receive the following error message:
Uncaught TypeError: Property 'scrollTo' of object [object Window] is not a function (core_572.js:1)
Floatbox popups do not appear on Chrome.

Thanks for your help with these issues. I am pleased to have gotten such a fast response!

Caleb
Administrator
Registered: Aug 2008
Posts: 3382
1) I'm not sure I'm understanding you on this one. When you make the fb.resize call with top and left set to -1, does the top-left corner of the floatbox change position relative to the viewport? If not, then the -1 parameters are doing their job. If the floatbox's top-left corner does move, is it possible for me to see an example online that I can dissect? The -1 parameters are working fine in all my test cases.

2) I suspect you're right that it's a problem in your code. The little canvas example I gave earlier in this thread seems to work fine in all browsers that support canvas. If you want to link me in to the case you are working with I wouldn't mind applying a second set of eyes to it.

3) Really? scrollTo is a callable function of the window object of all browsers since the first ones were carved out of rock, and has been in use in Floatbox for almost as long. This cannot be specific to Floatbox 5.7.2 because the use of scrollTo has not changed with that release. I assume the same error is thrown on my demo page, and all other sites that use Floatbox. Is this correct?
Member
Registered: Feb 2013
Posts: 11
1) Yes, the whole popup slides off the bottom of the screen. See for an example. After the page loads, you should see the Preview popup appear on the right-side of the page (if your screen is wide enough -- otherwise you will need to click the "Show/Hide Preview" icon). Then, scroll down so that the top of the preview popup is partially hidden from view (cut off on the top). Last, move your mouse over the middle of the popup (where it reads "Your New Solution"). The window will start to slide from view.

If you browse the source code, all of the functionality is located in solutionize_popupbox.js. showBuilderPreview is used to setup and display the preview popup and resizeBuilderPreview is called when you hover over the icon.

2) I will investigate this further. I am attempting to take a few shortcuts which may not be working as expected. I just wanted to mention it in case it comes up in other circumstances.

3) Sorry, this was do to a bad extension (one of the few I had installed).
Administrator
Registered: Aug 2008
Posts: 3382
Quote
See for an example.

A little more detail please....
Member
Registered: Feb 2013
Posts: 11
Sorry, forgot the link: Click Here
Administrator
Registered: Aug 2008
Posts: 3382
Wow! That's a cool effect. I should charge extra for that.

I'll slice and dice it tomorrow. Thanks for finding this problem before the public release.
Administrator
Registered: Aug 2008
Posts: 3382
The only call of fb.resize() I can find is fbInstance.resize(-1). I think you want to call fbInstance.resize(0, 0, -1, -1). Parameters are (width, height, left, top) and I believe you want to measure width and height (0) while locking left and top (-1). Or perhaps (-1, 0, -1, -1) to measure just height. Either way, you need the 3rd and 4th parameters to be -1 if you want to lock the current position.

Also, there's a onSolPopupResize function invoked from a number of places, but I can't find where the function is defined so I can't see if it's doing something that interferes.
Member
Registered: Feb 2013
Posts: 11
Look inside the resizeBuilderPreview method. It's called when you hover over the "Your New Solution" div.

resizeBuilderPreview:function()
{
var inst = fb.getInstance('sol_builder_preview');

if(inst)
{
SolutionizePopupBox.TEMP_manualBuilderPreviewResize = false;
inst.resize(-1, 0, -1, -1, false);
}
}
Administrator
Registered: Aug 2008
Posts: 3382
Ok, and where's onSolPopupResize that is attached to the afterResize callback?
Member
Registered: Feb 2013
Posts: 11
onSolPopupResize is not implemented for this page. On some pages, I use this so that the popup content can respond to a manual resize of the popup.
Administrator
Registered: Aug 2008
Posts: 3382
Thanks for your help. I've located the problem. When locking the position, fb.resize reads document coordinates but sets viewport coordinates. The difference is the page scroll amount. For html content, resize iterates 3 or 4 times to handle scrollbars within the content appearing or disappearing as a result of the size change. We see the floatbox drifting down by the vertical page scroll amount at each iteration.

I'm confident that this is the problem and that it is fixed. I'm thinking I should let this release go public now, but if you would like to test a new build first, say so and it shall be so.

Cheers...
Member
Registered: Feb 2013
Posts: 11
I am very willing to try it before it is released publically, but it is entirely up to you.

Caleb

Page: 1