3-D Flip 변화를 위해서 Perspective Transform 사용하기

By Josh Marinacci, October 17th, 2008

You can easily create 3-D transitions in JavaFX by using the PerspectiveTransform effect.

여러분은 JavaFX에서 PerspectiveTransform 효과를 이용하여 쉽게 3-D 변화를 만들수 있습니다.

코드 이해하기

모든 JavaFX 그래픽 노드들은 여러분이 노드에 특별한 효과들을 적용하기 위해서 사용 할수 있는 effect 변수를 가지고 있습니다. PerspectiveTransform 효과는 네개의 구석 위치(point)들에 의해서 정의된 사면의 폴리곤(polygon)에 맞추기 위해서 노드를 잡아당깁니다. 신중하게 이 위치들을 계산함으로써 여러분은 3-D filpping 효과를 만들수 있습니다.

Figure 1의 코드는 FlipView라고 불리는 커스텀 노드를 정의합니다. 이 노드들은 전후 노드들을 위한 두개의 공용 변수들과 가지고 있고 time라고 불리는 세번째 내부 변수를 가지고 있습니다. create 함수는 전후 노드들을 위한 두개의 다른 Groups를 포함하는 Group를 리턴합니다. 중요한 부분은 여기 각 그룹들의 효과들이 time 변수를 취하는 getPT 함수에 달려있다는 것입니다. 왜냐하면 time 변수가 변경될때 마다 getPT 함수는 꼭 호출되야하기 때문입니다. PerspectiveTransform는 실제로 현재 시간에 근거하여 계산이 되는 곳인 getPT 함수에 있습니다.

Source Code
package fliptransition;

import javafx.scene.effect.*;
...

class FlipView extends CustomNode {
    public var frontNode:Node;
    public var backNode:Node;

    var flipped = false;
    var time = Math.PI/2;
    override public function create():Node {
        return Group {
            content: [ 
                Group { content: backNode visible: bind (time<0) effect: bind getPT(time) },
                Group { content: frontNode  visible: bind (time>0) effect: bind getPT(time) },
            ]
        }
    }

Figure 1: FlipView class

getPT함수는 Math.sin()Math.cos() 메소드들을 노드가 3-D 각도에서 있는것처럼 보이게 하기 위해서 노드의 치수를 늘리는데 사용합니다. 각 플립(flip)에서 뒤쪽으로 회선하는 사각형의 측면은 조금은 작게 만들어 집니다. 앞쪽으로 회전하는 사각형의 측면은 조금더 높게 만들어 집니다. 이러한 회전들은 3-D transition의 환영을 만들어 냅니다. widthheight는 전후 노드들의 크기와 지속적으로 맞춥니다. radiusback 변수들은 추출 각도와 효과의 왜곡을 커스터마이즈 하기 위해서 수정되어질수 있습니다.

Source Code
    function getPT(t:Number):PerspectiveTransform {
        var width = 200;
        var height = 200;
        var radius = width/2;
        var back = height/10;
        return PerspectiveTransform {
            ulx: radius - Math.sin(t)*radius     uly: 0 - Math.cos(t)*back
            urx: radius + Math.sin(t)*radius     ury: 0 + Math.cos(t)*back
            lrx: radius + Math.sin(t)*radius     lry: height - Math.cos(t)*back
            llx: radius - Math.sin(t)*radius     lly: height + Math.cos(t)*back
        }
    }

Figure 2: getPT Function

transition을 실제로 애니메이트 하기 위해서 anim 타임라인은 time 변수를 -3.14/2 (혹은 90 라디안)에서 -3.14/2 까지 0.5초 안에 움직입니다. 상세한 설명을 위해서 Figure 3를 보세요.

public var anim = Timeline { keyFrames: [ at(0s) { time=> Math.PI/2 tween Interpolator.LINEAR}, at(1s) { time=> -Math.PI/2 tween Interpolator.LINEAR}, KeyFrame { time: 1.0s action: function() { flipped = not flipped; } } ] }

Figure 3: Animate the Transition

FlipView를 사용하기 위해서 여러분은 단순히 그것을 만들고 앞뒤로 움직이기 위해서 그것을 컨텐츠 노드 안에 넘겨주기만 하면 됩니다.

Source Code
var flip = FlipView {
    translateX: 50
    translateY: 40+50
    backNode: ImageView { image: Image { url: "{__DIR__}lion1.png"  }  }
    frontNode: ImageView { image: Image { url: "{__DIR__}lion2.png"  }  }
};

Figure 4: Create a FlipView