Created
May 23, 2019 14:30
-
-
Save sirolf2009/41921d045e4d64323f925ed50792094c to your computer and use it in GitHub Desktop.
Zoom on scroll
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import javafx.animation.KeyFrame | |
import javafx.animation.KeyValue | |
import javafx.animation.Timeline | |
import javafx.event.EventHandler | |
import javafx.geometry.Bounds | |
import javafx.scene.Node | |
import javafx.scene.input.ScrollEvent | |
import javafx.util.Duration | |
class AnimatedZoomOperator { | |
static val DEFAULT_ZOOM_FACTOR = 1.5 | |
val Timeline timeline | |
new() { | |
this.timeline = new Timeline(60) | |
} | |
def EventHandler<ScrollEvent> zoom(Node node) { | |
return zoom(node, DEFAULT_ZOOM_FACTOR) | |
} | |
def EventHandler<ScrollEvent> zoom(Node node, double zoomFactor) { | |
new EventHandler<ScrollEvent>() { | |
override handle(ScrollEvent evt) { | |
zoom(node, evt, zoomFactor) | |
} | |
} | |
} | |
def void zoom(Node node, ScrollEvent evt) { | |
zoom(node, evt, DEFAULT_ZOOM_FACTOR) | |
} | |
def void zoom(Node node, ScrollEvent evt, double zoomFactor) { | |
if(evt.getDeltaY() <= 0) { // zoom out | |
zoom(node, 1 / zoomFactor, evt.getSceneX(), evt.getSceneY()) | |
} else { | |
zoom(node, zoomFactor, evt.getSceneX(), evt.getSceneY()) | |
} | |
} | |
def void zoom(Node node, double factor, double x, double y) { | |
// determine scale | |
val double oldScale = node.getScaleX() | |
val double scale = oldScale * factor | |
val double f = (scale / oldScale) - 1 | |
// determine offset that we will have to move the node | |
val Bounds bounds = node.localToScene(node.getBoundsInLocal()) | |
val double dx = (x - (bounds.getWidth() / 2 + bounds.getMinX())) | |
val double dy = (y - (bounds.getHeight() / 2 + bounds.getMinY())) | |
// timeline that scales and moves the node | |
timeline.getKeyFrames().clear() | |
timeline.getKeyFrames().addAll(new KeyFrame(Duration.millis(200), new KeyValue(node.translateXProperty(), node.getTranslateX() - f * dx)), // | |
new KeyFrame(Duration.millis(200), new KeyValue(node.translateYProperty(), node.getTranslateY() - f * dy)), // | |
new KeyFrame(Duration.millis(200), new KeyValue(node.scaleXProperty(), scale)), // | |
new KeyFrame(Duration.millis(200), new KeyValue(node.scaleYProperty(), scale))) | |
timeline.play() | |
} | |
def void resetZoom(Node node) { | |
timeline.getKeyFrames().clear() | |
timeline.getKeyFrames().addAll(new KeyFrame(Duration.millis(200), new KeyValue(node.translateXProperty(), 0)), // | |
new KeyFrame(Duration.millis(200), new KeyValue(node.translateYProperty(), 0)), // | |
new KeyFrame(Duration.millis(200), new KeyValue(node.scaleXProperty(), 1)), // | |
new KeyFrame(Duration.millis(200), new KeyValue(node.scaleYProperty(), 1))) | |
timeline.play() | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val label = new Label("Hello World!") | |
val zoomOperator = new AnimatedZoomOperator() | |
label.setOnScroll(zoomOperator.zoom(label)) | |
new Button("Reset Zoom") => [ | |
setOnAction [ | |
zoomOperator.resetZoom(label) | |
] | |
] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment