Normally this is a bitmap effect, but in JavaFx all is nodes…
So I use Nodes :) and this image (from http://forum.deltaforceteam.de/forum/viewtopic.php?f=3&t=127 )
The viewports variable is a sequence which contains for each character the portion of the image corresponding to it.
The line variable is a concatenation of the viewports of the letters to build the text shown in the screen.
And the timeline is used to scroll the text
I add a Reflection effect too :)
Main.fx |
package scrolllinedemo; /* * Main.fx * * Created on 12 déc. 2009, 00:08:52 */ import javafx.stage.Stage; import javafx.scene.Scene; import javafx.geometry.Rectangle2D; import javafx.scene.image.ImageView; import javafx.scene.image.Image; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.scene.effect.Reflection; import javafx.scene.Group; import javafx.scene.shape.Rectangle; import javafx.scene.control.TextBox; import javafx.scene.control.Button; /** * @author Patrick */ def letterWidth = 32; def letterHeight = 32; var blankLine = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; var text = "Hello, this is my first old school scroll line demo. by Patrick ! "; var textFont = StringConverter.stringToFont(text); insert blankLine before textFont[0]; var textLength = sizeof(textFont)-1; insert blankLine into textFont; var textIncrement = 0; var font = Image { url: "{__DIR__}img/font.png" } def viewports = for (row in [0..5]) { for (col in [0..9]) { Rectangle2D{ minX: col * letterWidth, minY: row * letterHeight, height: letterWidth, width: letterHeight } } } var line = bind for (col in [0..10]) { //10 chars (320 = 32*10) ImageView { x: bind (col * letterWidth) -scrollX , y: 0, viewport: bind viewports[textFont[col+textIncrement]] image: font } } var scrollX =0; var t = Timeline { repeatCount: Timeline.INDEFINITE keyFrames : [ KeyFrame { time : 0s canSkip : true }, KeyFrame { time : 8ms canSkip : true action: function(): Void{ var tempX = scrollX+1; var tempTextIncrement = textIncrement; if (tempX>=32){ tempX = 0; if (textIncrement<textLength) then tempTextIncrement++ else tempTextIncrement = 0; } textIncrement = tempTextIncrement; scrollX = tempX; } } ] } t.play(); var tb:TextBox; Stage { title: "Application title" width: 335 height: 150 scene: Scene { content: [ Group { content:Group{ clip:Rectangle { width: 320 height: 64 } content: line } effect:Reflection { fraction: 0.75 topOffset: 0.0 topOpacity: 0.5 bottomOpacity: 0.0 } } tb = TextBox { text: "try to type your text here... and press on GO!" columns: 30 selectOnFocus: true translateY:70 } Button { text: "GO!" action: function() { var textFontTemp = StringConverter.stringToFont(tb.text); insert blankLine before textFontTemp[0]; textLength = sizeof(textFontTemp)-1; insert blankLine into textFontTemp; textFont = textFontTemp; textIncrement =0; } translateY:70 translateX:275 } ] } }download StringConverter.fx