Drawing circle/ellipse on HTML5 canvas using mouse events - javascript

I want something like ellipse option in paint for drawing on my canvas. I have achieved this partially. The problem is I am not able to get radius of circle; currently I have hard coded it to 15. Also I want to draw an ellipse (like in paint) not exact circle.
This is my code for drawing circle on canvas using mouse events. Please help me with code to achieve my above mentioned requirements.
function tool_circle() {
var tool = this;
this.started = false;
this.mousedown = function (ev) {
tool.started = true;
tool.x0 = ev._x;
tool.y0 = ev._y;
};
this.mousemove = function (ev) {
if (!tool.started) {
return;
}
context.fillStyle = 'red';
var distance = Math.sqrt(Math.pow(tool.x0 - ev._x, 2) + Math.pow(tool.y0 - ev._y));
context.beginPath();
context.arc(tool.x0, tool.y0,15, 0, Math.PI * 2, false);
context.stroke();
context.fill();
};
this.mouseup = function (ev) {
if (tool.started) {
tool.mousemove(ev);
tool.started = false;
img_update();
}
};
}

I would something similar as with markE's answer however, using Bezier curve will draw ellipses but it won't give you the exact radius that you probably would need.
For that a function to draw a manual ellipse is needed, and it's rather simple -
This function will take a corner start point and and end point and draw an ellipse exactly within that boundary:
Live demo
function drawEllipse(x1, y1, x2, y2) {
var radiusX = (x2 - x1) * 0.5, /// radius for x based on input
radiusY = (y2 - y1) * 0.5, /// radius for y based on input
centerX = x1 + radiusX, /// calc center
centerY = y1 + radiusY,
step = 0.01, /// resolution of ellipse
a = step, /// counter
pi2 = Math.PI * 2 - step; /// end angle
/// start a new path
ctx.beginPath();
/// set start point at angle 0
ctx.moveTo(centerX + radiusX * Math.cos(0),
centerY + radiusY * Math.sin(0));
/// create the ellipse
for(; a < pi2; a += step) {
ctx.lineTo(centerX + radiusX * Math.cos(a),
centerY + radiusY * Math.sin(a));
}
/// close it and stroke it for demo
ctx.closePath();
ctx.strokeStyle = '#000';
ctx.stroke();
}
The demo marks the rectangle area too to show that the ellipse is exactly within it.
Draw
To handle mouse operation that will let you draw the ellipse you can do:
var canvas = document.getElementById('myCanvas'),
ctx = canvas.getContext('2d'),
w = canvas.width,
h = canvas.height,
x1, /// start points
y1,
isDown = false; /// if mouse button is down
/// handle mouse down
canvas.onmousedown = function(e) {
/// get corrected mouse position and store as first point
var rect = canvas.getBoundingClientRect();
x1 = e.clientX - rect.left;
y1 = e.clientY - rect.top;
isDown = true;
}
/// clear isDown flag to stop drawing
canvas.onmouseup = function() {
isDown = false;
}
/// draw ellipse from start point
canvas.onmousemove = function(e) {
if (!isDown) return;
var rect = canvas.getBoundingClientRect(),
x2 = e.clientX - rect.left,
y2 = e.clientY - rect.top;
/// clear canvas
ctx.clearRect(0, 0, w, h);
/// draw ellipse
drawEllipse(x1, y1, x2, y2);
}
A tip can be to create a top canvas on top of your main canvas and do the drawing itself there. When mouse button is released then transfer the drawing to your main canvas. This way you don't have to redraw everything when drawing a new shape.
Hope this helps!

Here's an example of how to drag-draw an oval.
Demo: http://jsfiddle.net/m1erickson/3SFJy/
Example code using 2 Bezier curves to drag-draw an oval:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; padding:0px;}
#canvas{ border:1px solid blue; }
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var startX;
var startY;
var isDown=false;
function drawOval(x,y){
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.beginPath();
ctx.moveTo(startX, startY + (y-startY)/2);
ctx.bezierCurveTo(startX, startY, x, startY, x, startY + (y-startY)/2);
ctx.bezierCurveTo(x, y, startX, y, startX, startY + (y-startY)/2);
ctx.closePath();
ctx.stroke();
}
function handleMouseDown(e){
e.preventDefault();
e.stopPropagation();
startX=parseInt(e.clientX-offsetX);
startY=parseInt(e.clientY-offsetY);
isDown=true;
}
function handleMouseUp(e){
if(!isDown){ return; }
e.preventDefault();
e.stopPropagation();
isDown=false;
}
function handleMouseOut(e){
if(!isDown){ return; }
e.preventDefault();
e.stopPropagation();
isDown=false;
}
function handleMouseMove(e){
if(!isDown){ return; }
e.preventDefault();
e.stopPropagation();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
drawOval(mouseX,mouseY);
}
$("#canvas").mousedown(function(e){handleMouseDown(e);});
$("#canvas").mousemove(function(e){handleMouseMove(e);});
$("#canvas").mouseup(function(e){handleMouseUp(e);});
$("#canvas").mouseout(function(e){handleMouseOut(e);});
}); // end $(function(){});
</script>
</head>
<body>
<h4>Drag to create a circle or oval</h4>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

