0

I need resize and redraw canvas, on mouse drawing.
I did demo, but this is not works, all time when i resize canvas it is clean all data

I tried different options like:

  • temporary canvas
  • toDataURL

But without success

user1058043
  • 71
  • 1
  • 1
  • 7

1 Answers1

1

Your fiddle is working, i thing the only thing you missed is that resizing a canvas does clear it, so in the provided fiddle you clear it in fact on every single move of your mouse.

Edit : OK i think i understood your issues.

1) On resizing, you loose the content.
2) On resizing you loose current path, so you have to re-initiate a path drawing.
3) If you create a canvas on each mouse move, memory consumption will reach mountains and your app won't be reactive.
4) since the re-draw happens on a mouse move and not on a requestAnimationFrame, the whole thing will look quite hugly if you just do the full redraw on mouse move.

So i updated this fiddle so that it fixes all those issues :

try it here : http://jsfiddle.net/gamealchemist/JHr2P/78/

  • i handle a temp canvas that will double it size when not big enough (so it changes much less often size. use a factor less than 2X, or another caching strategy if you think appropriate). So the memory use will not be that big.
  • i save the image to temp canvas after stroking the line.
  • ( the image is store to localContent only on mouse up to reduce overhead ).
  • then i resize + redraw from the temp canvas.
  • then i re-initiate a line draw.
  • all of the above is done within a requestAnimationFrame to avoid hugly flickering.

store / restore code :

var _storeCanvas =  document.createElement('canvas');
var _storeCtx = _storeCanvas.getContext('2d');

function storeInTempCanvas() {
   if (_storeCanvas == null || _storeCanvas.width < canvas.width || _storeCanvas.height )    {   
    _storeCanvas.width = 2 * canvas.width; 
    _storeCanvas.height = 2 * canvas.height;
   }
   _storeCtx.drawImage(canvas, 0, 0);
}

function restorefromTempCanvas() {
    ctx.drawImage(_storeCanvas, 0, 0);
}

updated mouse move code :

var draw = {
      // ... same mousedwon code...

    mousemove: function(coordinates) {
        if (this.isDrawing) {
            requestAnimationFrame ( function() {
                        ctx.lineTo(coordinates.x, coordinates.y);
                        ctx.stroke();            
                        storeInTempCanvas();
                        canvas.width+=1;
                        restorefromTempCanvas();
                        ctx.beginPath();
                        ctx.moveTo(coordinates.x, coordinates.y);
            } );
       }
    },

 //... same mouseup code.


}  
GameAlchemist
  • 18,995
  • 7
  • 36
  • 59
  • Can you please update my example? Because i don't understand where my mistake. I see only if i comment this row -> ctx.canvas.width += 1; , then drawing works good, except of resizing, if i uncomment it then resizing works but not drawing... – user1058043 Dec 05 '13 at 15:04
  • if what you seek is resize when window change, i started this (http://jsfiddle.net/JHr2P/75/) . Otherwise if you want to increase canvas size always, it's quite straightforward : draw, store the latest image then re-draw it scaled on each move. – GameAlchemist Dec 05 '13 at 15:13
  • Thanks, but this exactly what i say, if comment ctx.canvas.width += 1; drawing works. But canvas not resizing :( i need resize windows all time that user press and move mouse. And save (show) what user draws. And i tried draw-store-redraw thru temp canvas, via toDataUrl ... not working, maybe i did something wrong ... – user1058043 Dec 05 '13 at 15:15
  • without resizing, show on start position with start size, only resize canvas – user1058043 Dec 05 '13 at 15:18
  • Interesting exercise! How about creating a large oversized canvas to start with and display a smaller "viewport" by containing the oversized canvas in a smaller div container with scrollbars? – markE Dec 05 '13 at 18:55
  • At first thanks, this is exactly what i need. But i found strange behaviour, if i add some limit in the canvas for resizing (it means only in specific area resize canvas, for example if(x > 400) - http://jsfiddle.net/JHr2P/79/) then color of line not the same ... Do you know why and how to solve? Thanks – user1058043 Dec 07 '13 at 15:37
  • And also, if i _quickly_ draws circle before this limit (for example x = 400), then circle seems more smooth, and if i draw _quickly_ circle in new (extends) section then circle seems more angular, probably this is because additional works on creating new canvas copy/paste and etc. Do you know how avoid it? – user1058043 Dec 07 '13 at 17:16
  • 1
    You're welcome. For your first issue : when not resizing, the line keeps being redrawn from the start each time. When resizing, we draw only one segment each time. So the antialiasing of the line keeps reinforcing on each draw when not resizing, leading to a wider line. If you draw only one segment each time wether resizing or not, the behaviour will be consistent. See here : http://jsfiddle.net/gamealchemist/JHr2P/80/ – GameAlchemist Dec 07 '13 at 17:28
  • the second issue is a performance issue. You can improve it by creating less often a canvas (now, each increment creates a new one) you can double the size, just add 100px, ... or decide of a maximum canvas size, so you allocate only once. This make sense anyway, window size is a logical limit. i tried, it improves things. Then cache the div and its size instead of walking the dom. it improves also. Then i warmed up the mouse handling functions, (improves also). see http://jsfiddle.net/gamealchemist/JHr2P/81/ – GameAlchemist Dec 07 '13 at 17:41
  • For first issue, looks great. Again thanks you very much. For second, except of wrong offset, circle seems more ugly than in previous version – user1058043 Dec 07 '13 at 17:55
  • 1
    version 81 was better for me with latest Chrome... ?? Anyway i think the next step for performances is to have a fixed canvas of which you show only a part of itself (a viewport), and grow on resize. This implies some little changes but will lead to better performances. Try the changes of version 81 and keep the useful ones. – GameAlchemist Dec 07 '13 at 18:52
  • Strange, i will check. Thanks you! – user1058043 Dec 07 '13 at 18:59