首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaFX GraphicsContext clearRect不适用于剪辑掩码

JavaFX GraphicsContext clearRect不适用于剪辑掩码
EN

Stack Overflow用户
提问于 2015-11-12 17:41:28
回答 3查看 2K关注 0票数 1

clearRect方法的GraphicsContext方法的文档声明它使用了当前的剪辑,但它目前并不适用于我。考虑:

代码语言:javascript
复制
GraphicsContext context = canvas.getGraphicsContext2D();
context.beginPath();
context.rect(0,0,100,100); //Set the current path to a rectangle
context.stroke(); //Highlights where the current path is
context.clip();   //Intersect current clip with rectangle
context.fillOval(80, 80, 40, 40); //This correctly draws the oval clipped
context.clearRect(0,0,100,100); //This does nothing at all

上面的代码正确地设置了剪辑掩码,这可以从fillOval正确工作的事实中得到证明,但是clearRect什么也不做(尽管没有context.clip()它正常工作)。为什么会这样呢?

(请注意,我特别需要剪辑掩码才能工作,因为稍后我计划将其设置为特定的形状,以便在非矩形形状中擦除。)

-编辑--

要明确的是,clearRect实际上什么也不做,甚至没有抹去椭圆形。我意识到它不会抹去被抚摸的长方形,但这不是我所关心的。

-编辑2 --

更新到最新的JDK部分解决了这个问题。上面的代码现在正常工作。然而,使用非矩形剪辑掩码仍然存在同样的问题.例如:

代码语言:javascript
复制
GraphicsContext context = canvas.getGraphicsContext2D();
context.beginPath();
context.arc(50, 50, 40, 40, 0, 360); // Make a circular clip mask
context.closePath();
context.clip();
context.fillRect(0, 0, 200, 200); //Draw a circle clipped correctly, shows clip mask is working
context.clearRect(0, 0, 200, 200); //Does nothing

我意识到我可以使用保存和恢复得到一个矩形剪辑面具回来,然后clearRect将工作。然而,我想要能够擦除在非矩形形状。

用于复制此代码的完整代码(通过在eclipse中创建一个新的JavaFX项目并添加上面的行):

代码语言:javascript
复制
public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            BorderPane root = new BorderPane();
            Scene scene = new Scene(root, 400, 400);
            primaryStage.setScene(scene);
            primaryStage.show();

            Canvas canvas = new Canvas(500, 500);
            root.getChildren().add(canvas);

            GraphicsContext context = canvas.getGraphicsContext2D();
            context.beginPath();
            context.arc(50, 50, 40, 40, 0, 360);
            context.closePath();
            context.clip();
            context.fillRect(0, 0, 200, 200);
            context.clearRect(0, 0, 200, 200);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

这应该显示一个空白的屏幕,但圆圈没有被清除。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-11-19 12:47:37

根据Edit 2,这种行为似乎是一个bug。总之,当设置非矩形剪辑时,clearRect没有任何效果。(如果它不适用于您,即使是矩形剪辑,更新到最新的JDK。)我已经为这件事提交了一份错误报告。

票数 1
EN

Stack Overflow用户

发布于 2020-01-16 14:05:17

虽然我同意应该解决这个问题,但面对的事实是,事实并非如此,但我已经想出了一个至少能满足我的具体需要的解决办法。

它是一种使用SVGPath清除基于GraphicsContext的区域的方法。

代码语言:javascript
复制
private void clearPath(GraphicsContext gc, SVGPath path) {
        int xstart = (int) path.getLayoutX();
        int xend = (int) (xstart + path.getLayoutBounds().getMaxX());
        int ystart = (int) path.getLayoutY();
        int yend = (int) (ystart + path.getLayoutBounds().getMaxY());

        PixelWriter pw = gc.getPixelWriter();
        for (int x = xstart; x <= xend; x++) {
            for (int y = ystart; y <= yend; y++) {
                if(path.contains(new Point2D(x, y))) {
                    pw.setColor(x, y, Color.TRANSPARENT);
                }
            }
        }
    }
票数 1
EN

Stack Overflow用户

发布于 2015-11-15 07:26:50

该代码在Windows7和JavaFX 8u40上运行得很好。

您应该做的是提供一个MCVE。没有人能猜出你对GraphicsContext还做了些什么。可能缺少了一个保存恢复,什么的没有。顺便说一句,您的代码缺少closePath()

编辑前回答:

您所面临的问题是JavaFX绘制线的方式。查看节点类的文档:

在设备像素级,整数坐标映射到像素与像素中心之间的角和裂缝上,显示在整数像素位置之间的中点处。因为所有的坐标值都是用浮点数指定的,所以坐标可以精确地指向这些角(当浮点值有确切的整数值时)或指向像素上的任何位置。例如,坐标(0.5,0.5)将指向舞台上左上像素的中心。类似地,尺寸为10×10的(0,0)矩形将从舞台上左上像素的左上角到第10扫描线上第10像素的右下角。该矩形内最后一个像素的像素中心将位于坐标(9.5,9.5)。

这就是为什么你在右边和底部都有一条细线。台词不是脆脆

我建议您将矩形移动到中心,并使用填充方法使其对您更加可见。

没有clearRect的代码:

使用clearRect的代码:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33677829

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档