我一直很好奇如何实现这样的阴影效果,其中阴影效果不会透过半透明顶部内容显示出来。
我想出的解决方案是在阴影上使用裁剪,这样它只会显示在被其投射阴影的半透明内容之外。
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;
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();
}
private Pane createShadowPane() {
Pane shadowPane = new Pane();
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);
}
}
相关
这个答案是对一些关于半透明窗口和面板的其他问题的跟进,其中有多个部分,我没有实现其中一个关于如何在半透明窗口上获得光晕阴影效果的问题?(这个问题)