how do make the radius of the circle responsive in canvas element? - javascript

I have a canvas element in which I have drawn a circle. How do I give the responsiveness to the canvas element?
If the width of the browser changes I need to change the radius by some amount, if the height of the browser changes I need to change the radius by some amount.
For that how do I need to calculate the changing ratio?
var canvasWidthRatio = currentDivWidth / initialDivWidth;
var canvasHeightRatio = currentHeight / initialDivHeight;
radius = (I need something here)

It appears you're letting the canvas resize based on its div container. That can introduce a problem.
If you resize the canvas's CSS using different percentages for width & height then the canvas content will distort--it will stretch.
To avoid distortion you must resize the canvas width & height proportionally (by the same percentage). The proportionally resized canvas will not necessarily fill the new div size as it did before.
An alternative:
Resize the canvas element itself & use the scaling transformation to redraw your content
This way you won't need to recalculate your circle's radius or position. You can use the exact same drawing commands that were originally used to draw your circle. The canvas's built-in scaling will do all the recalculations for you!
Get a reference to your canvas & your div container and save the original div size
var divcontainer=document.getElementById('mydiv');
var canvas=document.getElementById('mycanvas');
var context=canvas.getContext('2d');
var originalWidth=divcontainer.width;
var originalHeight=divcontainer.height;
Resize the canvas element to the new div size.
var newWidth=divcontainer.width;
var newHeight=divcontainer.height;
// Notes:
// Resizing the canvas element will clear its content
// This alternative allows the canvas to resize disproportionately
canvas.width=newWidth;
canvas.height=newHeight;
Use context scaling to automatically resize the canvas. Any redrawn content will scale automatically using the same original drawing commands.
// calculate the scaling percentage necessary such that
// new content will fit on the canvas
var scaleFactor=Math.min((newWidth/originalWidth),(newHeight/originalHeight));
// scale the canvas
context.scale(scaleFactor);
// now redraw all content (your circle) using their original sizes & coordinates
// unscale the canvas
// (scaling is cumulative, so this cleans up for the next resizing)
context.scale(-scaleFactor);

try this
var radius = 10; // set default radius to start with
var radiusX = Math.min(currentDivWidth , radius); // set horizontal radius to be atleast as wide as width of div
var radiusY = Math.min(currentDivHeight , radius); // set vertical radius to be atleast as high as height of div
radius = Math.min(radiusX, radiusY); // now set the radius of the circle equal to the minimum of the two values so that it is a perfect circle
context.arc(0, 0, radius, 0, 2*Math.PI, false); // use new radius to draw a brand new circle

try using like this:
radius = Math.min(radiusX, radiusY);// here radiusX and radiusY will be currentDivWidth,currentDivHeight resp.
context.arc(0, 0, radius, 0, 2*Math.PI);
see a better description here:http://www.w3schools.com/tags/canvas_arc.asp

Related

Download original Canvas even after resizing

Click here to view image
Step1) I am drawing an image of 1920*1080 to canvas1 with the drawImage(image,0,0);
setp2) Now i am taking another logo image and drawing it to another canvas called canvas2 with the drawImage(logo,0,0);
I used fabricjs to for logo drag able and re sizable functionalities.
Step3) Then i am drawing canvas1 & canvas2 to another canvas called canvas3 and downloading it.
In this case everything is fine except image is displaying large(1920*1080). for user experience I have used image resize method to reduce the image and displayed in 900*500 canvas. But when i am downloding i should get the original canvas of 1920*1080 with logo. But i am getting 900*500 with logo.
Can any one help in this regards will be greatful
The resizing code
Here real width & real Height are width & height of background image
function ImageResize(){
var d_canvas = document.getElementById('canvas');
var context = d_canvas.getContext('2d');
var background = document.getElementById('background');
var wrh = realWidth / realHeight;
newWidth = d_canvas.width;
newHeight = newWidth / wrh;
if (newHeight > d_canvas.height) {
newHeight = d_canvas.height;
newWidth = newHeight * wrh;
}
context.drawImage(background,0,0, newWidth , newHeight);
}
Use the extended form of drawImage to scale and reposition the logo over the original background image:
Create a 3rd html5 canvas sized to 1920x1080 and draw your step1-image to the 3rd canvas.
Recalculate the Logo coordinates & sizes provided by FabricJS from 900x500 to 1920x1080:
// pseudo-code
// Given FabricJS's position & size of the logo on a 950x500 stage
// Calc the logo's relative position & size vs a larger background
logoX *= 1920/900;
logoY *= 1080/500;
logoWidth *= 1920/900;
logoHeight *= 1080/500;
Draw the logo onto the 3rd canvas using the recalculated position & size
thirdContext.drawImage(
logoImage,
0,0,logoImage.width,logoImage.height,
logoX,logoY,logoWidth,logoHeight
);
Export the 3rd canvas

