Reputation: 99
I'm trying to make a simple paint program, and I'm slowly getting there. But the circle-tool has a small issue. The circle is moving a bit when the user click and drag. This doesn't happen with the rectangle, oval and polygon tool. How can this be fixed?
Here is the code for drawing the circle
tools.circle = function () {
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.clearRect(0, 0, canvas.width, canvas.height);
var radius = Math.max(Math.abs(ev._x - tool.x0), Math.abs(ev._y - tool.y0)) / 2;
var x = Math.min(ev._x, tool.x0) + radius;
var y = Math.min(ev._y, tool.y0) + radius;
context.fillStyle = 'hsl(' + 360 * Math.random() + ', 85%, 50%)';
context.beginPath();
context.arc(x, y, radius, 0, Math.PI * 2, false);
context.stroke();
context.closePath();
context.fill();
};
this.mouseup = function (ev) {
if (tool.started) {
tool.mousemove(ev);
tool.started = false;
drawCanvas();
}
};
};
And here is the working code for an oval
tools.oval = function () {
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.clearRect(0, 0, canvas.width, canvas.height);
var radius1 = Math.abs(ev._x - tool.x0);
var radius2 = Math.abs(ev._y - tool.y0);
var scaleX = radius1 / (Math.max(radius1, radius2));
var x = tool.x0 / scaleX;
var scaleY = radius2 / (Math.max(radius1, radius2));
var y = tool.y0 / scaleY;
context.fillStyle = 'hsl(' + 360 * Math.random() + ', 100%, 50%)';
context.save();
context.scale(scaleX, scaleY);
context.beginPath();
context.arc(x, y, Math.max(radius1, radius2), 0, 2 * Math.PI);
context.restore();
context.stroke();
context.closePath();
context.fill();
};
this.mouseup = function (ev) {
if (tool.started) {
tool.mousemove(ev);
tool.started = false;
drawCanvas();
}
};
};
It would be very nice if the circle didn't move with the mouse on the canvas, but instead stayed at the starting point and was dragged out from there.
Upvotes: 0
Views: 52
Reputation: 1418
Based on your code you need to change these lines:
//causes pointer moving from circle these lines:
var radius = Math.max(Math.abs(ev._x - tool.x0), Math.abs(ev._y - tool.y0))/2;
//causes center moving
var x = Math.min(ev._x, tool.x0) + radius;
var y = Math.min(ev._y, tool.y0) + radius;
in
var radius = Math.max(Math.abs(ev._x - tool.x0), Math.abs(ev._y - tool.y0));
var x = tool.x0;
var y = tool.y0;
Upvotes: 1
Reputation: 12891
You can use the Pythagoras theorem to get the distance from the point you clicked on the canvas to the point you're dragging your mouse to - thus the radius for your circle. Now simply draw the circle from the initial 'click' position.
Here's the modified mousemove function for your circle:
this.mousemove = function(ev) {
if (!tool.started) {
return;
}
context.clearRect(0, 0, canvas.width, canvas.height);
var tempX = ev._x - tool.x0;
var tempY = ev._y - tool.y0;
var radius = Math.sqrt(tempX * tempX + tempY * tempY);
var scale = radius / radius;
var x = tool.x0 / scale;
var y = tool.y0 / scale;
context.fillStyle = 'hsl(' + 360 * Math.random() + ', 100%, 50%)';
context.save();
context.scale(scale, scale);
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI);
context.restore();
context.stroke();
context.closePath();
context.fill();
};
Upvotes: 1
Reputation: 1930
You are moving your center by recalculating the min value between your initial start point and your current mouse location. If you want the center of the circle to remain still, your x and y coordinates should remain fixed:
var x = tool.x0;
var y = tool.y0;
Upvotes: 0