I came across the cool blog by Rakesh Menon the other day “JavaFX – Text Effects”. It got me thinking how many other cool text effects could we do in JavaFX. Quick research for ideas came up with “50 Stunning Photoshop Text Effect Tutorials” blog post on Smashing Magazine. So I picked a couple fun ones and had a go :-)

Neon Text

Neon Sign ScreenshotClick To Run


The first example the came to my attention as I could see how I could have used it in our recent game, was Neon Text @ spoono.com. This is achieved in JavaFX by applying multiple innershadow and dropshadow effects to the text. Here is the complete code for the test application above.

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.*;
import javafx.scene.image.*;
import javafx.scene.shape.*;
import javafx.scene.paint.*;
import javafx.scene.effect.*;
import javafx.scene.control.*;

var width = 600;
var height = 300;
var text:Text;
var textBox:TextBox;
Stage {
    title: "Text Effects: Neon Sign"
    resizable: false
    scene: Scene {
        width: width, height: height
        content: [
            ImageView { image: Image{ url: "{__DIR__}bricks.jpg"} }
            Rectangle {
                width: width, height: height
                fill: RadialGradient {
                    centerX: 0.5, centerY: 0.5
                    radius: 0.7, proportional: true
                    stops: [
                        Stop{offset: 0.4, color: Color.rgb(0,0,0,0.1)}
                        Stop{offset: 1, color: Color.rgb(0,0,0,0.8)}
                    ]
                }
            }
            text = Text {
                effect: Blend{
                    mode: BlendMode.MULTIPLY
                    bottomInput: DropShadow {
                        color: Color.rgb(254,235,66,0.3)
                        offsetX: 5, offsetY: 5
                        radius: 5
                        spread: 0.2
                    }
                    topInput: Blend{
                        mode: BlendMode.MULTIPLY
                        bottomInput: DropShadow {
                            color: Color.web("#f13a00")
                            radius: 20
                            spread: 0.2
                        }
                        topInput: Blend{
                            mode: BlendMode.MULTIPLY
                            bottomInput: InnerShadow {
                                color: Color.web("#feeb42")
                                radius: 9
                                choke: 0.8
                            }
                            topInput: InnerShadow {
                                color: Color.web("#f13a00")
                                radius: 5
                                choke: 0.4
                            }
                        }
                    }
                }
                fill: Color.WHITE
                font : Font { name: "Harlow" size : 110 }
                layoutX: bind (width - text.layoutBounds.width)/2
                layoutY: bind (height/2) + 20
                content: bind textBox.rawText
            }
            textBox = TextBox {
                text:"Neon Sign"
                layoutX: 100
                layoutY: height - 40
                width: width-200
            }
        ]
    }
}

Snow & Ice

Snow & IceClick To Run

This one was based on the Tutsplus.com article Icey Styles in Photoshop but as we do not have the Bevel and Emboss effect that photoshop has yet I had do my best to simulate it with inner and drop shadows.

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.*;
import javafx.scene.shape.*;
import javafx.scene.paint.*;
import javafx.scene.effect.*;
import javafx.scene.control.*;

var width = 600;
var height = 400;
var text:Text;
var textBox:TextBox;
Stage {
    title: "Text Effects: Snow & Ice"
    resizable: false
    scene: Scene {
        width: width
        height: height
        content: [
            Rectangle {
                width: width, height: height
                fill: RadialGradient {
                    centerX: 0.5, centerY: 0.5
                    radius: 0.7, proportional: true
                    stops: [
                        Stop{offset: 0.4, color: Color.web("#34365e")}
                        Stop{offset: 1, color: Color.web("#0d0f3a")}
                    ]
                }
            }
            text = Text {
                effect: Blend{
                    mode: BlendMode.SRC_OVER
                    bottomInput: DropShadow {
                        color: Color.rgb(0,0,0,0.1)
                        offsetX: 8, offsetY: 8
                        radius: 2
                    }
                    topInput: Blend{
                        mode: BlendMode.SRC_OVER
                        bottomInput: DropShadow {
                            color: Color.web("#21233f")
                            radius: 4
                            spread: 0.9
                        }
                        topInput: Blend{
                            mode: BlendMode.DARKEN
                            bottomInput: InnerShadow {
                                color: Color.web("#cee3f4")
                                radius: 5
                                choke: 0.7
                                offsetX: -4, offsetY: -4
                            }
                            topInput: Blend{
                                mode: BlendMode.MULTIPLY
                                bottomInput: InnerShadow {
                                    color: Color.web("#6c7fee")
                                    radius: 7
                                    choke: 0.2
                                    offsetX: 2, offsetY: 2
                                }
                                topInput: InnerShadow {
                                    color: Color.web("#a5ebff")
                                    radius: 4
                                    offsetX: -2, offsetY: -2
                                }
                            }
                        }
                    }
                }
                fill: Color.web("#f7fafb")//web("#e5f5fb")
                strokeWidth: 3
                font : Font {
                    name: "Kabel"
                    size : 120
                }
                layoutX: bind (width - text.layoutBounds.width)/2
                layoutY: bind (height/2) - 20
                content: bind if (textBox.rawText == "") then "Snow \n& Ice" else textBox.rawText
            }
            textBox = TextBox {
                layoutX: 100
                layoutY: height - 40
                width: width-200
            }
        ]
    }
}

