Search |
|||
Sergey Malenkov's blogAlong the RiverPosted by malenkov on November 20, 2009 at 6:24 AM PST
The subject of the next JFXstudio Challenge competition is a Holiday. What are you going to do on this holiday? How about having a trip along the river? The image can be dragged with the mouse cursor, or you can use the cursor keys for navigation. Also the thumbnail can be used to select the most appropriate viewport. The painting used in the application was created in 12th century by an artist, Zhang Zeduan. This painting, as well as its remake made in the 18th century, is available on the Wikipedia website. You can find more panoramic views on this site. For example,
Be patient! The application will start only when the image is loaded. Study the script now. def url = FX.getArgument("url");
def image = Image {
url: if (url != null)
then "{url}"
else "https://malenkov.dev.java.net/20091120/AlongTheRiver.jpg"
}
The code above is used to load the image by the specified URL. If it is not set, the default image is loaded. class View extends Rectangle {
def scale = bind scene.width / image.width;
override var width = bind scene.width;
override var height = bind scene.height - image.height * scale;
def maxX = bind image.width - width on replace { setX(x) }
def maxY = bind image.height - height on replace { setY(y) }
function setX(newX: Number) { x = if (newX < 0 or maxX < 0) 0 else if (maxX < newX) maxX else newX }
function setY(newY: Number) { y = if (newY < 0 or maxY < 0) 0 else if (maxY < newY) maxY else newY }
}
The onMousePressed: function(event) {
if (event.dragX != 0 or event.dragY != 0) {
view.setX(x - event.sceneX);
view.setY(y - event.sceneY)
}
x = event.sceneX + view.x;
y = event.sceneY + view.y
}
The method above is used to handle the onMouseDragged: function(event) {
view.setX(event.x - view.width / 2);
view.setY(event.y - view.height / 2)
}
The method above is used to handle the def timer = Timeline {
repeatCount: Timeline.INDEFINITE
keyFrames: KeyFrame {
canSkip: true
time: 10ms
action: function() {
if (key == KeyCode.VK_UP) view.setY(view.y - rate) else
if (key == KeyCode.VK_DOWN) view.setY(view.y + rate) else
if (key == KeyCode.VK_LEFT) view.setX(view.x - rate) else
if (key == KeyCode.VK_RIGHT) view.setX(view.x + rate);
rate *= 1.02
}
}
}
This timeline is used to change the coordinates according to the key pressed. Note that the rate increases gradually. var rate: Number;
var key: KeyCode on replace {
rate = 0.2;
if (key != null)
then timer.play()
else timer.stop()
}
The timeline starts when the key is pressed and stops when the key is released. The rate sets to the initial state. ImageView {
image: image
cursor: HAND
translateX: bind -view.x
translateY: bind -view.y
focusTraversable: true
onKeyPressed: function(event) { key = event.code }
onKeyReleased: function(event) { key = null }
onMousePressed: view.onMousePressed
onMouseDragged: view.onMousePressed
}
It is the primary image that is moved accordingly to the viewport coordinates. The Group {
translateY: bind view.height
transforms: Scale {
x: bind view.scale
y: bind view.scale
}
content: [
ImageView {
image: image
smooth: false
blocksMouse: true
onMousePressed: view.onMouseDragged
onMouseDragged: view.onMouseDragged
}
view
]
}
A thumbnail is created by scaling. The viewport is shown over the thumbnail as a transparent rectangle. »
Related Topics >>
Blogs Comments
Comments are listed in date ascending order (oldest first)
|
CategoriesArchivesRecent Entries |
||
|
|