Tải bản đầy đủ (.pdf) (22 trang)

Effect - Visual Transitions

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (244.65 KB, 22 trang )

C H A P T E R 3

■ ■ ■

49

Effect: Visual Transitions
Visual transitions are animations that introduce a new visual component to the scene, usually by
replacing a component already in the scene. A good example of a visual transition is a fade-out on TV—it
is a visual effect that informs the viewer that something is ending and something new has started.
Application designers take advantage of visual transitions to inform the user that new content is on
the screen, perhaps because of a navigation choice made by the user. This chapter explores how visual
transitions are implemented in JavaFX by setting up a scene where the transitions can be viewed and the
details of each transition inspected.
While this book uses the term “transition” to describe a change in an application, the JavaFX API
does have a class called javafx.animation.transition.Transition. This is not what we mean here by
transition, though the classes contained in the package javafx.animation.transition could certainly be
used when implementing a visual transition.
Getting Started
The visual transitions in the following sections all work on the same principle: They are functions that
take a node in the scene and replace it with another node. An animation is also involved to make the
replacement interesting to the user. It is important when implementing these functions that at the end
of the animation, the nodes are left in a predictable state. For example, if a node passed into the
transition function has its opacity set to .6 and the transition adjusts that value, at the end of the
transition, the opacity should be set back to .6. This will cut down on unwanted side-effects.
The code in Listing 3-1 implements a simple scene containing a node to be transitioned and a
number of buttons that trigger each transition type covered in this chapter.
Listing 3-1. Main.fx
package org.lj.jfxe.chapter3;

import javafx.stage.Stage;


import org.lj.jfxe.chapter3.example1.*;
import org.lj.jfxe.chapter3.example2.*;
import org.lj.jfxe.chapter3.example3.*;
import org.lj.jfxe.chapter3.example4.*;
import org.lj.jfxe.chapter3.example5.*;
import javafx.scene.Scene;
CHAPTER 3 ■ EFFECT: VISUAL TRANSITIONS

50

import javafx.scene.control.Button;
import javafx.scene.paint.Color;
import javafx.scene.Node;
import javafx.scene.layout.VBox;

/**
* @author lucasjordan
*/

var nodeA = ExampleNodeA{
translateX: 320 - 160
translateY: 240 - 120
}
var nodeB = ExampleNodeB{
translateX: 320 - 160
translateY: 240 - 120
}

var displayed:Node = nodeA;
var notDisplayed:Node = nodeB;


var disabled = false;

var fadeButton = Button{
text: "Fade Transition"
action: function(){
disabled = true;
FadeReplace.doReplace(displayed, notDisplayed, doAfter);
}
disable: bind disabled;
}

var slideButton = Button{
text: "Slide Transition"
action: function(){
disabled = true;
SlideReplace.doReplace(displayed, notDisplayed, doAfter);
}
disable: bind disabled;
}

var flipButton = Button{
text: "Flip Transition"
action: function(){
disabled = true;
FlipReplace.doReplace(displayed, notDisplayed, doAfter);
}
disable: bind disabled;
}
var wipeButton = Button{

text: "Wipe Transition"
action: function(){
CHAPTER 3 ■ EFFECT: VISUAL TRANSITIONS

51

disabled = true;
WipeReplace.doReplace(displayed, notDisplayed, doAfter);
}
disable: bind disabled;
}
var burnButton = Button{
text: "Burn Transition"
action: function(){
disabled = true;
BurnReplace.doReplace(displayed, notDisplayed, doAfter);
}
disable: bind disabled;
}

Stage {
title: "Chapter 3"
scene: Scene {
width: 640
height: 480
fill: Color.BLACK
content: [
VBox{
spacing: 10
translateX: 25

translateY: 30
content: [fadeButton,slideButton,flipButton,wipeButton,burnButton]
},
nodeA
]
}
}

function doAfter():Void{
var temp = notDisplayed;
notDisplayed = displayed;
displayed = temp;
disabled = false;
}

The stage contains a scene with a VBox, which contains the buttons and the node—nodeA. The nodes,
nodeA and nodeB, represent the content that we will be switching in and out as the buttons are pressed.
The variables displayed and notDisplayed record which node is displayed or not; thus when nodeA is
visible, the variable notDisplayed points to nodeB. After each transition, the values of displayed and
notDisplayed are switched to reflect the content of the scene. This business of tracking which node is
displayed or not is a sort of bookkeeping that facilitates this demonstration. Other applications that use
these transitions may or may not keep track of the visible content in this way.
The code in Listing 3-2 is the implementation of the example class ExampleNodeA. This code is also
not critical to the transitions themselves, but provides a somewhat realistic demonstration. The
implementation of ExampleNodeB is very similar to that of ExampleNodeA, but I’ll leave it to you to look to
the source code for the details.
CHAPTER 3 ■ EFFECT: VISUAL TRANSITIONS

52


Listing 3-2. ExampleNodeA.fx
package org.lj.jfxe.chapter3;

import javafx.scene.Group;
import javafx.scene.shape.Rectangle;
import javafx.scene.layout.*;
import javafx.scene.paint.*;
import javafx.scene.control.*;
import javafx.geometry.HPos;

/**
* @author lucasjordan
*/

