I need help trying to represent lines in a canvas. The lines are drawn with the mouse and my problem comes when I try to make the canvas responsive.
When I am drawing lines in the desktop you don't really see the distortion, but when the canvas is loaded in a mobile and I draw an horizontal line, turns out that it keeps the "round shape" of the point, but in vertical lines the point narrows on the sides so the line gets narrower. Because is difficult to explain I show up a picture where I can ilustrate you better:
I also include an example of the code I am using, so you have a better idea of what I am talking about:
//getting the mouse coords
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
scaleX = canvas.width / rect.width, /*relationship bitmap vs. element for X*/
scaleY = canvas.height / rect.height; /*relationship bitmap vs. element for Y*/
return {
x: Math.round((evt.clientX - rect.left)*scaleX),
y: Math.round((evt.clientY - rect.top)*scaleY)
};
}
and in the context of the canvas I say:
ctx.lineJoin="round";
The full code is here:
https://jsfiddle.net/rhwcbwwL/20/
Thank you in advance!!
Related
I have a canvas that is stretched out since I am making a sandbox game. I can not use the normal method of detecting the pixel on the page a canvas is clicked because I need to know which stretch pixel was clicked. Hopefully this makes sense?
All you have to do is scale the position based on your current canvas size and original canvas size.
function scaleCursorPoint(int mouseX, int mouseY, ctx) {
return {
x: mouseX * (ctx.canvas.width / ctx.width),
y: mouseY * (ctx.canvas.height / ctx.height)
};
}
ctx (which is gotten with canvas.getContext('2d') has the width of the original unstretched. ctx.canvas gets the original canvas DOM element. ctx.canvas.width is the size of the DOM element (the stretched size).
Divide the two and you get the scale value. Then just multiple that scale value with the points you got and you're good
I need to rotate an image in a canvas and simultaneously resize it to make sure that the corners of the canvas does not remain empty. The solution should be something similar to what do aviary in the "Crop, Resize & Rotate" example.
I think the solution is to combine the functions of rotation and resize of canvas, but I can not find any concrete solution to the problem and I didn't find any exaustive example on the web.
Any advice would be helpful
Thanks
I have not had a look at the example you have given but I gave a detailed answer on the problem of fitting a rotated image onto a canvas so that there is no blank spaces.
There is some math involved (go figure) but it is just basic trigonometry and I provided an explanation of how its all done. There are two solutions, one that finds the min scale that will fit the canvas for any rotation and the other the will find the min scale to fit the canvas for a particular rotation.
It is assumed that the image is centered, if not there is an easy way to adapt the code provided by supplying an abstract canvas size so that the rotated image is centered on that abstract canvas.
So if your center of image is at x = 100, y = 100 and the canvas is canvasWidth = 300, canvasHeight = 300 then just use an abstract size of absCanvasWidth = (canvasWidth - x) * 2; and then the image at x = absCanvasWidth/2 do the same for height. That will fit the rotated, translated image to fill the canvas.
The answer with the code can be found for the question After rotate, draw Image at correct position
Here's some code that might help you. This shows how to rotate an image 90 degrees clockwise, then scale it to fit in the original canvas space.
window.onload = function() {
var img = document.getElementById("myImage");
var rotatedCanvas = document.getElementById("myRotatedCanvas");
var width = rotatedCanvas.offsetWidth;
var height = rotatedCanvas.offsetHeight;
// draw the original image
var ctx = document.getElementById("myCanvas").getContext("2d");
ctx.drawImage(img, 0, 0);
// draw the rotated image
ctx = rotatedCanvas.getContext("2d");
ctx.rotate(90 * Math.PI / 180);
// the last two parameters scale the image
ctx.drawImage(img, 0, -width, height, width);
};
img {
display: none;
}
canvas {
border: 1px black solid;
}
<img src="http://imgur.com/UeMOrix.gif" id="myImage"/>
<canvas id="myCanvas" width="400" height="150"></canvas>
<br>
<canvas id="myRotatedCanvas" width="400" height="150"></canvas>
I'm implementing drawing on canvas with html5 and javascript.
If I dont set canvas width and height manually ( leave it default) , my drawing works good.
However, when I set canvas size either from css or javascript, my drawing looks like distorted. The line starts drawing little bit away from the line, and the line looks distorted.
Here is the code for mousedown event.
if (mouseDown)
{
previousX = currentX;
previousY = currentY;
currentX = e.clientX - canvas.offsetLeft;
currentY = e.clientY - canvas.offsetTop;
ctx.beginPath();
ctx.moveTo(previousX, previousY);
ctx.lineTo(currentX, currentY);
ctx.strokeStyle = color;
ctx.lineWidth = y;
ctx.stroke();
ctx.closePath();
}
You must set the size of canvas using its correct properties/attributes.
Canvas is an element with a bitmap. If you use CSS or style you will only scale the element, not the bitmap. The result is a blurry image.
Set correct size by doing this (and CSS is not necessary normally):
<canvas width=800 height=800></canvas>
or in JavaScript:
canvas.width = 800; // example size
canvas.height = 800;
If you use CSS, either using a rule or the style attribute in the element, to scale the canvas you will only scale a 300x150 pixel bitmap to something else which will give bad quality. Always scale the bitmap and then redraw (as the canvas will be cleared).
The canvas API is only for drawing in raster. That's why it doesn't retain clarity when it resizes. It's to be expected.
If you'd want to produce vector, you'd have to use SVG (Scalable Vector Graphics) instead. But the SVG doesn't support drawing. Producing SVG is basically through XML, so it's not flexible the same way as the canvas API is.
Here's a library that will help you accomplish drawing to the canvas in vector:
http://paperjs.org/
"Paper.js is an open source vector graphics scripting framework that runs on top of the HTML5 Canvas."
Here's another thread which enumerates more options:
HTML5 Canvas Vector Graphics?
I am making for school a star catching game.
I want the enviroment to change dynamicly so that when i resize browser windows the game will resize with it.
I got the following running code:
http://jsfiddle.net/xigolle/yA74f/
The only problem with that is that the mouse isn't center on the witch.
What is the best way for me to get the mouse on the center on every size?
The problem lays for sure in this part:
ctx.drawImage(img, this.x, this.y, canvas.width/10, canvas.height/10);
The size of the browser window i get from a event listener who activates when i resize.
And the value is put in canvas.width and canvas.height.
I hope you guys can help me :)
For any more question or unclearance please ask :)
You have two problems
The first is your use of drawImage
ctx.drawImage(img, this.x, this.y, canvas.width/10, canvas.height/10);
This is going to rescale the witch image in a way that does not keep the proportions, which is why when resizing the window the witch either squishes or expands
You should resize the image based on a ratio of the original image size and original canvas size. Then use that ratio times the new canvas size to get the right image size.
//Original canvas width/height
var initialWidth = 500, initialHeight = 500;
var initialImgWidth = 120, initialImgHeight = 65;
var wRatio = initialImgWidth/initialWidth, hRatio = initialImgHeight/initialHeight;
...
ctx.drawImage(img, this.x, this.y, canvas.width*wRatio, canvas.height*hRatio);
Now that we have the image resize resolved now we can center the image on the mouse
Now to center you have to take the mouse x/y and minus each with 1/2 of width/height of the rescaled witch respectively
Witch.x = event.pageX-((canvas.width*wRatio)/2);
Witch.y = event.pageY-((canvas.height*hRatio)/2);
JSFiddle
EDIT
My rescale calculations were wrong, for now to scale the image for now just scale it by its original dimensions
var imgWScale = initialImgWidth/2;
var imgHScale = initialImgHeight/2;
...
ctx.drawImage(img, this.x, this.y, imgWScale,imgHScale);
...
Witch.x = event.pageX-(imgWScale/2);
Witch.y = event.pageY-(imgHScale/2);
Just remember to center just get the images width/height and divide in half and then take that from the mouse coordinates.
I'm working on a canvas project which includes some drag and drop functionality for some bitmap images on the canvas. I'm having trouble selecting images after the canvas has been resized.
At the minute what i've got is working fine for when the canvas is at it's default dimensions.
I'm drawing all my graphics to a canvas then drawing that image to another canvas and displaying that.
So I want to be able to 'select' an image on the canvas.
Obviously I do this by comparing the mouse coordinates with the coordinates of the object.
mouseX = mouse.x - window.offsetLeft; //I'm accounting for the offset
I'm then multiplying the mouse coordinates by (theVisibleCanvas.width / originalCanvas.width) to account for the scaling of the canvas.
This all works fine for when the window is maximized ( the default dimensions) but once I've resized the window the coordinates start getting further and further out.
Can anyone point out any steps involved in translating mouse coordinates in relation to the canvas resizing?
The line of you provided has little to do with canvas as it uses the offset of the window rather than the offset of the canvas.
To get the coordinates from the mouse adjusted to canvas you can use something like this:
function getXY(canvas, event){
var rect = canvas.getBoundingClientRect(), /// get absolute rect. of canvas
x = event.clientX - rect.left, /// adjust for x
y = event.clientY - rect.top; /// adjust for y
return {x:x, y:y}; /// return object
}
Now you can call this:
var pos = getXY(myCanvasElement, theEvent);
console.log(pos.x, pos.y); /// use the pos object for something
Of course, myCanvasElement is a reference to your actual canvas element and theEvent provided by the callback.