Here's my way of drawing an ellipse onto a canvas with mouse drag.
It uses radius of 1, but dynamic scaling to get the ellipse effect :)
https://jsfiddle.net/richardcwc/wdf9cocz/
//Canvas
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
//Variables
var scribble_canvasx = $(canvas).offset().left;
var scribble_canvasy = $(canvas).offset().top;
var scribble_last_mousex = scribble_last_mousey = 0;
var scribble_mousex = scribble_mousey = 0;
var scribble_mousedown = false;
//Mousedown
$(canvas).on('mousedown', function(e) {
scribble_last_mousex = parseInt(e.clientX-scribble_canvasx);
scribble_last_mousey = parseInt(e.clientY-scribble_canvasy);
scribble_mousedown = true;
});
//Mouseup
$(canvas).on('mouseup', function(e) {
scribble_mousedown = false;
});
//Mousemove
$(canvas).on('mousemove', function(e) {
scribble_mousex = parseInt(e.clientX-scribble_canvasx);
scribble_mousey = parseInt(e.clientY-scribble_canvasy);
if(scribble_mousedown) {
ctx.clearRect(0,0,canvas.width,canvas.height); //clear canvas
//Save
ctx.save();
ctx.beginPath();
//Dynamic scaling
var scalex = 1*((scribble_mousex-scribble_last_mousex)/2);
var scaley = 1*((scribble_mousey-scribble_last_mousey)/2);
ctx.scale(scalex,scaley);
//Create ellipse
var centerx = (scribble_last_mousex/scalex)+1;
var centery = (scribble_last_mousey/scaley)+1;
ctx.arc(centerx, centery, 1, 0, 2*Math.PI);
//Restore and draw
ctx.restore();
ctx.strokeStyle = 'black';
ctx.lineWidth = 5;
ctx.stroke();
}
//Output
$('#output').html('current: '+scribble_mousex+', '+scribble_mousey+'<br/>last: '+scribble_last_mousex+', '+scribble_last_mousey+'<br/>mousedown: '+scribble_mousedown);
});
canvas {
cursor: crosshair;
border: 1px solid #000000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas" width="800" height="500"></canvas>
<div id="output"></div>

Related

check if circle is hovered HTML5 Canvas [duplicate]

I'm new to canvas and I'm trying to listen to mouse clicks on the circles that I previously drew on canvas. I'm trying to change the colour of the circles (maybe to green) when I click on them.
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var radius = 15;
for (var i = 0; i < 600; i += 100) {
var x = 100 + i;
var y = 100;
draw_circle(i, x, y, radius);
}
function draw_circle(ID, x, y, radius) {
context.beginPath();
context.arc(x, y, radius, 0, Math.PI * 2, false);
context.fillStyle = 'red';
context.fill();
context.lineWidth = 3;
context.strokeStyle = 'black';
context.stroke();
context.closePath();
}
<!DOCTYPE HTML>
<html>
<head>
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0px;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="700" height="700"></canvas>
</body>
</html>
Just add the arc path again and use isPointInPath() with the mouse position. Only one arc can be tested at once, but it's fast to clear and add new paths. Do this in a loop.
Example
var c = document.querySelector("canvas"), ctx = c.getContext("2d");
getArc(50, 50, 40);
ctx.fill();
c.onclick = function(e) {
var rect = this.getBoundingClientRect(), // get abs. position of canvas
x = e.clientX - rect.left, // adjust mouse-position
y = e.clientY - rect.top;
getArc(50, 50, 40); // get path wo/ filling/stroking it
if (ctx.isPointInPath(x, y)) alert("Clicked");
};
function getArc(x, y, r) {
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI*2);
ctx.closePath();
}
<canvas></canvas>
The other approach is to use math and trigonometry:
// at this point we have the mouse position, so:
var dx = x - arcX,
dy = y - arcY,
dist = Math.abs(Math.sqrt(dx*dx + dy*dy));
if (dist <= radius) { ...clicked... };
Tip: you can skip squaring the dist by using r2 instead.
With SVG, it would be easy - a circle is an element, and can have a click handler, and has fill that you can manipulate to change colour.
With Canvas, you need to:
save the data for each circle you draw (center and radius)
capture click on canvas as cx, cy
check every circle data x, y, r you have, see whether dx * dx + dy * dy < r * r, where dx = cx - x, dy = cy - y. Circles that satisfy this equation were clicked
repaint the circle
With Canvas, you can use function addEventListener. There are quite a few mouse events you can detect: mousedown, mouseup, mousemove, mouseout and mouseover.
Here is a example:
<!DOCTYPE HTML>
<html>
<head>
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0px;
}
</style>
<script>
function initialize() {
var canvas = document.getElementById("myCanvas");
canvas.addEventListener("mousedown", doMouseDown, false);
}
function doMouseDown() {
canvas_X = event.pageX;
canvas_Y = event.pageY;
alert("X = " + canvas_X + "Y = " + canvas_Y);
}
</script>
</head>
<body>
<canvas id="myCanvas" width="700" height="700"></canvas>
</body>
</html>