Rotate image by 90 degrees on HTML5 Canvas

I am having trouble rotating an image using an HTML5 canvas. I suppose that I just have the math wrong, and would appreciate any help in getting this right.
On a mobile device I am capturing a user signature on a 150px by 558px canvas. I am than attempting to create a 558px by 150px image that is just the captured signature rotated 90 degrees. Below is a snippet of the code I've currently come up with. As you can likely surmise, I do not have a good grip on the math going into this. I believe I have the procedure correct, just not the numbers.
What I'm trying to do is:
1) set the center of the canvas to the middle, offsetting by the height and width of my image
2) rotate the canvas by 90 degrees
3) draw the image
4) translate the canvas back.
EDIT: Here's a JSFiddle: http://jsfiddle.net/x9FyK/
var $signature = $("#signature");
var signatureData = $signature.jSignature("getData");
console.log(signatureData);
var img= new Image();
img.onload = function() {
var rotationCanvas = document.createElement('canvas');
rotationCanvas.width = img.height;
rotationCanvas.height = img.width;
var context = rotationCanvas.getContext("2d");
context.translate((rotationCanvas.width/2) - (img.width/2), -(rotationCanvas.height/2) - img.height/4);
context.rotate(Math.PI/2);
context.drawImage(img,0,0);
context.translate(-((rotationCanvas.width/2) - (img.width/2)), -(-(rotationCanvas.height/2) - img.height/4));
var rotatedData = rotationCanvas.toDataURL();
...Handling rotated data here
};
img.src = signatureData;
If I can provide any more information, please let me know.
Thanks in advance for your help,
There are several ways of resetting a transformed (translated+rotated) canvas back to its original state.
Low-Pointer's answer is using context.save to save the context in is original un-transformed state and using context.restore to restore the context to its original state after the drawing is done.
The other way it to undo your transforms in the reverse order that they were performed.
Also, note that context.translate will actually move the canvas origin to the center of the canvas. Since images are drawn from their top-left (not their center), you must offset drawImage by half the image width and height if you want the image centered in the canvas.
Here's and example: http://jsfiddle.net/m1erickson/EQx8V/
// translate to center-canvas
// the origin [0,0] is now center-canvas
ctx.translate(canvas.width/2,canvas.height/2);
// roate the canvas by +90% (==Math.PI/2)
ctx.rotate(Math.PI/2);
// draw the signature
// since images draw from top-left offset the draw by 1/2 width & height
ctx.drawImage(img,-img.width/2,-img.height/2);
// un-rotate the canvas by -90% (== -Math.PI/2)
ctx.rotate(-Math.PI/2);
// un-translate the canvas back to origin==top-left canvas
ctx.translate(-canvas.width/2,-canvas.height/2);
// testing...just draw a rect top-left
ctx.fillRect(0,0,25,10);
this will surely help you >>HTML5 Canvas Rotate Image :)
use some SEPARATE js function for drawing your canvas :
function drawRotated(degrees){
contex_var.clearRect(0,0,canvas.width,canvas.height);
contex_var.save();
contex_var(canvas.width/2,canvas.height/2);
contex_var.rotate(degrees*Math.PI/180);
contex_var.drawImage(image,-image.width/2,-image.width/2);
contex_var.restore();
}
Suppy some angle to any buttonclick function:
$("#clockwise").click(function(){
angleInDegrees+=30;
drawRotated(angleInDegrees);
});

why do figures appear distorted on canvas?

