在Javascript画布绘图中,如何消除arc()中的线条?
我正在尝试用 Javascript 在画布上绘制弧线,但我想去掉 Javascript 自动绘制的线。画线的时候,有两个问题: a) fill() 故障 b) 它看起来像一把弓
这是我拥有的和我想要的图像: 左边是我在 JS 中的,右边是我在 Java 中的。 Java 实现效率相当低,我想使用已有的功能。
以下是相关的 JS 函数:
function pointAt(center, l, theta){
return {
x : Math.sin(theta) * l + center.x,
y : Math.cos(theta) * l + center.y
};
}
function drawArc(ctx, center, l, theta, sweep, label, thickness){
var p0 = pointAt(center, l, theta);
var p1 = pointAt(center, l + thickness, theta);
var p2 = pointAt(center, l + thickness, theta + sweep);
var p3 = pointAt(center, l, theta + sweep);
ctx.fillStyle = "red";
drawPoint(ctx, p0);
ctx.fillStyle = "blue";
drawPoint(ctx, p1);
ctx.fillStyle = "green";
drawPoint(ctx, p2);
ctx.fillStyle = "yellow";
drawPoint(ctx, p3);
ctx.beginPath();
ctx.moveTo(p0.x, p0.y);
ctx.lineTo(p1.x, p1.y);
ctx.arc(center.x, center.y, l + thickness, theta, theta + sweep, false);
ctx.moveTo(p2.x, p2.y);
ctx.lineTo(p3.x, p3.y);
ctx.arc(center.x, center.y, l, theta + sweep, theta, true)
ctx.closePath();
ctx.fill();
ctx.stroke();
//TODO: draw label!!!
}
function drawPoint(ctx, p){
ctx.fillRect(p.x - 4, p.y - 4, 8, 8);
}
这是 Java 中的一个工作实现:
private static void drawArc(Graphics g, Point center, int l, double theta, double sweep, String label, int thickness){
for (double i = 0; i < thickness; i+=.5) { //hardcoded
Point last = pointAt(center, l + i, theta);
for(double t = theta; t < theta + sweep; t+=.01){
Point cur = pointAt(center, l + i, t);
g.drawLine(last.x, last.y, cur.x, cur.y);
last = cur;
}
}
double t = theta + sweep / 2;
Point p = pointAt(center, l + 15, t);
int size = g.getFontMetrics().stringWidth(label);
BufferedImage img = new BufferedImage(size * 2, size * 2, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setColor(Color.RED);
double rot = (Math.PI / 2 - t);
// System.out.println(rot / Math.PI + "PI");
boolean b = true;
if(rot < -Math.PI / 2){
rot += Math.PI;
b = false;
}
g2.setTransform(AffineTransform.getRotateInstance(rot, size, size));
g2.drawString(label, size, size);
g2.dispose();
if(!b)
size *= 1.75; //magic value or hardcoded???
g.drawImage(img, p.x - size, p.y - size, null);
}
所以我的问题: 如何把香蕉变成粗弧线?
I'm trying to draw an arc on a canvas in Javascript, but I want to get rid of the line that Javascript automatically draws. With the line being drawn, there are two problems:
a) fill() malfunctions
b) It looks like a bow
Here's an image of what I have and what I want:
The left is what I have in JS, the right is what I have in Java. The Java implementation is fairly inefficient and I would like to use the functions already available.
Here are the relevant JS functions:
function pointAt(center, l, theta){
return {
x : Math.sin(theta) * l + center.x,
y : Math.cos(theta) * l + center.y
};
}
function drawArc(ctx, center, l, theta, sweep, label, thickness){
var p0 = pointAt(center, l, theta);
var p1 = pointAt(center, l + thickness, theta);
var p2 = pointAt(center, l + thickness, theta + sweep);
var p3 = pointAt(center, l, theta + sweep);
ctx.fillStyle = "red";
drawPoint(ctx, p0);
ctx.fillStyle = "blue";
drawPoint(ctx, p1);
ctx.fillStyle = "green";
drawPoint(ctx, p2);
ctx.fillStyle = "yellow";
drawPoint(ctx, p3);
ctx.beginPath();
ctx.moveTo(p0.x, p0.y);
ctx.lineTo(p1.x, p1.y);
ctx.arc(center.x, center.y, l + thickness, theta, theta + sweep, false);
ctx.moveTo(p2.x, p2.y);
ctx.lineTo(p3.x, p3.y);
ctx.arc(center.x, center.y, l, theta + sweep, theta, true)
ctx.closePath();
ctx.fill();
ctx.stroke();
//TODO: draw label!!!
}
function drawPoint(ctx, p){
ctx.fillRect(p.x - 4, p.y - 4, 8, 8);
}
Here's a working implementation in Java:
private static void drawArc(Graphics g, Point center, int l, double theta, double sweep, String label, int thickness){
for (double i = 0; i < thickness; i+=.5) { //hardcoded
Point last = pointAt(center, l + i, theta);
for(double t = theta; t < theta + sweep; t+=.01){
Point cur = pointAt(center, l + i, t);
g.drawLine(last.x, last.y, cur.x, cur.y);
last = cur;
}
}
double t = theta + sweep / 2;
Point p = pointAt(center, l + 15, t);
int size = g.getFontMetrics().stringWidth(label);
BufferedImage img = new BufferedImage(size * 2, size * 2, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setColor(Color.RED);
double rot = (Math.PI / 2 - t);
// System.out.println(rot / Math.PI + "PI");
boolean b = true;
if(rot < -Math.PI / 2){
rot += Math.PI;
b = false;
}
g2.setTransform(AffineTransform.getRotateInstance(rot, size, size));
g2.drawString(label, size, size);
g2.dispose();
if(!b)
size *= 1.75; //magic value or hardcoded???
g.drawImage(img, p.x - size, p.y - size, null);
}
So my question:
How do I turn the banana into a thick arc?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
只需顺时针绘制外圆弧,然后逆时针绘制内圆弧即可。画布会自动为您用直线封闭两端。
http://jsfiddle.net/tMEdq/
另外,这里有一些很好的参考:
http://diveintohtml5.ep.io/canvas.html#divingin
http://www.nihilogic.dk/labs/canvas_sheet/HTML5_Canvas_Cheat_Sheet.png
Just draw the outer arc clockwise, then the inner arc counter-clockwise. The canvas will automatically close off the ends with straight lines for you.
http://jsfiddle.net/tMEdq/
Also, here are good references:
http://diveintohtml5.ep.io/canvas.html#divingin
http://www.nihilogic.dk/labs/canvas_sheet/HTML5_Canvas_Cheat_Sheet.png
您也有太多的绘图调用 - 这就是您所需要的:
只需绘制第一个圆弧,它将自动连接到下一个圆弧,然后关闭路径以完成循环。
您还在
pointAt()
中以错误的方式调用了sin
和cos
-sin()
应该改变Y 轴坐标,而不是 X 轴!工作演示位于 http://jsfiddle.net/alnitak/zChSe/
You have way too many drawing calls too - this is all you need:
Just draw the first arc, which will automatically get joined to the next, and then close the path to complete the loop.
You also have your
sin
andcos
calls the wrong way around inpointAt()
-sin()
should alter the Y axis coordinate, not the X axis!Working demo at http://jsfiddle.net/alnitak/zChSe/
只要这样做:
“横向”线是隐式放置的,请参阅 http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-arc。
Just do:
The "lateral" lines are implict placed, see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-arc.