对齐像素并避免模糊的通用机制

General mechanism to snap to pixel and avoid blurryness

我正在创建一个由 2 个相互重叠的矩形组成的健康栏。内层显示当前生命值,外层显示总生命值。

问题

血条模糊不清。

到目前为止我得到了什么

我读过有关 e. G。 ,但只解决了部分问题。

截图,上图没有0.5,下图加了0.5。

代码如下:

private class HealthBar extends Pane {

    Rectangle outerHealthRect;
    Rectangle innerHealthRect;

    public HealthBar() {

        double height = 10;

        double outerWidth = 60;
        double innerWidth = 40;

        // using 0.5, otherwise it would be blurry
        double x=snap( 0.0);
        double y=snap( 0.0);

        outerHealthRect = new Rectangle( x, y, outerWidth, height);
        outerHealthRect.setStroke(Color.BLACK);
        outerHealthRect.setFill(Color.WHITE);

        innerHealthRect = new Rectangle( x, y, innerWidth, height);
        innerHealthRect.setStroke(Color.TRANSPARENT);
        innerHealthRect.setFill(Color.LIMEGREEN);

        getChildren().addAll( outerHealthRect);
        getChildren().addAll( innerHealthRect);

    }

    public void setValue( double value) {
        innerHealthRect.setWidth( snap( outerHealthRect.getWidth() * value));
    }

    private double snap( double value) {
        return (int) value + 0.5;
    }
}

在我出于调试目的应用缩放后,很明显透明笔划不被视为与带颜色的笔划相同宽度的透明线:

问题

我可以尝试使用 canvas 的不同方法,但这些是影响您必须设置 JavaFX 应用程序的方式的一般性问题。

非常感谢。

不要捕捉填充。我链接到的问题解释说,线条是在像素上绘制的(通过中间 - 这需要一个完整的像素),这意味着 +0.5,因为坐标在像素之间。

填充需要在整个像素上绘制到它们之间的 space。

public HealthBar() {

    double height = 10;

    double outerWidth = 60;
    double innerWidth = 40;

    double x=10,y=10;//away from pane edge just to see better

    outerHealthRect = new Rectangle( snap(x), snap(y), outerWidth, height);
    outerHealthRect.setStroke(Color.BLACK);
    outerHealthRect.setFill(Color.WHITE);

    //just move green bar right a bit to see edges
    //and move it down 1 pix so it's not over the black edge
    //this means height is -1 as well
    innerHealthRect = new Rectangle( x+11, y+1, innerWidth, height-1);
    innerHealthRect.setFill(Color.LIMEGREEN);
    //no need to draw transparent anything

    getChildren().addAll( outerHealthRect);
    getChildren().addAll( innerHealthRect);

}