/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
* Copyright 2009 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms.
*
* This file is available and licensed under the following license:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Sun Microsystems nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package mosaic;
import java.util.Random;
import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.animation.transition.ParallelTransition;
import javafx.animation.transition.RotateTransition;
import javafx.animation.transition.TranslateTransition;
import javafx.scene.Cursor;
import javafx.scene.CustomNode;
import javafx.scene.Group;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.Node;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.input.MouseEvent;
def random = new Random();
var anchor = 0;
public class ThumbImage extends CustomNode {
var width = 104.0;
var height = 79.0;
var fromX = 0.0;
var fromY = 0.0;
var toX = 0.0;
var toY = 0.0;
var finalR = 0;
var startX = 0.0;
var startY = 0.0;
var mouseDragged = false;
var alignment = 0;
init {
if(anchor == 3) {
anchor = 0;
} else {
anchor++;
}
alignment = anchor;
}
public var imageView = ImageView {
x: 2
y: 2
fitWidth: bind (width - 4)
fitHeight: bind (height - 4)
preserveRatio: true
};
var progress = bind imageView.image.progress on replace {
if(progress >= 90.0) {
scaleX = 0.5;
scaleY = 0.5;
visible = true;
rotate();
}
}
var imageWidth = bind imageView.image.width on replace {
if(imageWidth >= 0.0) {
width = imageWidth;
}
}
var imageHeight = bind imageView.image.height on replace {
if(imageHeight >= 0.0) {
height = imageHeight;
}
}
public var url : String on replace {
if(url != null) {
imageView.image = Image {
url: "{url}_m.jpg"
backgroundLoading: true
}
visible = false;
}
}
var zoomTimeline : Timeline;
var hoverRotateTransition : RotateTransition;
override function create() : Node {
cursor = Cursor.HAND;
blocksMouse = true;
visible = false;
hoverRotateTransition = RotateTransition {
duration: 300ms
node: this
};
zoomTimeline = Timeline {
};
var borderRect = Rectangle {
width: bind width
height: bind height
strokeWidth: 2.0
stroke: Color.WHITE
arcWidth: 5
arcHeight: 5
}
rotate();
Group {
content: [ borderRect, imageView ]
}
}
override var onMouseEntered = function(e) {
if(mouseDragged or zoomTimeline.running) {
return;
}
toFront();
hoverRotateTransition.stop();
hoverRotateTransition.fromAngle = finalR;
hoverRotateTransition.toAngle = 0;
hoverRotateTransition.playFromStart();
}
override var onMouseExited = function(e) {
if(mouseDragged or
zoomTimeline.running or
hoverRotateTransition.running) {
return;
}
hoverRotateTransition.fromAngle = 0;
hoverRotateTransition.toAngle = finalR;
hoverRotateTransition.playFromStart();
if((scaleX > 0.5) or (scaleY > 0.5)) {
initFinalPoint();
zoomTimeline.playFromStart();
}
}
override var onMousePressed = function(e) {
startX = translateX;
startY = translateY;
e.node.rotate = 0;
mouseDragged = true;
}
override var onMouseReleased = function(e) {
mouseDragged = false;
}
override var onMouseDragged = function(e : MouseEvent) {
translateX = startX + e.dragX;
translateY = startY + e.dragY;
var scaleFactor = 2.5;
var halfWidth = Main.width/2.0 - 100;
var halfheight = Main.height/2.0 - 100;
var imageScaleX = scaleFactor -
(scaleFactor * (halfWidth - translateX + 1)/halfWidth);
if(translateX > halfWidth) {
imageScaleX = scaleFactor -
(scaleFactor * (halfWidth - (Main.width - translateX - 200) + 1)/halfWidth);
}
if(imageScaleX < 0.5) { imageScaleX = 0.5; }
var imageScaleY = scaleFactor -
(scaleFactor * (halfheight - translateY + 1)/halfheight);
if(translateY > halfheight) {
imageScaleY = scaleFactor -
(scaleFactor * (halfheight - (Main.height - translateY - 200) + 1)/halfheight);
}
if(imageScaleY < 0.5) { imageScaleY = 0.5; }
scaleX = java.lang.Math.min(imageScaleX, imageScaleY);
scaleY = scaleX;
}
function initFinalPoint() : Void {
if(alignment == 0) {
fromX = -100;
fromY = 0;
toX = random.nextInt(Main.width - 100) - 20;
toY = 0;
} else if(alignment == 1) {
fromX = Main.height - 100;
fromY = -75;
toX = Main.width - 150;
toY = random.nextInt(Main.height - 100) - 10;
} else if(alignment == 2) {
fromX = Main.width;
fromY = Main.height - 100;
toX = random.nextInt(Main.width - 100) - 10;
toY = Main.height - 160;
} else if(alignment == 3) {
fromX = 0;
fromY = Main.height - 100;
toX = -50;
toY = random.nextInt(Main.height - 200);
}
}
public function rotate() : Void {
initFinalPoint();
var translateTransition = TranslateTransition {
duration: 2s
node: this
fromX: fromX
toX: toX
fromY: fromY
toY: toY
repeatCount: 1
};
zoomTimeline.keyFrames = [
KeyFrame {
time: 500ms
values: [ scaleX => 0.5 tween Interpolator.EASEOUT ]
},
KeyFrame {
time: 500ms
values: [ scaleY => 0.5 tween Interpolator.EASEOUT ]
},
KeyFrame {
time: 1s
values: [ translateX => toX tween Interpolator.EASEOUT ]
},
KeyFrame {
time: 1s
values: [ translateY => toY tween Interpolator.EASEOUT ]
}
];
var rotateTransition : RotateTransition = RotateTransition {
duration: 1s
node: this
byAngle: 360
repeatCount: 2
action: function() {
finalR = random.nextInt(360);
rotateTransition.node.rotate = finalR;
}
};
var parallelTransition = ParallelTransition {
content: [
translateTransition,
rotateTransition
]
};
parallelTransition.play();
}
public function cancel() : Void {
if(imageView.image != null) {
imageView.image.cancel();
}
}
}