2017-10-20 102 views
0

我開始玩JavaFXGraphicsContext。 特別是剪輯部分對我來說很有趣。JavaFX裁剪產生「彩票刮刮票」效果

所以我試圖創建一些圖形和爲它創建剪貼蒙版(一個簡單的矩形,其左右移動)

,但我注意到它的一些奇怪的行爲(不知道這是一個錯誤,或由於不正確代碼使用)

下面你可以找到一個示例應用程序來顯示該問題。

說明什麼,我從我的代碼預期: 白色帆布與洋紅色矩形文本,這是品紅上述唯一可見的(雖然它橫跨繪製)

其實這正是你所看到的第一

當您移動應用程序窗口時,MAGENTA矩形移動(如預期)!但ANTIQUEWHITE填充變得可見(我從未預料過),任何曾經被MAGENTA覆蓋過的區域現在都可見(無裁剪)

ANTIQUEWHITE和MAGENTA的東西,用來使它更明顯地出現問題。因爲整個畫布在開始時被清除並且只有一個裁剪被完成,所以對於重新繪製(或在舊繪圖上繪畫)應該不是問題

啓動應用程序並移動它以查看「彩票刮刮票」影響

public class ClippingExampleApp extends Application { 

    private boolean clip = true; 
    private static Bounds clippingArea = new BoundingBox(100, 50, 300, 300); 

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

    @Override 
    public void start(Stage primaryStage) { 
     primaryStage.setTitle("Clipping Test App"); 
     primaryStage.setX(100); 
     primaryStage.setY(50); 

     Group root = new Group(); 
     Canvas canvas = new Canvas(640, 480); 
     root.getChildren().add(canvas); 
     primaryStage.setScene(new Scene(root)); 

     ChangeListener<Number> updateBounds = new ChangeListener<Number>() { 

      @Override 
      public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) { 
       clippingArea = new BoundingBox(primaryStage.getX(), primaryStage.getY(), 300, 300); 
       draw(canvas, clip); 
      } 
     }; 
     primaryStage.yProperty().addListener(updateBounds); 
     primaryStage.xProperty().addListener(updateBounds); 
     primaryStage.widthProperty().addListener(updateBounds); 
     primaryStage.heightProperty().addListener(updateBounds); 

     primaryStage.show(); 
     clippingArea = new BoundingBox(primaryStage.getX(), primaryStage.getY(), 300, 300); 
     draw(canvas, clip); 
    } 

    private static void draw(Canvas canvas, boolean clip) { 
     GraphicsContext gc = canvas.getGraphicsContext2D(); 
     // CLEAR THE COMPLETE CANVAS 
     gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight()); 
     gc.save(); 
     if (clip) { 
      // clipping rect 
      gc.rect(clippingArea.getMinX(), clippingArea.getMinY(), clippingArea.getWidth(), clippingArea.getHeight()); 
      gc.clip(); 

      // fill the whole background (this should only affect the clipped 
      // area 
      gc.setFill(Color.ANTIQUEWHITE); 
      gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight()); 
      // this should overlap the Color.ANTIQUEWHITE - so no ANTIQUEWHITE is visible 
      gc.setFill(Color.MAGENTA); 
      gc.fillRect(clippingArea.getMinX(), clippingArea.getMinY(), clippingArea.getWidth(), clippingArea.getHeight()); 

      // finally fill the text, which sould only be visible where the magenta rect is... 
      String text = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua."; 
      gc.setFill(Color.BLACK); 
      gc.fillText(text, 50, 100); 
     } 
     gc.restore(); 
    } 
} 
+0

你的問題是什麼? – Sedrick

+0

顯然這個問題是如何解決這個奇怪的行爲,並得到該地區削減,這是謝謝你的MAGENTA – lumo

回答

2

documentation for restore()

注意,電流通路不會恢復。

所以所有的gc.rect()調用你累積到一個單一的路徑作爲剪輯。

如果添加

gc.beginPath(); 

if (clip)塊的開始清路,你看到的行爲,我認爲你期待。

+0

!實際上我認爲在每次繪製之後路徑都會被清除 - 並且不需要beginPath。 – lumo