Drawing wtih mouse move make line way of mouse point - javascript

I am making a project where i want to draw on a canvas.
I get the draw method on mouseover and intend to draw a line while following the mouse.
It draws the line perfectly only not on the correct position.
It is made possibly bij JQuery.
var canvas = document.getElementById('myCanvas');
ctx = canvas.getContext('2d');
ctx.beginPath();
$("#myCanvas").mousemove(function(arg)
{ ctx.lineTo(arg.pageX,arg.pageY-80);
ctx.stroke();
});
My html Canvas code:
<canvas id="myCanvas" width="500" height="500">
</canvas>
I hope it is understandable and that somebody can help me. (information the -80 at pageY is because i works better on my screen than)

Here is an optional way of reading mouse position relative to canvas:
$("#myCanvas").mousemove(function(arg) {
var pos = getMousePos(canvas, arg);
ctx.lineTo(pos.x, pos.y);
ctx.stroke();
});
function getMousePos(canvas, e) {
var rect = canvas.getBoundingClientRect(); // absolute position of canvas
return {
x: e.clientX - rect.left, // make x/y relative to canvas
y: e.clientY - rect.top
};
}
Just a side note: We will get issues with that lineTo/stroke combo BTW as the lineTo will add to path and when you stroke, the new line as well as all the other lines added will be stroked. As it is it will become slower the more lines that are drawn and anti-aliased pixels will start to appear. You can use beginPath and moveTo to solve but that is out-of-scope for this question.

Related

How to rotate one object at another (slowly)

I have been looking around for this function and thus far I just can't find any I can make any sense of. I already have a rotating function to make it equal to the position but slowly is proving to be a bit harder with 0-360 and all.
I am using a html canvas 2d context to render the objects on a Cartesian coordinate system .
I would like object1 to face at positionX and positionY at a turn rate (R) , fairly straightforward.
there is no need for me to supply any code since your likely going to make your own anyways. But I will anyways here you go:
let faceAt = function (thisObject,positionX,positionY) {
let desiredLocationX = positionX - thisObject.transform.x;
let desiredLocationY = positionY -thisObject.transform.y;
thisObject.transform.rotation = Math.degrees(Math.atan2(desiredLocationY, desiredLocationX));
};
The (Math.degrees) function converts radians to degrees.
This thread says it all : https://www.google.ca/amp/s/jibransyed.wordpress.com/2013/09/05/game-maker-gradually-rotating-an-object-towards-a-target/amp/
This question is quite unclear. But, I'm assuming you essentially just want to rotate an element around an arbitrary point on a HTML5 canvas.
On a canvas, you can only draw one element at a time. You can't really manipulate singular elements - for example, you can't rotate an element by itself. Instead, you'd need to rotate the entire canvas. This will always rotate around the centre of the canvas, but if you move the canvas origin, then you will draw on a different part of the canvas; thus allowing you to rotate around a point.
Check out the following example. You can click anywhere on the canvas to make the square rotate around that point. Hopefully this is what you are after:
let cv = document.getElementById("cv");
let ctx = cv.getContext("2d");
let angle = 0;
//Variables you can change:
let speed = 1; //Degrees to rotate per frame
let pointX = 250; //The x-coord to rotate around
let pointY = 250; //The y-coord to rotate around
ctx.fillStyle = "#000";
setInterval(()=>{ //This code runs every 40ms; so that the animation looks smooth
angle = (angle + speed) % 360; //Increment the angle. Bigger changes here mean that the element will rotate faster. If we go over 360deg, reset back to 0.
ctx.clearRect(0, 0, 400, 400); //Clear away the previous frame.
//Draw the point we are rotating around
ctx.beginPath();
ctx.arc(pointX,pointY,5,0,2*Math.PI);
ctx.fill();
ctx.closePath();
ctx.save(); //Save the state before we transform and rotate the canvas; so we can go back to the unrotated canvas for the next frame
ctx.translate(pointX, pointY); //Move the origin (0, 0) point of the canvas to the point to rotate around. The canvas always rotates around the origin; so this will allow us to rotate around that point
ctx.rotate(angle*Math.PI/180); //Rotate the canvas by the current angle. You can use your Math.degrees function to convert between rads / degs here.
ctx.fillStyle = "#f00"; //Draw in red. This is also restored when ctx.restore() is called; hence the point will always be black; and the square will always be red.
ctx.fillRect(0, 0, 50, 50); //Draw the item we want rotated. You can draw anything here; I just draw a square.
ctx.restore(); //Restore the canvas state
}, 40);
//Boring event handler stuff
//Move the point to where the user clicked
//Not too robust; relys on the body padding not changing
//Really just for the demo
cv.addEventListener("click", (event)=>{
pointX = event.clientX - 10;
pointY = event.clientY - 10;
});
#cv {
border:solid 1px #000; /*Just so we can see the bounds of the canvas*/
padding:0;
margin:0;
}
body {
padding:10px;
margin:0;
}
<canvas id="cv" width="400" height="400"></canvas><br>
Click on the canvas above to make the rectangle rotate around the point that was clicked.