I'm playing around with html5 canvas, and I have came across some strange behaviour. I'm doing pretty basic animation based on these three steps:
I call update() function inside wich I change x and y of the objects.
I clear the canvas with this line of code this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
I redraw all the elements.
This is how I draw the figures:
// drawing a circle
function drawCircle(x,y) {
var rad = 5;
ctx.beginPath();
ctx.arc(x, y, rad, 0, 2 * Math.PI);
ctx.closePath();
ctx.fill();
}
// and a rect
function drawRect(x, y,) {
var width = 60,
height = 10;
ctx.fillRect(x, y, width, height);
}
Now I expect my rectangle to be 60px width and 10px height. I've added a div after the <canvas> tag and set its width and height to 60px and 10px respectively in order to illustrate the discrepancy. As you can see on the picture, obviously my rectangle isn't 60х10. The same apply to the circle. What am I missing here?
here is fiddle
Set the size of the canvas using it's width and height attributes (for tag) or properties (in JS):
<canvas id="..." width=400 height=400></canvas>
in JS:
canvasEl.width = 400;
canvasEl.height = 400;
Don't use CSS as that only affects the canvas element but not its bitmap (consider canvas as an image). The default size of a canvas is 300 x 150 pixels. If you don't change that size it will be stretched to the size you set using CSS. This is why we in general don't recommend using CSS (there are special cases though where CSS is necessary such as print situations, non 1:1 pixel aspect ratios and so forth).
Probably it's because you styled your canvas to a costum with/height. A canvas' default width/height is 150*300 and if you do not scale well you obtain such result as you found.
drawImage(image, x, y, width, height)
This adds the width and height parameters, which indicate the size to which to
scale the image when drawing it onto the canvas.
So to be short you have to scale your drawings.
the Canvas element on MDN
Canvas drawing on MDN

draw rectangle over html with javascript

I know there's a similar question here, but neither the question nor the answer have any code.
What I want to do, is to port this functionality to a 100% Javascript solution. Right now I'm able to draw a rectangle on top of HTML content using PHP.
I scrape a website with CasperJS, take a snapshot, send the snapshot path back to PHP along with a json object that contains all the information necessary to draw a rectangle with GD libraries. That works, but now I want to port that functionality into Javascript.
The way I'm getting the rectangle information is using getBoundingClientRect() that returns an object with top,bottom,height, width, left,and right.
Is there any way to "draw" the HTML of the website to a canvas element, and then draw a Rectangle on that canvas element?
Or is there any way to draw a rectangle on top of the HTML using Javascript?
Hope my question is clear enough.
This is the function that I'm using to get the coordinates of the elements that I want to draw a Rectangle around.
function getListingRectangles() {
return Array.prototype.map.call(document.querySelectorAll('.box'), function(e) {
return e.getBoundingClientRect();
});
You can create a canvas element and place it on top of the HTML page:
//Position parameters used for drawing the rectangle
var x = 100;
var y = 150;
var width = 200;
var height = 150;
var canvas = document.createElement('canvas'); //Create a canvas element
//Set canvas width/height
canvas.style.width='100%';
canvas.style.height='100%';
//Set canvas drawing area width/height
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
//Position canvas
canvas.style.position='absolute';
canvas.style.left=0;
canvas.style.top=0;
canvas.style.zIndex=100000;
canvas.style.pointerEvents='none'; //Make sure you can click 'through' the canvas
document.body.appendChild(canvas); //Append canvas to body element
var context = canvas.getContext('2d');
//Draw rectangle
context.rect(x, y, width, height);
context.fillStyle = 'yellow';
context.fill();
This code should add a yellow rectangle at [100, 150] pixels from the top left corner of the page.

Canvas drawing using mouse coords issue?

I'm drawing to the canvas using the x/y coords of the mouse, but the line that I'm drawing always draws off a little bit, try drawing on here: http://zachrip.net/widgets/onlineedit/index.html (top left) for an example of what I mean. There is no offset so I do not account for it, so I don't know what the issue is?
The problem here is that you are setting the Canvas Element Size through your CSS, but you do not set the Drawing Surface Size.
The default size of the Drawing Surface is 300px by 150px. Since you do not set it, but set the Element Size, the browser scales the drawing surface size to fit the element. The x and y co-ordinates you get through the mouse event correspond to the Element Size, and not the actual Drawing Surface Size. Which is why you get the offset.
Now, the fiddle that I posted earlier merely had you set the size of Drawing Surface, instead of the Element. And that works, but if you'd rather have different Element and Drawing Surface sizes, then you can also do
function scaleCoords(x, y) {
x = x * DrawingSurfaceSize.width/ElementSize.width;
y = y * DrawingSurfaceSize.height/ElementSize.height;
return {x: x, y: y};
}
Example for second method.

Categories

Resources