Different canvas sizes when using drawImage(canvas,0,0) - html

I have 2 canvas elements these getting its height from a parent div.
var canvas = document.getElementById("canvas");
var canvas2 = document.getElementById("canvas2");
canvas.width = canvas.width;
canvas.height = canvas.height;
canvas2.width = canvas2.width;
canvas2.height = canvas2.height;
The sizes of the canvas elements are correct in the DOM. Now i get a Problem with the drawImage() function.
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var canvas2 = document.getElementById("canvas2");
var ctx2 = canvas2.getContext("2d");
for(var i = 0;i<len;i++){
!magic drawings!
}
ctx2.drawImage(canvas, 0, 0);
The Problem is it copy the first canvas to the canvas2. When the first canvas is 150px height it only applies 150px of canvas drawing on the second canvas which is 200px height.
Any Idea or suggestion?
Edit
Ok one possible solution, but its not pretty.
ctx2.drawImage(canvas, 0, 0, canvas2.width, canvas2.height);
So the canvas gets resized. Because the width doesn't change it gets stretched regarding to the higher height. so not a perfect solution.

Use the scaling parameters of canvas context to avoid stretching
var scaleFactor=canvas2.height/canvas.height;
ctx2.drawImage(canvas,0,0,canvas.width,canvas.height,
0,0,canvas.width*scaleFactor,canvas.height*scaleFactor);

Related

canvas' size could not display correctly at once

As a frontend starter, I've just started to learn canvas. I'm trying to draw some text. But the size of canvas could not display correctly at once:
My code for creating canvas:
const message = input.value;
let ctx = canvas.getContext('2d')
let metrics = ctx.measureText(message);
let textWidth = metrics.width*2;
canvas.width = textWidth;
canvas.height = 200;
ctx.font = "normal 30px Verdana";
ctx.fillStyle = "#000000";
ctx.fillText(message, 30, 200);
<input id=input value="init message" />
<canvas id=canvas></canvas>
and the result is:enter image description here
as you can see, the message can't be fully displayed, but when I click the button to run function draw() again, then the canvas can be fully displayed:
enter image description here
Could anyone please tell me why this happens.
There are a couple of thing you need to do:
call measureText after you set the font or the width will be incorrect
after changing a canvas dimensions you need to reset the font
On your code you will need to set the font twice.
First before we measure, Second after we change the canvas width and height; I added a console.log to my sample you can see that after canvas change dimensions the font changes to default;
Here is a working sample:
const message = "Hello World"
const font = "normal 30px Verdana"
let canvas = document.getElementById("c");
let ctx = canvas.getContext('2d');
ctx.font = font;
let metrics = ctx.measureText(message);
canvas.width = metrics.width * 2;
canvas.height = 100;
console.log(ctx.font)
ctx.font = font;
ctx.fillText(message, 30, 90);
canvas {
border: 2px solid #0000AA
}
<canvas id="c"></canvas>

Fit image to canvas by width and fit canvas to image new height

How to fit image that bigger that canvas width to canvas(with scale) and then to fit canvas to image height after fit by width.
// Create a variable for the canvas and it's context
var canvas = document.getElementById("imageCanvas");
var ctx = canvas.getContext("2d");
// Initialise an image object
var image = new Image();
// When it loads an image
image.onload = function() {
// Get the canvas' current style
var canvasStyle = getComputedStyle(canvas);
// Get it's current width, minus the px at the end
var canvasWidth = canvasStyle.width.replace("px", "");
// Work out the images ratio
var imageRatio = this.width/this.height;
// Work out the new height of the canvas, keeping in ratio with the image
var canvasHeight = canvasWidth/imageRatio;
// Set the canvas' height in the style tag to be correct
canvas.style.height = canvasHeight+"px";
// Set the width/height attributes to be correct (as this is what drawImage uses)
canvas.width = canvasWidth;
canvas.height = canvasHeight;
// Draw the image at the right width/height
ctx.drawImage(this, 0, 0, canvasWidth, canvasHeight);
};
// Load an image
image.src="https://placekitten.com/g/600/800";
#imageCanvas
{
width: 400px;
height: 400px;
}
<canvas id="imageCanvas" width="400px" height="400px"></canvas>
There you go, shrinks the image to the right width, resizes canvas to the right height. Hopefully the comments explain everything.

How to draw on canvas on mousedown?

