java - Text moving animation -
i new animations in javafx, , basic idea of how works; need starting keyframe , and ending one, play it.
what want have list of strings, say, "0, 1, 2, 3, 4, 5...10", , variable, index
. want have 3 of them on screen @ time inside 3 different text
objects:
0 1 2
in example above, index = 0
. if index = 1
, this:
1 2 3
you idea, want do, every time index
increments (it have property
), there animation of numbers trading spaces.
so (symbol numbers represent fading):
index = 0 : 0 1 2 index = 1 : ) 1 2# frame --- : ) 1 2 # frame --- : )1 2 # frame --- : 1 2 3
so in theory, lists stores these numbers infinite can't (shouldn't) have separate text
object each number. can't figure out how should done, keyframes moving text
object complicates things.
here sample.
import javafx.animation.*; import javafx.application.application; import javafx.beans.binding.stringbinding; import javafx.beans.property.*; import javafx.geometry.*; import javafx.scene.scene; import javafx.scene.control.*; import javafx.scene.layout.*; import javafx.scene.paint.color; import javafx.stage.stage; import javafx.util.duration; import java.util.list; import java.util.stream.*; public class numberswitcher extends application { private static final int num_nums_displayed = 3; private static final duration transition_time = duration.seconds(0.5); private final integerproperty idx = new simpleintegerproperty(0); private final integerproperty toidx = new simpleintegerproperty(0); private final list<label> labels = intstream.range(0, num_nums_displayed) .maptoobj( this::createlabel ) .collect(collectors.tolist()); private final button incrementbutton = new button("increment"); @override public void start(stage stage) { stage.setscene( new scene( createlayout(), color.palegreen ) ); stage.show(); enabletransitions(); } private stackpane createlayout() { incrementbutton.setstyle("-fx-base: darkslateblue; -fx-text-fill: papayawhip; -fx-font-size: 20px;"); hbox numbers = new hbox(10); numbers.getchildren().addall(labels); numbers.setpadding(new insets(15)); numbers.setmaxwidth(hbox.use_pref_size); vbox layout = new vbox( 15, numbers, incrementbutton ); layout.setalignment(pos.center); layout.setpadding(new insets(15)); layout.setstyle("-fx-background-color: null;"); stackpane centered = new stackpane(layout); centered.setstyle("-fx-background-color: null;"); return centered; } private label createlabel(final int i) { label label = new label(); label.setstyle( "-fx-font-size: 50px; -fx-font-family: monospace; -fx-text-fill: midnightblue;" ); label.textproperty().bind(new stringbinding() { { super.bind(idx); } @override protected string computevalue() { return "" + ((idx.get() + i) % 10); } }); return label; } private void enabletransitions() { paralleltransition changenumbers = new paralleltransition( createfadefirst() ); intstream.range(1, labels.size()) .maptoobj(this::createmoveleft) .foreachordered( moveleft -> changenumbers.getchildren().add(moveleft) ); changenumbers.setonfinished(e -> idx.set(toidx.get())); toidx.addlistener((observable, oldvalue, newvalue) -> changenumbers.play() ); // can disable incrementing while transition running, // kind of annoying, chose not to. // incrementbutton.disableproperty().bind( // changenumbers.statusproperty().isequalto( // pausetransition.status.running // ) // ); incrementbutton.setonaction(e -> { if (idx.get() != toidx.get()) { idx.set(toidx.get()); } toidx.set((toidx.get() + 1) % 10); }); } private fadetransition createfadefirst() { fadetransition fadefirst = new fadetransition( transition_time, labels.get(0) ); fadefirst.setfromvalue(1); fadefirst.settovalue(0); fadefirst.setonfinished(e -> labels.get(0).setopacity(1)); return fadefirst; } private translatetransition createmoveleft(int i) { translatetransition moveleft = new translatetransition( transition_time, labels.get(i) ); double dx = labels.get(i).getboundsinparent().getminx() - labels.get(i-1).getboundsinparent().getminx(); moveleft.setfromx(0); moveleft.settox(-dx); moveleft.setonfinished(e -> labels.get(i).settranslatex(0)); return moveleft; } public static void main(string[] args) { launch(args); } }
answers additional questions
i see translating nodes, but, @ point change location in hbox?
locations (e.g. layoutx , layouty) in hbox sample never changed after laid out in hbox. hbox layout manager, set layoutx , layouty co-ordinates of items in hbox automatically. hbox layout algorithm place each item in it's child list sequentially left right (by default) , size each item it's preferred size. hbox works based upon dirty flags, re-layout components inside when needs (e.g. components change or css style components change or available area hbox changes), none of occurs in sample.
are translating them, switching text, resetting translation?
yes.
could give quick overview of how works?
three labels added hbox. monospaced font , same number of characters used each label, each label equal width. 2 indices recorded. 1 current index in text area displayed characters, other the toidx next index in text array moved to. increment button provided increment toidx. change listener placed on toidx when changed, kicks off set of animations, first animation fades first label, other animations move remaining labels next position left. when animation complete, translation of each label set 0, each of moved labels move original position. also, once animation complete, current index set toidx. binding used automatically update text in each of labels when toidx updated.
the effect that, when increment button pressed, number in first label fades, numbers in labels right move left, , once there, return original positions, values set next highest number. provides effect requested in question.
Comments
Post a Comment