如何在 Javafx 中提高 canvas 上的线条绘制速度

How to increase draw speed of lines on canvas in Javafx

我正在用 Javafx 制作一个基本的绘画应用程序。我想知道是否有某种方法可以提高 canvas 上线条的绘制速度。

public class MouseListener implements EventHandler<MouseEvent>{

    @Override
    public void handle(MouseEvent event) {


        if(event.getSource() == canvas){
            canvas.getParent().setCursor(Cursor.CROSSHAIR);

        }


        if(event.getEventType() == MouseEvent.MOUSE_PRESSED){

            x1 = event.getX(); 
            y1 = event.getY(); 

        }else if(event.getEventType() == MouseEvent.MOUSE_MOVED){


            pGraphics.reset();

            x2 = event.getX();
            y2 = event.getY();

            mouseClick = 0; 

            pGraphics.drawLine(x1, y1, x2, y2);

        }


    }


public void drawLine(double x1, double y1, double x2, double y2){

    gc.strokeLine(x1, y1, x2, y2);

}

public void reset()
{
    gc.clearRect(0,0, gc.getCanvas().getWidth(), gc.getCanvas().getHeight());
}

如您所见,绘图非常简单,使用 MouseListener 检测线开始的 (x1, y1) 位置,设置线所在的 (x2, y2) 位置也是如此结束。如您所见,我在绘制后清除了线条,这是我的意图,因为这是应该 "show" 线条应该去的地方的函数,例如在 Microsoft Paint 中使用线条功能。不过,所有这一切的问题在于光标后面的 "laggs" 行,以及光标何时以正确的速度移动。所以问题是:这是否与我的绘制函数、canvas 绘图函数、mouseListener 的刷新率或其他完全或所有因素有关? 真的很感激对此的一些建议。

在您的简单示例中,在重置函数中使用背景色在前一条 x1,y1,x2,y2 线上绘制一条线然后绘制新线会更有效。

但是,如果您移动 1 像素,用户可能不会注意到差异。

如果用户只是在坐标处玩 x1 = 50, y1 = 50 至 x2'=51, y2'=50 或 x2''=50, y2=51 你仍然会清除整个 canvas,这对于只有 1-2 个更改的像素来说是非常愚蠢的,对于可能有数千或数百万像素的 canvas。

但是,无论哪种方式,您都可以在不对用户造成太大影响的情况下跳过一些重绘,以优化某些速度。因此,添加一个 if 来检查与当前 x2 和 y2

相比,前一个 x2 和 y2 之间的差异是否大于 x 个像素

我认为您在这里采用了完全错误的方法。将线节点放在 canvas 顶部并修改这条线的几何数据而不是不断清除 canvas 并重新绘制线会更容易和更有效。 (你还应该问问自己,在这里使用 Canvas 是否是正确的做法,但这是只有你才能决定的事情,因为你没有提供任何关于你实际想用你的 [=12 做什么的信息=].)

问题可能不是绘图速度,而是输入反应滞后,类似于问题中讨论的问题:correct way to move a node by dragging in javafx 2?

尝试链接问题答案中的一些方法,看看是否有帮助。

请注意,如果是这种情况,那么无论您使用 canvas 还是场景图都不会真正对性能问题产生影响,因为与输入事件处理相关的问题与渲染系统。

相关错误跟踪票:Performance issue when tracking mouse events

I see you have given a solution setting the undocumented JVM flag

-Djavafx.animation.fullspeed=true

How do I even begin to do this?

这不是我编写的解决方案,请注意未记录的标志可能会在未来的 Java 版本中被删除或修改其行为(尽管在这种情况下我认为这不太可能)。尽管如此,还是值得一试。

要了解如何设置命令行标志,请参阅:Proper usage of Java -D command-line parameters and also the java man page 标题为“-Dproperty=value”的部分。

它应该像键入 java -Djavafx.animation.fullspeed=true my package.MyMainClassjava -Djavafx.animation.fullspeed=true myjar.jar 一样简单(当然,用我的值替换适合您的应用程序的值)。