Use setInterval to infinitely draw rectangles

I'm trying to learn how to learn basic animation using ONLY canvas with the setInterval function.
I'm trying to draw a simple rectangle to the screen and move it to the right 1 pixel every 100 milliseconds. However when I do it paints over the previous rectangle. I called clearRect() but that doesn't seem to do anything.
How can I make this rectangle smoothly travel across the screen without leaving a trail?
Also if there is a better way to do this rather than using clearRect() and translate() please do share.
var ctx = document.getElementById('mycanvas').getContext('2d');
var a = setInterval(draw,100);
var x = 50;
function draw()
{
ctx.clearRect(0,0,300,300);
ctx.translate(1,0);
ctx.rect(x,50,50,50);
ctx.stroke();
}
You can do it two different ways:
You can continue to use rect() and stroke(), but you need to call beginPath() beforehand. When you call methods like rect(), a list, called the "path," is kept of all of the shapes, or "subpaths," that you've created. Then, when you call stroke(), the entire path is drawn. Thus, even if you clear the screen, all of the past rectangles are still remembered in the path, and drawn again. beginPath() clears that list.
var x = 50;
function draw() {
ctx.clearRect(0, 0, 300, 300);
ctx.beginPath();
ctx.rect(x, 50, 50, 50);
ctx.stroke();
x++;
}
Or, you can combine the rect() and stroke() into one line, and not need to call beginPath(). That's because the rectangle is both created and drawn at the same time, and isn't put in the list.
var x = 50;
function draw() {
ctx.clearRect(0, 0, 300, 300);
ctx.strokeRect(x, 50, 50, 50);
x++;
}
Either way, I advise incrementing x instead of using translate(), because translate() basically moves the imaginary "pen" that is drawing on the canvas. So if you translate(50, 50), and then you try to draw a rectangle at (0, 0) on the canvas, it will actually be at (50, 50).
As Microsoft puts it on MSDN, "The translate method effectively remaps the (0,0) origin on a canvas."
If you repeatedly do that, it will become difficult to keep track of where you're actually drawing.
Your x variable never changes, so your shape will not move. You need to increment x to get movement:
var x = 50;
function draw(){
ctx.clearRect(0,0,300,300);
ctx.translate(1,0);
ctx.rect(x,50,50,50);
ctx.stroke();
x++;
}
In order to get a smooth animation with shapes and other sprites moving across the screen (or even staying still) it would be better to make a clearScreen method that will basically draw over the entire canvas in whatever background color the canvas is. It is basically just a function that will draw a white (or whatever background color you are using) rectangle over the entire canvas. Then, you call the draw function that will make all the necessary drawings. That way, there won't be any trail or anything of the past movements and you won't have to call clearRect() on every single rectangle you make.
Basically, the function will erase the canvas and you can redraw whatever you need to in order to make the animation of the box moving across the screen.
Does that make sense?
EDIT:
Also, to be clear, you would make your own clearScreen method based on what size your canvas is and what color your background is. Its not hard, all it does is draw a rectangle over the screen.
Simply increment x on every call:
var canvas = document.getElementById('mycanvas')
var ctx = canvas.getContext('2d');
var a = setInterval(draw,100);
var x = 50;
function draw(){
canvas.width = canvas.width; // clears the canvas
ctx.rect(x++,50,50,50);
ctx.stroke();
if (x > 250) // resets the position
x = 50;
}
<canvas id="mycanvas"></canvas>
I also removed that translation since there's no need to do it just for the square animation.
Try beginPath() and closePath():
var maxX, x = 0,
s = 50,
maxY;
var repaint = function(ctx) {
if (x + s >= maxX) { //reached end of the canvas
return;
}
ctx.clearRect(0, 0, maxX, maxY); //clear previous
ctx.beginPath(); //start drawing
ctx.rect(x, s, s, s);
ctx.stroke();
ctx.closePath(); //stop drawing
x++;
setTimeout(function() {
repaint(ctx); //continue here
}, 100);
};
var cnvs = document.getElementById('canvas');
maxX = cnvs.width;
maxY = cnvs.height;
repaint(cnvs.getContext('2d'));
canvas {
border: 1px solid grey;
}
<canvas width="360" height="180" id='canvas'>HTML5 canvas not supported</canvas>

how draw only vertical and horizontal lines (Canvas)

