我目前正在使用 JavaFX 创建绘画应用程序。我目前有一个绘画函数(称为 squiggle),它从鼠标事件中获取一个点数组并创建连接每个点的线段。当我只处理 1px 线段时,这起初还不错。后来我使用 实现了一个笔触宽度变换器GraphicsContent.setStroke()
,它突出了线段自然呈矩形的事实。这会导致线条(尤其是在使用较粗的笔触宽度时)变得非常模糊且通常很奇怪。
我的想法是用这些点创建一个圆圈阵列,使其具有更真实的画笔感觉,但是这并不奏效,因为这些圆圈没有连接并且在每个点之间留下了很大的间隙。
当我尝试用线段连接每个圆时,它只会回到与之前相同的问题,因为矩形通常会遮住圆的阴影。
我也尝试过使用路径,这是我以前从未尝试过的。这只会让我回到原来的问题,但现在我在绘图时遇到了更多的延迟。这可能是因为我的实现方式错误,但目前,我甚至不确定路径是否会对我有帮助。
这是我toPath
在 Squiggle 类中的方法:
public Path toPath(){
Path path = new Path();
path.setStroke(this.getColor());
path.setStrokeWidth(this.getStrokeWidth());
path.setStrokeLineCap(StrokeLineCap.ROUND);
if (this.points.isEmpty()) {
return path;
}
Point start = this.points.getFirst();
path.getElements().add(new MoveTo(start.x, start.y));
for(int i = 1; i < this.points.size(); i++){
Point point = this.points.get(i);
path.getElements().add(new LineTo(point.x, point.y));
}
return path;
}
这是我的绘画面板中的更新方法:
GraphicsContext g2d = this.getGraphicsContext2D();
for(Squiggle sq: squiggles){
Path path = sq.toPath();
if (!path.getElements().isEmpty()){
for (var element : path.getElements()) {
if (element instanceof MoveTo moveTo) {
g2d.moveTo(moveTo.getX(), moveTo.getY());
} else if (element instanceof LineTo lineTo) {
g2d.lineTo(lineTo.getX(), lineTo.getY());
}
}
g2d.stroke();
}
}
我做错了什么吗?或者我需要尝试别的吗?
您没有绘制路径节点
Path 是一个节点,当放置在场景图中时,它将由 JavaFX 系统渲染。但场景图中的节点是 GraphicsContext,它是唯一被渲染的东西。
您使用 Path 作为数据持有者,通过 GraphicsContext 命令手动将其呈现在您的 GraphicsContext 中。您不会将路径的所有属性(笔触和线帽)应用于图形上下文。
如何将附加 Path 属性应用于 GraphicContext
你写道:
要将这些属性应用于 GraphicsContext (gc),您可以编写:
请参阅文档
GraphicsContext
以了解这些方法的描述(以及您可能需要的任何其他图形方法以获得所需的效果,例如Slaw 在评论中提到的setLineJoin )。假设您的输入模型数据不够丰富,无法定义笔画上的属性(例如端点和连接点)。在这种情况下,您可以为代码中的这些属性默认采用假定的适当值(例如
StrokeLineJoin.ROUND
和StrokeLineCap.ROUND
)。替代实施方案
您可以使用 Pane,将 Path 添加为 Pane 的子项,从而将其放置在 SceneGraph 中,而不是自己创建渲染 GraphicsContext 的命令。但这是一种完全不同的方法,我不会在这里进一步讨论。
您可能可以使用
Polyline
而不是路径,但两者都可以工作。