我想在画布中使用类似椭圆选项的东西来绘制画布。我已经部分实现了这一点。问题是我无法获得圆的半径,目前我已将其硬编码为15.此外,我想绘制椭圆(与油漆相同)不是精确的圆。 这是我使用鼠标事件在画布上绘制圆圈的代码。请帮助我使用代码来实现我上面提到的要求。
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();
}
};
}
答案 0 :(得分:6)
我会像markE的回答一样,但是使用Bezier曲线会绘制椭圆,但它不会给你你可能需要的确切半径。
为此需要绘制手动椭圆的函数,而且它非常简单 -
此函数将采用角点起点和终点,并在该边界内绘制一个完全的椭圆:
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();
}
该演示也标记了矩形区域,以显示椭圆正好位于其中。
要处理鼠标操作,您可以使用它来绘制椭圆:
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);
}
提示可以在主画布顶部创建顶部画布,并在那里进行绘制。释放鼠标按钮后,将绘图传输到主画布。这样,在绘制新形状时,您无需重绘所有内容。
希望这有帮助!
答案 1 :(得分:2)
以下是如何拖动绘制椭圆的示例。
演示:http://jsfiddle.net/m1erickson/3SFJy/
使用2条贝塞尔曲线拖动绘制椭圆的示例代码:
<!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>
答案 2 :(得分:0)
这是我用鼠标拖动在画布上绘制椭圆的方法。
它使用半径为1,但动态缩放以获得椭圆效果:)
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>