I am clearing canvas using ctx.clearRect(0,0,canvas.width,canvas.height) and just for debug I redraw after 2 seconds, on second time I redraw all content instead of lines. but it still showing one line on canvas which I draw lastly.
I have had problems before clearing a canvas by creating a full sized rectangle, so instead I use this more effective approach you may find helpful:
function clearCanvas(){
var context = canvas.getContext("2d");
context.clearRect(0, 0, canvas.width, canvas.height); //default
var w = canvas.width;
canvas.width = 1;
canvas.width = w; //Also change and re-apply canvas width
return;
}
Would you be able to post your full code?
Related
let me explain you what I do. I need to draw bigg image near to 5000px to 2688px. So I can't draw whole image because in browser it's too long. I decided to add scroll bar to see whole image. The following script allows me to draw a part of canvas
var img = new Image();
img.onload = function(){
canvasW = 5376
canvasH = 2688
ctx.drawImage(img, 0,0, canvasW, canvasH);
};
img.src = "image.png";
Now imagine I want to apply effects like blur or brigthness, contrast etc, My canvas will change, so how can I redraw modified canvas (with effect and not the first one.
I tried to check on stackoverflow but the examples is to redraw image from the first one. I mean the drawing is not from a modifed canvas.
I tried to store base64 of my canvas and redraw by using base64 :
var image = new Image()
image.addEventListener('load', function() {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
ctx.drawImage(image, canMouseX, canMouseY, canvasW, canvasH);
})
image.src = bases64[bases64.length - 1]
It doesn't work because by storing base64 there is just a part of canvas that is redraw. If you want more details clone my repo on : https://github.com/wyllisMonteiro/draggingScroll/tree/master
I want to find a solution to redraw a modified canvas
Here is my canvas on jsfiddle:
https://jsfiddle.net/vzrandom/fkho6grf/8/
I'm using simplex-noise.js and dat.GUI to create movement of particles. There is simulated click on canvas every 5 seconds. On click first animation is coming in background and new animation starts.
My problem is that animation on click starts too abruptly. I would like to have some kind of fade in of particles.
It seems like a simple problem but somehow I can't get it how to make fade in of elements that are inside the canvas - not entire canvas himself.
Entire code is on jsfiddle, here is part that handles the click:
function onCanvasClick(e) {
context.save();
context.globalAlpha = 1;
context.fillStyle = Configs.backgroundColor;
context.fillRect(0, 0, screenWidth, screenHeight);
context.restore();
simplexNoise = new SimplexNoise();
}
You need to render to an offscreen canvas.
Just create a second canvas
var canvas2 = document.createElement("canvas");
canvas2.width = canvas.width;
canvas2.height = canvas.height;
var ctx2 = canvas.getContext("2d");
Then for all your drawing calls use the background canvas 2dContext
To do the fade just render that canvas onto the display canvas setting alpha to make it fade.
The function called by requestAnimationFrame is passed a hi resolution time as the first argument. The code below is for the update function. Note that if you are using a polyfill for requestAnimationFrame you should use one that matches the standard.
var fadeTime = 1; // one second
var fadeTimeStart = undefined; // when undefined then this indicates start of fade
function update(time){
// render your particles to offscreen canvas
if(fadeTimeStart === undefined){ // get the current time as start
fadeTimeStart = time;
}
// get amount of fade
var fTime = (time - fadeTimeStart) / fadeTime;
// is it fading
if(fTime < 1){ // yes
ctx.globalAlpha = fTime;
clearRect(0,0,canvas.width,canvas.height); // clear last rendered scene
ctx.drawImage(canvas2,0,0); // draw the offscreen canvas
}else{
// you may or may not have to clear the canvas
ctx.drawImage(canvas2,0,0); // if no fade and assuming canvas is opaque then just draw the canvas onto the display.
}
requestAnimationFrame(update);
}
Then in the click event to start a new fade in just set the fadeTimeStart = undefined and it will start a new fade in.
I don't know if this is the effect you want to achieve, but you might get away with clearing the canvas a little on each iteration by filling it with a semi-transparent color in update function, instead of clearing it completely on each click.
See my fork here: https://jsfiddle.net/640e32ua/
Main change is changing Configs.backgroundColor to something semi-transparent and adding these two lines to update:
context.fillStyle = Configs.backgroundColor;
context.fillRect(0, 0, screenWidth, screenHeight);
I am creating a drawing app, and using this function to download the canvas image.
function download() {
var dt = canvas.toDataURL('image/png');
this.href = dt;
};
I want to set the canvas background to white before downloading because on mobile, the images are very distorted and black. Any ideas?
You may want to draw a white rectangle the size of the entire canvas, beneath the actual content of the canvas.
// get the canvas 2d context
var ctx = canvas.getContext('2d');
// set the ctx to draw beneath your current content
ctx.globalCompositeOperation = 'destination-over';
// set the fill color to white
ctx.fillStyle = 'white';
// apply fill starting from point (0,0) to point (canvas.width,canvas.height)
// these two points are the top left and the bottom right of the canvas
ctx.fillRect(0, 0, canvas.width, canvas.height);
You have to apply these lines before generating your toDataUrl() stream.
Idea taken from: http://www.mikechambers.com/blog/2011/01/31/setting-the-background-color-when-generating-images-from-canvas-todataurl/
After running this code:
var inventoryCanvas = document.getElementById("inventoryCanvas");
inventoryCanvas.width = width2;
it executes properly, however the canvas disappears when I run it.
Does anyone know the reason for this?
There is no way to stop this as it is expected behavior, I had a similar problem and solved it by creating a hidden buffer canvas. Before resize you can copy your original canvas to this buffer, resize the old canvas then redraw from the buffer.
Heres a quick fiddle demonstrating it:
http://jsfiddle.net/5keo7g2r/
var canvas = document.getElementById('canvas'),
buffer = document.getElementById('buffer'),
context = canvas.getContext("2d"),
bufferContext = buffer.getContext("2d");
bufferContext.drawImage(canvas, 0, 0); //Make a copy of the canvas to hidden buffer
canvas.width = 50; //Resize
context.drawImage(buffer, 0, 0); //Draw it back to canvas
I've got a user resizeable window and canvas, I copy the canvas before sizing the canvas, then redraw it back, which works well when the user resizes the window bigger.
imageData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
canvasWidth = winW-20; // set new width
canvasHeight = winH-66; // set new height
canvas.setAttribute('width', canvasWidth);
canvas.setAttribute('height', canvasHeight);
ctx.putImageData(imageData, 0, 0);
Making the canvas smaller clips the data, how can I copy the canvas data on to a larger temporary plane for redraw big or small without clipping.
Use a secondary canvas element you create dynamically:
var tempCanvas = document.createElement('canvas'),
tempCtx = tempCanvas.getContext('2d');
tempCanvas.width = canvas.width;
tempCanvas.height = canvas.height;
tempCtx.drawImage(canvas, 0, 0);
... resize
ctx.drawImage(tempCanvas, 0, 0, canvas.width, canvas.height);
Just note that many of these operations will eventually reduce the quality so my recommendation would be that you use an off-screen canvas as above but you keep it at a single size through its life-time and then draw to that instead of the on-screen one, and update the on-screen one after each main operation. If this is practically feasible depends of course on your project.
The other approach is to store all draw operations as (custom) objects or something similar and then redraw the whole canvas in scale after each resize. This allow you to keep the data in vector format and get better quality when rasterized to canvas.