Comment créer une scène transparente JavaFX avec des ombres sur la frontière?
j'ai lu de nombreuses questions sur la transparence et les ombres, mais je ne pense pas que j'ai vu cette question traitée.
je suis capable de créer avec succès une fenêtre à la fois avec transparence et une ombre, mais je ne peux pas comprendre comment faire que l'ombre couleur n'affecte pas la couleur de transparence.
par exemple, le code suivant crée une fenêtre avec une transparence grise et une ombre rouge. Cependant, la couleur rouge affecte le transparence de la fenêtre principale aussi, mais je veux seulement que l'ombre s'étende en dehors du bord des fenêtres.
donc ce que j'obtiens c'est:
mais ce que je veux c'est: (image éditée manuellement)
des idées pour faire ça?
mon code d'essai:
@Override
public void start(Stage stage) throws Exception {
stage.initStyle(StageStyle.TRANSPARENT);
StackPane stackPane = new StackPane();
stackPane.setStyle(
"-fx-background-color: rgba(255, 255, 255, 0.5);" +
"-fx-effect: dropshadow(gaussian, red, 50, 0, 0, 0);" +
"-fx-background-insets: 50;"
);
Scene scene = new Scene(stackPane, 450, 450);
scene.setFill(Color.TRANSPARENT);
stage.setScene(scene);
stage.show();
}
1 réponses
j'ai été un peu curieux pendant un certain temps sur la façon d'atteindre un tel effet d'ombre où l'effet d'ombre ne se manifeste pas à travers le contenu translucide du dessus.
la solution que j'ai trouvée était d'utiliser la coupure sur l'ombre de sorte qu'elle n'affiche qu'en dehors du contenu translucide qu'elle ombrage.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.*;
import org.scenicview.ScenicView;
// Java 8 code
public class ClippedShadow extends Application {
private static final int shadowSize = 50;
@Override public void start(final Stage stage) {
stage.initStyle(StageStyle.TRANSPARENT);
StackPane stackPane = new StackPane(createShadowPane());
stackPane.setStyle(
"-fx-background-color: rgba(255, 255, 255, 0.5);" +
"-fx-background-insets: " + shadowSize + ";"
);
Scene scene = new Scene(stackPane, 450, 450);
scene.setFill(Color.TRANSPARENT);
stage.setScene(scene);
stage.show();
}
// Create a shadow effect as a halo around the pane and not within
// the pane's content area.
private Pane createShadowPane() {
Pane shadowPane = new Pane();
// a "real" app would do this in a CSS stylesheet.
shadowPane.setStyle(
"-fx-background-color: white;" +
"-fx-effect: dropshadow(gaussian, red, " + shadowSize + ", 0, 0, 0);" +
"-fx-background-insets: " + shadowSize + ";"
);
Rectangle innerRect = new Rectangle();
Rectangle outerRect = new Rectangle();
shadowPane.layoutBoundsProperty().addListener(
(observable, oldBounds, newBounds) -> {
innerRect.relocate(
newBounds.getMinX() + shadowSize,
newBounds.getMinY() + shadowSize
);
innerRect.setWidth(newBounds.getWidth() - shadowSize * 2);
innerRect.setHeight(newBounds.getHeight() - shadowSize * 2);
outerRect.setWidth(newBounds.getWidth());
outerRect.setHeight(newBounds.getHeight());
Shape clip = Shape.subtract(outerRect, innerRect);
shadowPane.setClip(clip);
}
);
return shadowPane;
}
public static void main(String[] args) {
launch(args);
}
}
Liées
cette réponse est en quelque sorte une suite à d'autres questions sur les fenêtres translucides et les vitres qui avaient plusieurs parties, dont l'une que je n'ai pas eu le temps de mettre en œuvre concernant: Comment obtenir un effet d'ombre halo drop sur une fenêtre translucide? (cette question)