Movatterモバイル変換


[0]ホーム

URL:


Skip to content
Search Gists
Sign in Sign up

Instantly share code, notes, and snippets.

@dlemmermann
Last activeAugust 28, 2018 08:25
    • Star(1)You must be signed in to star a gist
    • Fork(0)You must be signed in to fork a gist
    Save dlemmermann/f9bcf4f2a883fff5d0d64faff1b31b87 to your computer and use it in GitHub Desktop.
    This code shows how you can use clipping in JavaFX in combination with the alpha channel to implement fade in / out effects (not animations).
    importjavafx.beans.property.DoubleProperty;
    importjavafx.beans.property.SimpleDoubleProperty;
    importjavafx.beans.property.SimpleObjectProperty;
    importjavafx.scene.Node;
    importjavafx.scene.control.Control;
    importjavafx.scene.control.Skin;
    publicclassMaskedViewextendsControl {
    publicMaskedView(Nodecontent) {
    setContent(content);
    }
    @Override
    protectedSkin<?>createDefaultSkin() {
    returnnewMaskedViewSkin(this);
    }
    privatefinalSimpleObjectProperty<Node>content =newSimpleObjectProperty<>(this,"content");
    publicfinalNodegetContent() {
    returncontent.get();
    }
    publicfinalSimpleObjectProperty<Node>contentProperty() {
    returncontent;
    }
    publicfinalvoidsetContent(Nodecontent) {
    this.content.set(content);
    }
    privatefinalDoublePropertyfadingSize =newSimpleDoubleProperty(this,"fadingSize",120);
    publicfinaldoublegetFadingSize() {
    returnfadingSize.get();
    }
    publicfinalDoublePropertyfadingSizeProperty() {
    returnfadingSize;
    }
    publicfinalvoidsetFadingSize(doublefadingSize) {
    this.fadingSize.set(fadingSize);
    }
    }
    importjavafx.beans.InvalidationListener;
    importjavafx.beans.WeakInvalidationListener;
    importjavafx.scene.Group;
    importjavafx.scene.Node;
    importjavafx.scene.control.SkinBase;
    importjavafx.scene.layout.StackPane;
    importjavafx.scene.paint.Color;
    importjavafx.scene.paint.CycleMethod;
    importjavafx.scene.paint.LinearGradient;
    importjavafx.scene.paint.Stop;
    importjavafx.scene.shape.Rectangle;
    publicclassMaskedViewSkinextendsSkinBase<MaskedView> {
    privatefinalRectangleleftClip;
    privatefinalRectanglerightClip;
    privatefinalRectanglecenterClip;
    privatefinalGroupgroup;
    privatefinalStackPanestackPane;
    publicMaskedViewSkin(MaskedViewview) {
    super(view);
    leftClip =newRectangle();
    rightClip =newRectangle();
    centerClip =newRectangle();
    centerClip.setFill(Color.BLACK);
    leftClip.setManaged(false);
    centerClip.setManaged(false);
    rightClip.setManaged(false);
    group =newGroup(leftClip,centerClip,rightClip);
    stackPane =newStackPane();
    stackPane.setManaged(false);
    stackPane.setClip(group);
    getChildren().add(stackPane);
    view.contentProperty().addListener((observable,oldContent,newContent) ->buildView(oldContent,newContent));
    buildView(null,view.getContent());
    view.widthProperty().addListener(it ->updateClip());
    view.fadingSizeProperty().addListener(it ->updateClip());
    }
    privatefinalInvalidationListenertranslateXListener =it ->updateClip();
    privatefinalWeakInvalidationListenerweakTranslateXListener =newWeakInvalidationListener(translateXListener);
    privatevoidbuildView(NodeoldContent,NodenewContent) {
    if (oldContent !=null) {
    stackPane.getChildren().clear();
    oldContent.translateXProperty().removeListener(weakTranslateXListener);
    }
    if (newContent !=null) {
    stackPane.getChildren().setAll(newContent);
    newContent.translateXProperty().addListener(weakTranslateXListener);
    }
    updateClip();
    }
    privatevoidupdateClip() {
    finalMaskedViewview =getSkinnable();
    Nodecontent =view.getContent();
    if (content !=null) {
    finaldoublefadingSize =view.getFadingSize();
    if (content.getTranslateX() <0) {
    leftClip.setFill(newLinearGradient(0,0,fadingSize,0,false,CycleMethod.NO_CYCLE,newStop(0,Color.TRANSPARENT),newStop(1,Color.BLACK)));
    }else {
    leftClip.setFill(Color.BLACK);
    }
    if (content.getTranslateX() +content.prefWidth(-1) >view.getWidth()) {
    rightClip.setFill(newLinearGradient(0,0,fadingSize,0,false,CycleMethod.NO_CYCLE,newStop(0,Color.BLACK),newStop(1,Color.TRANSPARENT)));
    }else {
    rightClip.setFill(Color.BLACK);
    }
    }
    view.requestLayout();
    }
    @Override
    protectedvoidlayoutChildren(doublecontentX,doublecontentY,doublecontentWidth,doublecontentHeight) {
    finaldoublefadingSize =Math.min(contentWidth /2,getSkinnable().getFadingSize());
    stackPane.resizeRelocate(snapPosition(contentX),snapPosition(contentY),snapSpace(contentWidth),snapSpace(contentHeight));
    resizeRelocate(leftClip,snapPosition(contentX),snapPosition(contentY),snapSpace(fadingSize),snapSpace(contentHeight));
    resizeRelocate(centerClip,snapPosition(contentX +fadingSize),snapPosition(contentY),snapSpace(contentWidth -2 *fadingSize),snapSpace(contentHeight));
    resizeRelocate(rightClip,snapPosition(contentX +contentWidth -fadingSize),snapPosition(contentY),snapSpace(fadingSize),snapSpace(contentHeight));
    }
    privatevoidresizeRelocate(Rectanglerect,doublex,doubley,doublew,doubleh) {
    rect.setLayoutX(x);
    rect.setLayoutY(y);
    rect.setWidth(w);
    rect.setHeight(h);
    }
    }
    Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

    [8]ページ先頭

    ©2009-2025 Movatter.jp