Dorki
Dorki

Reputation: 1207

How to clean canvas and re-draw again

So I made a simple example that if u click on a canvas, it keep drawing random lines, and it also pushes the current state into _history variable, and once you clicked on a "get previous" button, it pop up the previous state.

var _history = []
var canvas = document.getElementsByClassName('canvas')[0];
var ctx = canvas.getContext('2d');
			
canvas.addEventListener('click', generateLine, false);

var btn = document.getElementsByClassName('btn')[0];

btn.addEventListener('click', loadPrevious, false);

var img = document.getElementsByClassName('img')[0];


function generateLine() {
    ctx.beginPath();
    ctx.moveTo(0, 0);
    ctx.lineTo(Math.random() * 200, Math.random() * 200);
    ctx.stroke();
	
	var value = canvas.toDataURL();
	console.log(value);
	_history.push(value);
}

function loadPrevious() {
	_history.pop();
	var value = _history.pop();
	
	img.src = value;
	
	// clear data
	ctx.clearRect(0, 0, canvas.width, canvas.height);
	
	// re-draw
	ctx.drawImage(img, 0, 0);
}
.canvas {
	width: 100px;
	height: 100px;
	border: 1px solid black;
}

.app {
	text-align: center;
}

img {
	display: none;
}
<div class="App">
	<img alt="test" class="img" />
	Click on the image to draw random: <br />
	<canvas class="canvas"></canvas>
	<br />
	<button class="btn">load previous state</button>
</div>

The _history array is good, and when I pop a state it returns a good URI image, but I think the part of "loading" the state to the canvas is broken.

How can I solve that?

Upvotes: 0

Views: 422

Answers (1)

Andrew Halpern
Andrew Halpern

Reputation: 514

Calling the image in memory is asynchronous so you need to wrap it in a img.onload function.

var _history = []
var canvas = document.getElementsByClassName('canvas')[0];
var ctx = canvas.getContext('2d');

canvas.addEventListener('click', generateLine, false);

var btn = document.getElementsByClassName('btn')[0];

btn.addEventListener('click', loadPrevious, false);

var img = document.getElementsByClassName('img')[0];


function generateLine() {
    ctx.beginPath();
    ctx.moveTo(0, 0);
    ctx.lineTo(Math.random() * 200, Math.random() * 200);
    ctx.stroke();

    var value = canvas.toDataURL();
    console.log(value);
    _history.push(value);
}

function loadPrevious() {
    _history.pop();
    var value = _history.pop();

    img.src = value;

    // clear data
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    // re-draw
    img.onload = function() {
      ctx.drawImage(img, 0, 0);
    };
    
}
<style>
.canvas {
    width: 100px;
    height: 100px;
    border: 1px solid black;
}

.app {
    text-align: center;
}

img {
    display: none;
}
</style>

<div class="App">
    <img alt="test" class="img" />
    Click on the image to draw random: <br />
    <canvas class="canvas"></canvas>
    <br />
    <button class="btn">load previous state</button>
</div>

Upvotes: 1

Related Questions