Recessed

RecessedClick To Run

After playing with a couple from tutorials I thought I would have a go at one my self. This is a version of the classic web recessed text effect. The designer Alex Buga used this technique to great effect on his website. Unfortunately its down for redesign at the moment but for those who missed it here is a snap shot.

Alex Buga.com

Here is the code for this sample. Its much simpler than the first two as it only uses two effects and a gradient fill on the text. It could be applied to any color just by changing the text fill gradient to be darker version of the background it is sitting on.

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.*;
import javafx.scene.shape.*;
import javafx.scene.paint.*;
import javafx.scene.effect.*;
import javafx.scene.control.*;

var width = 600;
var height = 300;
var text:Text;
var textBox:TextBox;
Stage {
    title: "Text Effects: Recessed"
    resizable: false
    scene: Scene {
        width: width
        height: height
        content: [
            Rectangle {
                width: width, height: height
                fill: LinearGradient {
                    startX: 0, endX: 0, startY: 0, endY: 1
                    stops: [
                        Stop { offset: 0, color: Color.rgb(202,202,202) }
                        Stop { offset: 1, color: Color.rgb(97,97,97) }
                    ]
                }
            }
            text = Text {
                effect: Blend{
                    mode: BlendMode.MULTIPLY
                    bottomInput: DropShadow {
                        color: Color.rgb(255,255,255,0.5)
                        offsetX: 1, offsetY: 1
                        radius: 0
                    }
                    topInput: InnerShadow {
                        color: Color.rgb(0,0,0,0.7)
                        offsetX: 2, offsetY: 2
                        radius: 5
                    }
                }
                fill: LinearGradient {
                    startX: 0, endX: 0, startY: 0, endY: 1
                    stops: [
                        Stop { offset: 0, color: Color.rgb(190,190,190) }
                        Stop { offset: 1, color: Color.rgb(170,170,170) }
                    ]
                }
                font : Font { name: "Arial Black", size : 90 }
                layoutX: bind (width - text.layoutBounds.width)/2
                layoutY: bind (height/2) + 20
                content: bind textBox.rawText
            }
            textBox = TextBox {
                text:"Recessed"
                layoutX: 100
                layoutY: height - 40
                width: width-200
            }
        ]
    }
}

Stand Out

Stand OutClick To Run

One last little example for you, this one is going for a chrome look. This only uses a single simple reflection effect most of it is done with a gradient fill and gradient stroke.

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.*;
import javafx.scene.shape.*;
import javafx.scene.paint.*;
import javafx.scene.effect.*;
import javafx.scene.control.*;

var width = 600;
var height = 300;
var text:Text;
var textBox:TextBox;
Stage {
    title: "Text Effects: Stand Out"
    resizable: false
    scene: Scene {
        width: width
        height: height
        content: [
            Rectangle {
                width: width, height: height
                fill: LinearGradient {
                    startX: 0, endX: 0, startY: 0, endY: 1
                    stops: [
                        Stop { offset: 0, color: Color.web("#6c6a6a") }
                        Stop { offset: 1, color: Color.web("#3e3d3d") }
                    ]
                }
            }
            text = Text {
                effect: Reflection {
                        topOffset: -4
                }
                fill: LinearGradient {
                    startX: 0, endX: 0, startY: 0, endY: 1
                    stops: [
                        Stop { offset: 0.03, color: Color.web("#cccccc") }
                        Stop { offset: 0.499, color: Color.web("#fdfdfd") }
                        Stop { offset: 0.5, color: Color.web("#999999") }
                        Stop { offset: 0.99, color: Color.web("#dddddd") }
                    ]
                }
                stroke: LinearGradient {
                    startX: 0, endX: 0, startY: 0, endY: 1
                    stops: [
                        Stop { offset: 0.03, color: Color.web("#e9e5e5") }
                        Stop { offset: 0.06, color: Color.web("#909090") }
                        Stop { offset: 0.23, color: Color.web("#d1d1d1") }
                        Stop { offset: 0.34, color: Color.web("#9f9f9f") }
                        Stop { offset: 0.60, color: Color.web("#7b7b7b") }
                        Stop { offset: 0.67, color: Color.web("#aeaeae") }
                        Stop { offset: 0.76, color: Color.web("#7b7b7b") }
                        Stop { offset: 0.94, color: Color.web("#676766") }
                        Stop { offset: 0.99, color: Color.web("#e5e5e4") }
                    ]
                }
                font : Font { name: "Arial Black", size : 80 }
                layoutX: bind (width - text.layoutBounds.width)/2
                layoutY: bind (height/2) + 20
                content: bind textBox.rawText
            }
            textBox = TextBox {
                text:"STAND OUT"
                layoutX: 100
                layoutY: height - 40
                width: width-200
            }
        ]
    }
}

I hope you have enjoyed these :-) Have a go see what you can create your self it would be great to be able to put together a “50 Stunning JavaFX Text Effect Tutorials” blog.