/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
* Copyright 2008, 2010 Oracle and/or its affiliates. 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 Oracle Corporation 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;
if (width == 0) {
toX = random.nextInt(Main.width - 200);
}
else {
toX = random.nextInt(Main.width - width);
}
if (height == 0) {
toY = 120;
}
else {
toY = (height/2)+20;
}
} else if(alignment == 1) {
fromX = Main.height - 100;
fromY = -75;
if (width == 0) {
toX = Main.width-250;
}
else {
toX = Main.width-(width*2);
}
if (height == 0) {
toY = random.nextInt(Main.height-200);
}
else {
toY = random.nextInt(Main.height-(height));
}
} else if(alignment == 2) {
fromX = Main.width;
fromY = Main.height - 100;
if (width == 0) {
toX = random.nextInt(Main.width - 250);
}
else {
toX = random.nextInt(Main.width - width);
}
toY = (Main.height/2);
} else if(alignment == 3) {
fromX = 0;
fromY = Main.height - 100;
if (width == 0) {
toX = (Main.width/2)-400;
}
else {
toX = (Main.width/2)-(width+50);
}
if (height == 0) {
toY = random.nextInt(Main.height - 200);
}
else {
toY = random.nextInt(Main.height - height);
}
}
}
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();
}
}
}