public class ExampleNodeA extends Group{

init {
insert
Rectangle{
width: 320
height: 240
stroke: Color.BLUE
strokeWidth: 6
arcHeight: 24
arcWidth: 24
} into content;
insert
VBox{
spacing: 15
translateX: 30

translateY: 30
hpos: HPos.CENTER
content: [
Label{text:"Please Enter Your Personal Information",
textFill: Color.WHITESMOKE},
Tile{
vgap: 7
columns: 2
content: [
Label{text:"First Name", textFill: Color.WHITESMOKE},
TextBox{},
Label{text:"Last Name", textFill: Color.WHITESMOKE},
TextBox{},
Label{text:"Email Address", textFill: Color.WHITESMOKE},
TextBox{},
Label{text:"Home Phone", textFill: Color.WHITESMOKE},
TextBox{},
Label{text:"Cell Phone", textFill: Color.WHITESMOKE},
TextBox{},
]
CHAPTER 3 ■ EFFECT: VISUAL TRANSITIONS

53

}
]
} into content;
}
}


The classes presented create a scene that looks like the screenshot in Figure 3-1. There is a large
rectangle with rounded corners in the middle of the scene that contains a number of controls. When a
button on the left is pressed, the rectangle is replaced with a different but similar rectangle. Each button
will demonstrate one of the five example transitions presented in this chapter.


Figure 3-1. Transition demo
The following sections will cover the how each visual transition is implemented.
Example 1: Fade Replace
The fade replace is a simple transition where one node fades out to reveal a second. The general strategy
is to make the second node transparent and place it behind the first node, then create an animation that
simultaneously decreases the opacity of the first node while increasing the opacity of the second node.
When the animation is complete, the first node, now transparent, is removed from the scene.
CHAPTER 3 ■ EFFECT: VISUAL TRANSITIONS

54

The screenshot in Figure 3-2 shows the animation halfway through. In this state both the old node
and the new node are visible.


Figure 3-2. Fade replace in action
Listing 3-3 shows how this transition is implemented.
Listing 3-3. FadeReplace.fx
package org.lj.jfxe.chapter3.example1;

import javafx.scene.Node;
import javafx.animation.*;
import javafx.scene.Group;
import javafx.util.Sequences;


/**
* @author lucasjordan
*/

public function doReplace(nodeToReplace:Node,replacementNode:Node,doAfter:function()):Void{
var parent:Group = (nodeToReplace.parent as Group);
CHAPTER 3 ■ EFFECT: VISUAL TRANSITIONS

55

var origNodeToReplaceOpacity = nodeToReplace.opacity;
var origReplacementNodeOpacity = replacementNode.opacity;

replacementNode.translateX = nodeToReplace.translateX;
replacementNode.translateY = nodeToReplace.translateY;

var index = Sequences.indexOf(parent.content, nodeToReplace);
insert replacementNode before parent.content[index];

var t = Timeline{
keyFrames: [
KeyFrame{
time: 0s
values: [
replacementNode.opacity => 0.0 tween Interpolator.EASEBOTH
]
}

KeyFrame{

time: 1s
values: [
nodeToReplace.opacity => 0.0 tween Interpolator.EASEBOTH,
replacementNode.opacity => origReplacementNodeOpacity tween
Interpolator.EASEBOTH
]
action: function(){
delete nodeToReplace from parent.content;
nodeToReplace.opacity = origNodeToReplaceOpacity;
doAfter();
}
}
]
}
t.play();
}

Looking at Listing 3-3, the doReplace function takes two nodes and a function. The first node,
nodeToReplace, is replaced by the second node, replacementNode, and function doAfter is called when
the animation is complete. The opacity of both nodes is recorded. And since the opacity of these nodes
will change over the course of the animations, it is important that the original values be restored, as the
user of this function may not expect those values to change.
Next, replacementNode is placed behind nodeToReplace. This is done by finding the index of
nodeToReplace in its parent content and then adding replacementNode before that index, since nodes
with a higher index are drawn after nodes with a lower index.
Once the nodes are positioned in the scene, a Timeline called t is created with three KeyFrames. The
first KeyFrame sets the opacity of replacementNode to zero. The second KeyFrame states that after one
second, the opacity of replacementNode should increase to its original value, and that the opacity of
nodeToReplace should be at zero at the end of the first second. The last KeyFrame does not alter the visual
appearance of the animation, but does call the callback function doAfter when the animation is done.

CHAPTER 3 ■ EFFECT: VISUAL TRANSITIONS

56

Having a callback function is important, as it allows the caller of the function to know when the
animation is done. In the example presented here, the callback function is used to re-enable the buttons
and keep track of which node is currently displayed in the scene. In a more complex application the
callback function could be useful in any number of ways.
Example 2: Slide Replace
The slide replace, as the name implies, slides one node into the scene as the current one slides out. This
example has a node sliding in from the left as the existing node slides out of the scene to the right. To
achieve this effect, a clipped group is created containing both nodes, and the group and the clipped area
are then animated.
The screenshot in Figure 3-3 shows the animation halfway done, where the new node is on the left
with its left side clipped. The node being replaced is moving to the right and has its right side clipped.


Figure 3-3. Slide replace
Listing 3-4 shows the code that implements this transition.

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×