我目前正在使用 JavaFX 创建绘画应用程序。我目前有一个绘制函数(称为squiggle),它从鼠标事件中获取一系列点,并创建连接每个点的线段。当我只处理 1px 线段时,一开始这很好。此后,我使用
GraphicsContent.setStroke()
实现了笔划宽度更改器,这突出了线段自然是矩形形状的事实。这会导致线条(尤其是使用较粗的笔画宽度时)变得非常模糊且通常很奇怪。
我的想法是用这些点创建一系列圆圈,以赋予其更真实的画笔感觉,但这不起作用,因为圆圈没有连接,并且每个点之间留下了很大的间隙。
当我尝试用线段连接每个圆时,它只会返回与之前相同的问题,因为矩形通常会遮住圆的阴影。
我也尝试过使用路径,这是我以前从未尝试过的。这只会让我回到原来的问题,但现在我在绘图时遇到更多的延迟。这可能是因为我实施错误,但此时,我什至不确定路径是否会帮助我。
这是我在 Squiggle 类中的
toPath
方法:
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.setStroke(this.getColor());
path.setStrokeWidth(this.getStrokeWidth());
path.setStrokeLineCap(StrokeLineCap.ROUND);
然后将这些属性应用到 GraphicsContext (gc),您可以这样写:
gc.setStroke(path.getStroke());
gc.setLineWidth(path.getStrokeWidth());
gc.setLineCap(path.getStrokeLineCap());
您可以使用窗格,通过将路径添加为窗格的子项将路径放置在场景图形中,而不是自己创建命令来渲染 GraphicsContext。 但这是一种完全不同的方法,我不会在这里进一步讨论。