Detect mouse clicks on circles on HTML5 canvas

I'm new to canvas and I'm trying to listen to mouse clicks on the circles that I previously drew on canvas. I'm trying to change the colour of the circles (maybe to green) when I click on them.
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var radius = 15;
for (var i = 0; i < 600; i += 100) {
var x = 100 + i;
var y = 100;
draw_circle(i, x, y, radius);
}
function draw_circle(ID, x, y, radius) {
context.beginPath();
context.arc(x, y, radius, 0, Math.PI * 2, false);
context.fillStyle = 'red';
context.fill();
context.lineWidth = 3;
context.strokeStyle = 'black';
context.stroke();
context.closePath();
}
<!DOCTYPE HTML>
<html>
<head>
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0px;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="700" height="700"></canvas>
</body>
</html>
Just add the arc path again and use isPointInPath() with the mouse position. Only one arc can be tested at once, but it's fast to clear and add new paths. Do this in a loop.
Example
var c = document.querySelector("canvas"), ctx = c.getContext("2d");
getArc(50, 50, 40);
ctx.fill();
c.onclick = function(e) {
var rect = this.getBoundingClientRect(), // get abs. position of canvas
x = e.clientX - rect.left, // adjust mouse-position
y = e.clientY - rect.top;
getArc(50, 50, 40); // get path wo/ filling/stroking it
if (ctx.isPointInPath(x, y)) alert("Clicked");
};
function getArc(x, y, r) {
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI*2);
ctx.closePath();
}
<canvas></canvas>
The other approach is to use math and trigonometry:
// at this point we have the mouse position, so:
var dx = x - arcX,
dy = y - arcY,
dist = Math.abs(Math.sqrt(dx*dx + dy*dy));
if (dist <= radius) { ...clicked... };
Tip: you can skip squaring the dist by using r2 instead.
With SVG, it would be easy - a circle is an element, and can have a click handler, and has fill that you can manipulate to change colour.
With Canvas, you need to:
save the data for each circle you draw (center and radius)
capture click on canvas as cx, cy
check every circle data x, y, r you have, see whether dx * dx + dy * dy < r * r, where dx = cx - x, dy = cy - y. Circles that satisfy this equation were clicked
repaint the circle
With Canvas, you can use function addEventListener. There are quite a few mouse events you can detect: mousedown, mouseup, mousemove, mouseout and mouseover.
Here is a example:
<!DOCTYPE HTML>
<html>
<head>
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0px;
}
</style>
<script>
function initialize() {
var canvas = document.getElementById("myCanvas");
canvas.addEventListener("mousedown", doMouseDown, false);
}
function doMouseDown() {
canvas_X = event.pageX;
canvas_Y = event.pageY;
alert("X = " + canvas_X + "Y = " + canvas_Y);
}
</script>
</head>
<body>
<canvas id="myCanvas" width="700" height="700"></canvas>
</body>
</html>

