Effect chaining - CSS Equivalent for effect.setInp

2019-08-02 05:41发布

I need to apply multiple effects ( mainly innershadow and dropshadow ) through CSS. But I'm not able to chain these effects.
Is there CSS equivalent for setInput() of javafx.scene.effect.Effect? So far I found only this link. It indicates something about fixes but no details about how to use chaining.
EDIT: Further explanation if question is not clear:
to apply effect through css, -fx-effect is used. I need to apply multiple effects to same node. How to "chain" these effects in CSS? This can be easily done through code using setInput() mentioned earlier. TIA

2条回答
唯我独甜
2楼-- · 2019-08-02 05:50

As @Lorand mentions, it's not possible to chain effects via CSS.

He also gives the link of a well known example of chaining effects via code.

I'll provide a solution with FXML, using that same example to compare results.

By (updated) code:

@Override
public void start(Stage primaryStage) throws IOException { 
    Circle circle = new Circle(64,64,48);
    Paint fill = new LinearGradient(0, 0, 0, 1, 
                                true, CycleMethod.NO_CYCLE,
                                new Stop(0.0, Color.rgb(207, 0, 58)),
                                new Stop(1.0, Color.rgb(129, 0, 33)));
    circle.setFill(fill);
    circle.setStroke(null);
    InnerShadow innerShadow = new InnerShadow(BlurType.GAUSSIAN,Color.color(0, 0, 0, 0.65),5,0,0,-5);
    InnerShadow innerGlow = new InnerShadow(BlurType.GAUSSIAN,Color.color(1, 1, 1, 0.65),5,0,0,5);
    innerGlow.setInput(innerShadow);

    DropShadow dropShadow = new DropShadow(BlurType.GAUSSIAN, Color.color(0, 0, 0, 0.65), 5, 0, 0, 0);
    dropShadow.setInput(innerGlow);

    circle.setEffect(dropShadow);

    VBox vBox = new VBox(circle);
    vBox.setAlignment(Pos.CENTER);
    Scene scene = new Scene(vBox,200,200,Color.web("#a9a9a9"));
    primaryStage.setTitle("Chain effect by code");
    primaryStage.setScene(scene);
    primaryStage.show();
}

Note that the effects are defined in reverse order of application. For the sake of clarity, we could also write this:

circle.setEffect(dropShadow);
dropShadow
    .setInput(innerGlow);
    innerGlow
        .setInput(innerShadow);

Now let's use Scene Builder 2.0 to create an FXML file circle.fxml.

Once we have the circle, we set the DropShadow effect, and then we edit the effect, and select Replace Effect Input option from the menu button:

Applying chain effect 1

Then choose InnerShadow, define the effect, and select again Replace Effect Input, selecting again InnerShadow:

Applying chain effect 2

Define the effect, save and exit. This will be the source code:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.*?>
<?import javafx.scene.effect.*?>
<?import javafx.scene.paint.*?>
<?import java.lang.*?>
<?import javafx.scene.shape.*?>

<VBox alignment="CENTER" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Circle radius="48.0" stroke="TRANSPARENT" strokeType="INSIDE" strokeWidth="1.0">
         <fill>
            <LinearGradient endX="0.0" endY="1" proportional="true" startX="0" startY="0">
               <stops>
                  <Stop color="#cf003a" offset="0.0" />
                  <Stop color="#810021" offset="1.0" />
               </stops>
            </LinearGradient>
         </fill>
         <effect>
             <DropShadow blurType="GAUSSIAN" color="#000000a6" radius="5.0">
               <input>
                  <InnerShadow blurType="GAUSSIAN" color="#ffffffa6" offsetY="5.0" radius="5.0">
                     <input>
                        <InnerShadow blurType="GAUSSIAN" color="#000000a6" offsetY="-5.0" radius="5.0" />
                     </input>
                  </InnerShadow>
               </input>
            </DropShadow>
         </effect>
      </Circle>
   </children>
</VBox>

Finally, loading this file in our scene:

@Override
public void start(Stage primaryStage) throws IOException { 
    VBox vBox = FXMLLoader.load(getClass().getResource("circle.fxml"));

    Scene scene = new Scene(vBox,200,200,Color.web("#a9a9a9"));
    primaryStage.setTitle("Chain effect by FXML");
    primaryStage.setScene(scene);
    primaryStage.show();
}

This will be the result:

Chain of Effects

查看更多
一纸荒年 Trace。
3楼-- · 2019-08-02 06:13

It's currently not possible in Java 7 nor in Java 8 to chain effects or apply multiple effects via CSS. See the Oracle CSS Documentation.

It's also mentioned in the CSS vs Code article.

查看更多
登录 后发表回答