4

I'm looking to create a system where users create an image in canvas on their browser (with the help of paper.js or processing.js etc) and be able to print a large (up to A3, 300dpi ideally) size representation of what they have created in canvas.

Obviously exporting images straight from the canvas element in the users browser I'm limited to screen size and resolution etc.

So I've looked into the solution of momentarily scaling up the canvas element when the users saves and capturing the image data at the larger size. This could be a solution but I'm pretty sure file size would get out of hand pretty quickly at larger sizes.

I haven't used Node.js very much but was wondering if anyone with experience would know if Node could achieve this and if it would be a better solution and briefly how I'd go about it?

markstewie
  • 9,237
  • 10
  • 50
  • 72
  • This can perhaps give some input on the topic: http://stackoverflow.com/questions/17025603/what-is-the-best-practice-to-export-canvas-with-high-quality-images/17035046#17035046 –  Apr 11 '14 at 04:31
  • *So I've looked into the solution of momentarily scaling up the canvas element when the users saves and capturing the image data at the larger size.* - what do you exactly mean by it? – artur grzesiak Apr 11 '14 at 08:56

1 Answers1

14

I see two ways to achieve what you want :

  • use an oversized canvas, that you scale with css.
    For instance, you can have a 1000X1000 canvas, that you show within a 200pxX200px smaller view.

    <canvas          width=1000   height=1000
            style = 'width:200px; height:200px;'     id='cv'>  
    </canvas>
    
  • use a small canvas for display on screen, and really draw on a backing canvas, that you reproduce on the view canvas at each change.

Both solution cannot solve the issue that mouse coordinates are integer, so to implement a 'pixel perfect' location of object you'll have to implement some kind of zooming. Second solution might be simpler for this.

To retrieve the mouse coordinates, with css scaling do not forget to multiply them by the scale, and in case 2, by the scale you decided.

// formula to get the css scale :
var cssScaleX = canvas.width / canvas.offsetWidth;  
var cssScaleY = canvas.height / canvas.offsetHeight;
// then mouse coords are to be multiplied by the scale : 
//                                       mouse.x *= cssScaleX;

I tried quickly both solutions, and i was quite surprised to see that css solution is very slow (in both Ch and FF), and it seems faster to copy a back canvas than to have css doing it. Maybe it depends on some quality settings, but it seems solution 2 is both more flexible and faster.

first css version is here (move mouse to draw 10X10 rect) :

http://jsbin.com/kegohufu/1/

second back canvas + copy version is here (move mouse to draw 10X10 rect) :

http://jsbin.com/qomiqoqi/1/

GameAlchemist
  • 18,995
  • 7
  • 36
  • 59
  • 1
    Thanks very much for your answer! Definitely helps. – markstewie Apr 13 '14 at 00:47
  • Thanks! I went by the second way, but I have problem with the rotation of the image, get very slow. Do you have some idea? ( I opened another question http://stackoverflow.com/questions/28497910/rotate-high-res-image-in-html5-canvas) In any case, thanks for share your knowlegment ;) – HEDMON Feb 13 '15 at 10:53
  • Browsers should just convert the canvas drawing calls straight into PostScript vector graphics when printing. – Andy Oct 31 '15 at 20:54