How can I draw arrows on a canvas with mouse

recently I started playing with canvas element. Now I am able to draw lines(as many as I wish) on a canvas with mouse. You can see it here in the code: https://jsfiddle.net/saipavan579/a6L3ka8p/.
var ctx = tempcanvas.getContext('2d'),
mainctx = canvas.getContext('2d'),
w = canvas.width,
h = canvas.height,
x1,
y1,
isDown = false;
tempcanvas.onmousedown = function(e) {
var pos = getPosition(e, canvas);
x1 = pos.x;
y1 = pos.y;
isDown = true;
}
tempcanvas.onmouseup = function() {
isDown = false;
mainctx.drawImage(tempcanvas, 0, 0);
ctx.clearRect(0, 0, w, h);
}
tempcanvas.onmousemove = function(e) {
if (!isDown) return;
var pos = getPosition(e, canvas);
x2 = pos.x;
y2 = pos.y;
ctx.clearRect(0, 0, w, h);
drawEllipse(x1, y1, x2, y2);
}
function drawEllipse(x1, y1, x2, y2) {
var radiusX = (x2 - x1) * 0.5,
radiusY = (y2 - y1) * 0.5,
centerX = x1 + radiusX,
centerY = y1 + radiusY,
step = 0.01,
a = step,
pi2 = Math.PI * 2 - step;
ctx.beginPath();
ctx.moveTo(x1,y1);
for(; a < pi2; a += step) {
ctx.lineTo(x2,y2);
}
ctx.closePath();
ctx.strokeStyle = '#000';
ctx.stroke();
}
function getPosition(e, gCanvasElement) {
var x;
var y;
x = e.pageX;
y = e.pageY;
x -= gCanvasElement.offsetLeft;
y -= gCanvasElement.offsetTop;
return {x:x, y:y};
};
Now I want to draw arrow headed lines(for pointing to some specific point on a image) in the same way as I am drawing the lines. How can do that? Thank you in advance.
You can draw an arrowhead at the end of line segment [p0,p1] like this:
calculate the angle from p0 to p1 using Math.atan2.
Each side of the arrowhead starts at p1, so calculate the 2 arrow endpoints using trigonometry.
draw the [p0,p1] line segment and the 2 arrowhead line segments.
Here's example code and a Demo:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var p0={x:50,y:100};
var p1={x:250,y:50};
drawLineWithArrowhead(p0,p1,15);
function drawLineWithArrowhead(p0,p1,headLength){
// constants (could be declared as globals outside this function)
var PI=Math.PI;
var degreesInRadians225=225*PI/180;
var degreesInRadians135=135*PI/180;
// calc the angle of the line
var dx=p1.x-p0.x;
var dy=p1.y-p0.y;
var angle=Math.atan2(dy,dx);
// calc arrowhead points
var x225=p1.x+headLength*Math.cos(angle+degreesInRadians225);
var y225=p1.y+headLength*Math.sin(angle+degreesInRadians225);
var x135=p1.x+headLength*Math.cos(angle+degreesInRadians135);
var y135=p1.y+headLength*Math.sin(angle+degreesInRadians135);
// draw line plus arrowhead
ctx.beginPath();
// draw the line from p0 to p1
ctx.moveTo(p0.x,p0.y);
ctx.lineTo(p1.x,p1.y);
// draw partial arrowhead at 225 degrees
ctx.moveTo(p1.x,p1.y);
ctx.lineTo(x225,y225);
// draw partial arrowhead at 135 degrees
ctx.moveTo(p1.x,p1.y);
ctx.lineTo(x135,y135);
// stroke the line and arrowhead
ctx.stroke();
}
body{ background-color: ivory; }
canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>

Drawing a rectangle on Canvas

