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.
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
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/
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?
I've got a container with a video element and a mask image over it, that looks like the following:
<div id="container">
<img id="mask" src="/images/mask.png" width="1078" height="1508" />
<video autoplay="" id="video"></video>
</div>
As you guys can see the mask image is 1078px width and 1508px height. The video element is also 1078px width, but just 807px height (it doesn't have to be longer).
The canvas element haves the same width and height. When I try taking a snapshot of the video and draw that snapshot and a copy of the mask image to the canvas both elements are stretched way outside the canvas bounding.
var context = canvas.getContext('2d');
// Draw video
context.drawImage(video, 0, 0);
// Get mask image and draw mask
maskObj.src = document.getElementById("mask").src;
context.drawImage(maskObj, 0, 0);
I know I can pass more parameters trough the drawImage() function, but I do not know what that other parameters are exactly for. This article says you can just pass width and height as a integer. But if I do the following:
context.drawImage(video, 0, 0, 1078, 807);
context.drawImage(maskObj, 0, 0, 1078, 1508);
It is still draws the elements way outside the canvas bounding.
Can't really find out what I'm doing wrong so all the help is appreciated.
Example;
The only way it should happen is if you set the size of your canvas with css. Try to change the size of your canvas with the html attributes, or maybe add this :
canvas.width = 1078;
canvas.height = 1508;
var context = canvas.getContext('2d');
The resolution of a canvas only depends on those attributes. The css width and height just stretches it.
all you got to do is to get the video dimensions and set your canvas width and height to those values like below:
var video = document.getElementById('video');
canvas.height = video.videoHeight;
canvas.width = video.videoWidth;
var context = canvas.getContext('2d');
context.drawImage(video, 0, 0, canvas.width, canvas.height);
Given a PNG in a web context with some transparent pixels and some non-transparent pixels, is there a way in Javascript to determine if a user has clicked on a non-transparent pixel? A webkit-only solution would be perfectly acceptable.
1) Create HTML5 canvas of same size as your image
2) Get Canvas's context, drawImage(yourImage, 0, 0)
3) d = context.getImageData(0, 0, w of img, h of img)
4) d.data[(y*width+x)*4+3] for the alpha
canvas = document.createElement("canvas"); //Create HTML5 canvas: supported in latest firefox/chrome/safari/konquerer. Support in IE9
canvas.width = img.width; //Set width of your rendertarget
canvas.height = img.height; // \ height \ \ \
ctx = canvas.getContext("2d"); //Get the 2d context [the thing you draw on]
ctx.drawImage(img, 0, 0); //Draw the picture on it.
id = ctx.getImageData(0,0, img.width, img.height); //Get the pixelData of image
//id.data[(y*width+x)*4+3] for the alpha value of pixel at x,y, 0->255
I know these things are out of fashion these days, but HTML image maps are still valid, and can accomplish adding hit targets to nearly-arbitrary shapes within an image. If you don't actually want to reload another page on click, you could probably change the anchor in the URL with this technique and pick up the change with a Javascript interval.
Canvas is the way to go for this purpose. But also remember that older internet explorer versions will not be capable of the getImageData() function. Even if you include excanvas.
I made a small jquery plugin exactly for this purpose, maybe it will help you solving your problem without to completely reinvent the wheel. http://www.cw-internetdienste.de/pixelselection/