2017-10-20 44 views
0

J'ai commencé à jouer avec JavaFXGraphicsContext. Surtout la partie Clipping est intéressante pour moi.L'écrêtage JavaFX produit un «ticket de grattage de loterie». Effet

j'ai donc essayé de créer des graphiques et de créer un masque d'écrêtage pour elle (un simple rectangle, qui se déplace autour)

mais je remarqué un comportement étrange avec elle (pas sûr si cela est un bug ou à cause incorrecte code useage)

ci-dessous vous pouvez trouver un exemple d'application pour montrer le problème.

Description de ce que je pensais de mon code: toile blanche avec un rectangle de MAGENTA avec le texte, qui est visible au-dessus du magenta (bien qu'il soit tiré à travers)

fait c'est exactement ce que vous voyez premier !

Lorsque vous déplacez la fenêtre d'application, le rectangle MAGENTA se déplace (comme prévu)! mais le remplissage ANTIQUEWHITE devient visible (ce que je n'attendais pas) et toute zone qui a été couverte avec MAGENTA est maintenant visible (pas de coupure)

ANTIQUEWHITE et MAGENTA stuff, est utilisé pour rendre plus évident que quelque chose ne va pas. Comme toute la toile est effacée au début et qu'une seule coupure est faite, il ne devrait pas y avoir de problème sur repeindre (ou peindre sur un dessin ancien)

lancez l'application et déplacez-la pour voir le «ticket de loterie» effectuer

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

Quelle est votre question? – Sedrick

+0

évidemment la question est de savoir comment résoudre ce comportement étrange et obtenir la zone coupée qui est MAGENTA – lumo

Répondre

2

De l'documentation for restore():

Notez que le chemin actuel n'est pas restauré.

Donc tous les appels gc.rect() que vous faites s'accumulent dans un seul chemin qui est utilisé comme le clip.

Si vous ajoutez

gc.beginPath(); 

pour dégager le chemin au début du bloc if (clip), vous voyez le comportement que je pense que vous attendez.

+0

merci! en fait, je pensais que le chemin est effacé après chaque peinture - et beginPath n'est pas nécessaire. – lumo