I am looking to simply add a dot to the canvas.
I have the following code:
var canv = document.getElementById("myCanvas");
var context = canv.getContext("2d");
var radius = 5;
var putPoint = function(e){
context.beginPath();
context.arc(e.clientX, e.clientY, radius, 0, Math.PI*2);
context.fill();
}
canv.addEventListener('mousedown', putPoint);
I was learning how to do this with a video tutorial. However they were setting the canvas
as the full width/height of the browser window, whereas my canvas is on 400px * 400px and is contained within a div. I think this is the problem.
So my question is are the "e.client" parameters not working because of my canvas being only
a small part of the window?
If so, how can I track the mouse co-ordinates on my canvas?
You must adjust e.clientX/e.clientY by the offset of the canvas element.
Otherwise you're miscalculating the position of your mouse and your dot is probably being drawn outside the bounds of your canvas.
Here's your code modified to take the canvas offset into account.
var putPoint = function(e){
var BB=canvas.getBoundingClientRect();
var offsetX=BB.left;
var offsetY=BB.top;
var mouseX=e.clientX-BB.left;
var mouseY=e.clientY-BB.top;
context.beginPath();
context.arc(mouseX,mouseY,radius,0,Math.PI*2);
context.fill();
}

html5 canvas background image blur and resize

I have an idea of making a canvas the background with an image. The reason why I want the canvas element to be the background is because I would like to blur the image when the user is logged in. I think that would be a nice effect. And since I don't refresh the page I like it to animate a blurring effect. I am going to have multiple questions in here because they all rely on each other.
I have 2 ideas of how to make this. the first one will have a simple div tag with the background image set. then, when the user have logged in - a canvas element will be created by the script with the background image placed as in the div, then blur it and let it fade in over the div tag.
Another way would be to build the canvas element from the beginning and then let the image be set from the beginning.
This is how I make a background image.
var canvas = document.getElementById('bg_canvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
imageObj.onload = function() {
context.drawImage(imageObj, 0, 0);
};
imageObj.src = '2.jpg';
Okay.. thats the easy part.. I need a way to make the height or width in the drawImage function set to auto. if the width is bigger than the height I want the height to be set to auto. I don't want the image to be stretched over the screen. How should I do that?
Now problem number 2. When the user resizes the screen, I would like to resize the image inside the canvas element as well. blurred or not blurred.
i assume it would be set to something like this:
$(document).ready(function() {
winResize();
$(window).resize(function() {
winResize());
}
});
function winResize() {
var canvas = document.getElementById('bg_canvas');
var context = canvas.getContext('2d');
var imageObj = new Image();
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
imageObj.onload = function() {
context.drawImage(imageObj, 0, 0, canvas.height, canvas.width);
};
imageObj.src = '2.jpg';
}
Now I still need the auto mechanism for the height or width of the image.
I am not going to ask for the blur effect, since it should be able to find online somewhere, but what i would like to know is what you would recommend for me to do, when fading in the blurred version. I don't remember there should be a way to fade inside a canvas element, so perhaps I have to duplicate the already existing canvas and then blur and then fade in.
Load the plain image, use a canvas to create a blurred version of the image, then turn that into a real image again for use in an <img> or css background:
function blurImage(imgURL) {
var img = new Image();
img.onload = function() {
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var context = canvas.getContext("2d");
context.drawImage(img,0,0);
/*
code that actually blurs the image goes here
*/
var dataURI = canvas.toDataUrl("image/png");
setBlurredImage(dataURI);
};
img.src = imgURL;
}
with a set handler:
function setBlurredImage(dataURI) {
whateverElement.style.background = "url(" + dataURI + ")";
}
And now you have a background image that is blurred.

HTML5 Canvas lines not having consistent width

I'm drawing a rectangle on HTML5 canvas using the below code:
canvasId = $('#objectData').find('#miImages '+imageId+' .imageContainer canvas').attr("id");
canvas = document.getElementById(canvasId);
context = canvas.getContext("2d");
context.beginPath();
context.rect(coordinateArray[0],coordinateArray[1],coordinateArray[2],coordinateArray[3]);
context.lineWidth = 2;
context.strokeStyle = "DarkBlue";
context.stroke();
The problem is that the two vertical lines are a lot thicker than the two horizontal lines, what is causing this?
EDIT: I have height set at 89 and width set at 802. When I remove the height the rectangle no longer distorts.
I was sizing my canvas with CSS instead of JavaScript which was scaling the canvas rather than actually resizeing it. I fixed this using the below code.
function applyCanvasSize(){
$("#objectData img").on('load', function(){
var theHeight = $(this).height();
var canvasId = $(this).next('canvas').attr('id');
var canvas = document.getElementById(canvasId);
if (canvas.getContext) {
canvas.width = 802;
canvas.height = theHeight;
}
});
}
Kinda late but had the same problem.
Somewhere in my code, I was changing the size of the canvas using style.width and style.height. Directly use width and height instead. Without "px" in the end (thus only accepts pixels ?). You wont get the distortion anymore.