I am trying to create a simple canvas program where the user can consistently create new shapes. This one is just a basic rectangle creator (I am hoping to expand it more to circles, lines, and maybe even other stuff). Right now though I have created something that is working in a really weird way.
<html>
<head>
<meta chartset="utf-8">
<title>Dragging a square</title>
<script type="text/javascript">
var canvas, context, startX, endX, startY, endY;
var mouseIsDown = 0;
function init() {
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
canvas.addEventListener("mousedown", mouseDown, false);
canvas.addEventListener("mousemove", mouseXY, false);
document.body.addEventListener("mouseup", mouseUp, false);
}
function mouseUp() {
mouseIsDown = 0;
//mouseXY();
}
function mouseDown() {
mouseIsDown = 1;
startX = event.clientX;
startY = event.clientY;
mouseXY();
}
function mouseXY(eve) {
if (!eve) {
var eve = event;
}
endX = event.pageX - canvas.offsetLeft;
endY = event.pageY - canvas.offsetTop;
drawSquare();
}
function drawSquare() {
// creating a square
var width = Math.abs(startX - endX);
var height = Math.abs(startY - endY);
context.beginPath();
context.rect(startX, startY, width, height);
context.fillStyle = "yellow";
context.fill();
context.lineWidth = 7;
context.strokeStyle = 'black';
context.stroke();
}
</script>
</head>
<body onload="init()">
<canvas id="canvas" width="400" height="400" style="border: 1px solid black; cursor: pointer;"></canvas>
</body>
</html>
Sorry about the slightly weird formatting when I copy and pasted my code. I think the problem is my mouseXY function. What I want is the user to click somewhere on the canvas a drag the mouse to create a rectangle, when the user lets go that is the end of that operation and they can create a whole new rectangle right after. At this point the program kind of just lets me click and create a new rectangle but if I let go of the mouse button it doesn't stop, in fact I have to click again to make it stop which then creates a new rectangle. I am still very new to this and I am having a lot of trouble with this, I will continue to work on this and if I figure it out I will let the site know. Thank you and have a great day!
Well I got this to work (thanks to #Ken) but now I am trying to solve a new problem. I want to be able to put multiple rectangles on the canvas. I created a function that represents the Rectangle and then created a draw function within the rectangle function to draw out a rectangle. I created a new function called addShape() that ideally creates the rectangle object and pushes into an array called square and drawShapes() that is supposed to erase everything on the canvas and redraws everything. Here is what I have so far:
<html>
<head>
<meta chartset="utf-8">
<title>Dragging a square</title>
<script type="text/javascript">
function Rectangle(canvas, x, y, width, height,color) {
//this.context = canvas.getContext("2d");
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color;
this.draw = function() {
this.context.globalAlpha = 0.85;
this.context.beginPath();
this.context.rect(this.x, this.y, this.width, this.height);
this.context.fillStyle = this.color;
this.context.strokeStyle = "black";
this.context.lineWidth = 1;
this.context.fill();
this.context.stroke();
};
};
// hold the canvas and context variable, as well as the
// starting point of X and Y and the end ones
var canvas, context, startX, endX, startY, endY;
var mouseIsDown = 0;
// An array that holds all the squares
var squares = [];
window.onload = function() {
canvas = document.getElementById("canvas");
context = canvas.getContext("2d");
canvas.addEventListener("mousedown", mouseDown, false);
canvas.addEventListener("mousemove", mouseXY, false);
canvas.addEventListener("mouseup", mouseUp, false);
}
function mouseUp(eve) {
if (mouseIsDown !== 0) {
mouseIsDown = 0;
var pos = getMousePos(canvas, eve);
endX = pos.x;
endY = pos.y;
//Square(); //update on mouse-up
addShape(); // Update on mouse-up
}
}
function mouseDown(eve) {
mouseIsDown = 1;
var pos = getMousePos(canvas, eve);
startX = endX = pos.x;
startY = endY = pos.y;
// Square(); //update
addShape();
}
function mouseXY(eve) {
if (mouseIsDown !== 0) {
var pos = getMousePos(canvas, eve);
endX = pos.x;
endY = pos.y;
//Square();
addShape();
}
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
function addShape() {
var w = endX - startX;
var h = endY - startY;
var offsetX = (w < 0) ? w : 0;
var offsetY = (h < 0) ? h : 0;
var width = Math.abs(w);
var height = Math.abs(h);
var s = new Rectangle(startX + offsetX, startY + offsetY, width, height, "yellow");
squares.push(s);
// Update the display
drawShapes();
}
function drawShapes() {
context.clearRect(0,0,canvas.width,canvas.height);
for (var i = 0; i < squares.length; i++) {
var shape = squares[i];
shape.draw();
};
}
function clearCanvas() {
squares = [];
drawShapes();
}
</script>
</head>
<body onload="addShape()">
<canvas id="canvas" width="400" height="400" style="border: 1px solid black; cursor: pointer;"></canvas><br>
<button onclick="clearCanvas()">Clear Canvas</button>
</body>
</html>
I am pretty sure I broke the original code... thank you for any help!
You need to modify a couple of things in the code: (edit: there are many issues with this code. I went through some of them inline here, but haven't tested. If you put it in a fiddle it's easier for us to check)..
Fiddle
When mouse down occur initialize both start and end points. Call a common draw function that is not dependent on the event itself:
function mouseDown(eve) {
mouseIsDown = 1;
var pos = getMousePos(canvas, eve);
startX = endX = pos.x;
startY = endY = pos.y;
drawSquare(); //update
}
At mouse up, only register if isMouseDown is true, else this function will handle all incoming up-events (as you have attatched it to document, which is correct - window could have been used too):
function mouseUp(eve) {
if (mouseIsDown !== 0) {
mouseIsDown = 0;
var pos = getMousePos(canvas, eve);
endX = pos.x;
endY = pos.y;
drawSquare(); //update on mouse-up
}
}
Only draw if mouseisdown is true:
function mouseXY(eve) {
if (mouseIsDown !== 0) {
var pos = getMousePos(canvas, eve);
endX = pos.x;
endY = pos.y;
drawSquare();
}
}
In addition you will need to clear the previous area of the rectangle before drawing a new or else it won't show when you draw a bigger rectangle and then move the mouse back to draw a smaller one.
For simplicity you can do:
function drawSquare() {
// creating a square
var width = Math.abs(startX - endX);
var height = Math.abs(startY - endY);
context.clearRect(0, 0, context.width, context.height);
//or use fillRect if you use a bg color
context.beginPath();
context.rect(startX, startY, width, height);
context.fillStyle = "yellow";
context.fill();
context.lineWidth = 7;
context.strokeStyle = 'black';
context.stroke();
}
Use this for mouse position:
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}

HTML5 Canvas drawing ellipse increasingly

I am writing on whiteboard using HTML5 drawing.
The problem is when I am trying to draw ellipse, so press down and drag, many ellipse are drawn.
ctx.moveTo(startX, startY + (y-startY)/2);
ctx.bezierCurveTo(startX, startY, x, startY, x, startY + (y-startY)/2);
ctx.bezierCurveTo(x, y, startX, y, startX, startY + (y-startY)/2);
ctx.stroke();
I want to show only one ellipse every time.
Any help?
This might help - this is my version of drawing an ellipse using only arc and scaling.
https://jsfiddle.net/richardcwc/wdf9cocz/
//Canvas
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
//Variables
var scribble_canvasx = $(canvas).offset().left;
var scribble_canvasy = $(canvas).offset().top;
var scribble_last_mousex = scribble_last_mousey = 0;
var scribble_mousex = scribble_mousey = 0;
var scribble_mousedown = false;
//Mousedown
$(canvas).on('mousedown', function(e) {
scribble_last_mousex = parseInt(e.clientX-scribble_canvasx);
scribble_last_mousey = parseInt(e.clientY-scribble_canvasy);
scribble_mousedown = true;
});
//Mouseup
$(canvas).on('mouseup', function(e) {
scribble_mousedown = false;
});
//Mousemove
$(canvas).on('mousemove', function(e) {
scribble_mousex = parseInt(e.clientX-scribble_canvasx);
scribble_mousey = parseInt(e.clientY-scribble_canvasy);
if(scribble_mousedown) {
ctx.clearRect(0,0,canvas.width,canvas.height); //clear canvas
//Save
ctx.save();
ctx.beginPath();
//Dynamic scaling
var scalex = 1*((scribble_mousex-scribble_last_mousex)/2);
var scaley = 1*((scribble_mousey-scribble_last_mousey)/2);
ctx.scale(scalex,scaley);
//Create ellipse
var centerx = (scribble_last_mousex/scalex)+1;
var centery = (scribble_last_mousey/scaley)+1;
ctx.arc(centerx, centery, 1, 0, 2*Math.PI);
//Restore and draw
ctx.restore();
ctx.strokeStyle = 'black';
ctx.lineWidth = 5;
ctx.stroke();
}
//Output
$('#output').html('current: '+scribble_mousex+', '+scribble_mousey+'<br/>last: '+scribble_last_mousex+', '+scribble_last_mousey+'<br/>mousedown: '+scribble_mousedown);
});
canvas {
cursor: crosshair;
border: 1px solid #000000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas" width="800" height="500"></canvas>
<div id="output"></div>

Categories

Resources