I want to make one drawing tool with html5 canvas, that can draw only horizontal and vertical lines
For example despite which way I will drag the mouse it must draw vertical or horizontal line.
Below I will show one image where i will show what i need...
can any one give me some code example ?
This is something that you have to use some logic or algorithm for.What I have done here is to Calculate dx and dy, ie change in x and change in y.
When change in x is more (dx>dy) keep your y constant, and vice versa.
Here's my code
HTML
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Jquery
var prvX = -300;
var prvy = -300;
$('#myCanvas').bind("mousemove",function(e){
var c=document.getElementById("myCanvas");
c.width=c.width;
var ctx=c.getContext("2d");
ctx.beginPath();
ctx.moveTo(20,20);
var dx = Number(e.offsetX) - Number(prvX);
var dy = Number(e.offsetY) - Number(prvy);
if(Number(dx)>Number(dy))
{
ctx.lineTo(e.offsetX,20);
}
else
{
ctx.lineTo(20,e.offsetY);
}
prvX =e.offsetX;
prvy=e.offsetY;
ctx.stroke();});
Fiddle
http://jsfiddle.net/zhq5n/4/
Better one here by GameAlchemist
http://jsfiddle.net/gamealchemist/zhq5n/5/

Incorrect mouse coordinates when drawing on Canvas

I'm trying to draw on a canvas, but the mouse positions are off, they seem to be too far to the right when I draw.
The canvas is centered in the middle with a width of 960px.
Here's the URL to the page: http://passion4web.co.uk/ben/canvas/app/
I'm using the following function to get the mouse position:
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
A canvas has two distinct sizes:
The size on the page
The size in pixel of the image
You need to set the canvas size in pixel to the size on the page to get an accurate 1:1 rendering:
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
Please remember that when you set the width/height members of a canvas object the picture is cleared (even if you are setting the same value currently present).

Rotating around an arbitrary point: HTML5 Canvas

Come see the amazing disappearing rectangle!
But seriously I have a really simple HTML5 canvas that just draws a rectangle(using lineTo instead of rect for a reason).
My Problem: I am attempting to rotate the rectangle 90 degrees. The rectangle should be rotated 90 degrees but instead it disappears.
In my webapp project I am getting weird x,y placement errors when I rotate my complex polygons in HTML5 canvas', so I have created this simple HTML to test rotation & ensure its rotating around its x,y point of 100,100. But even this has weird results when I attempt to rotate a shape.
Can anyone tell me how to get my rectangle visible & how I can rotate my polygons around a specific point without them completely changing x,y values.
Has anyone experienced this issue with HTML5 canvas' & know solutions to fix this?
<canvas id="testCanvas" width="900px" height="900px" style="background-color: blue;">
</canvas>
<script type="text/javascript">
var canvas = document.getElementById("testCanvas");
var dc = canvas.getContext("2d");
dc.clearRect(0, 0, canvas.width, canvas.height);
dc.save();
dc.fillStyle = "#FF0000";
dc.rotate( 90*Math.PI/180 ); // rotate 90 degrees
dc.beginPath();
dc.moveTo(100, 100);
dc.lineTo(200, 100);
dc.lineTo(200,300);
dc.lineTo(100,300);
dc.closePath();
dc.fill();
dc.restore();
-->
</script>
To rotate around a point you need to do 3 steps.
First translate the context to the center you wish to rotate around.
Then do the actual rotation.
Then translate the context back.
Like this:
var canvas = document.getElementById("testCanvas");
var dc = canvas.getContext("2d");
var angle = 0;
window.setInterval(function(){
angle = (angle + 1) % 360;
dc.clearRect(0, 0, canvas.width, canvas.height);
dc.save();
dc.fillStyle = "#FF0000";
dc.translate(150,200); // First translate the context to the center you wish to rotate around.
dc.rotate( angle*Math.PI/180 ); // Then do the actual rotation.
dc.translate(-150,-200); // Then translate the context back.
dc.beginPath();
dc.moveTo(100, 100);
dc.lineTo(200, 100);
dc.lineTo(200,300);
dc.lineTo(100,300);
dc.closePath();
dc.fill();
dc.restore();
}, 5);
When you rotate the canvas, it rotates from the origin (0, 0), so your rectangle ends up getting rotated off the screen.
See this example where it's only rotated 45 deg: http://jsfiddle.net/wjLSm/
One way to fix this is to translate the canvas by its width & height/2: http://jsfiddle.net/wjLSm/1/ (then 0,0 is at the middle -- be aware of this)
Did you mean like this?
var canvas = document.getElementById("testCanvas");
var dc = canvas.getContext("2d");
dc.clearRect(0, 0, canvas.width, canvas.height);
dc.save();
dc.fillStyle = "#FF0000";
dc.translate(200, -100);
dc.rotate(45 * Math.PI / 180);
dc.beginPath();
dc.moveTo(100, 100);
dc.lineTo(200, 100);
dc.lineTo(200, 300);
dc.lineTo(100, 300);
dc.closePath();
dc.fill();
// rotate 90 degrees
dc.restore();
<canvas id="testCanvas" width="900px" height="900px" style="background-color: blue;">
</canvas>

Categories