Created
December 30, 2014 07:26
-
-
Save skrb/22051fdd259f7bc2793c to your computer and use it in GitHub Desktop.
Bezier Demo: Enable Touch, Mouse Drag and Slider
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
package net.javainthebox.bezier; | |
import javafx.application.Application; | |
import javafx.beans.binding.Bindings; | |
import javafx.beans.property.DoubleProperty; | |
import javafx.scene.Group; | |
import javafx.scene.Node; | |
import javafx.scene.Scene; | |
import javafx.scene.control.Label; | |
import javafx.scene.control.Slider; | |
import javafx.scene.layout.AnchorPane; | |
import javafx.scene.paint.Color; | |
import javafx.scene.shape.Circle; | |
import javafx.scene.shape.CubicCurve; | |
import javafx.scene.shape.Line; | |
import javafx.scene.shape.StrokeLineCap; | |
import javafx.stage.Stage; | |
public class BezierDrawer extends Application { | |
private static final double INIT_SIZE = 600.0; | |
private static final double BOTTOM_PANE_HEIGHT = 320.0; | |
private final Circle start = new Circle(20, 250, 15); | |
private final Circle end = new Circle(580, 250, 15); | |
private final Circle control1 = new Circle(100, 250, 15); | |
private final Circle control2 = new Circle(500, 250, 15); | |
private final Line line1 = new Line(); | |
private final Line line2 = new Line(); | |
private final Slider startXSlider = new Slider(0, INIT_SIZE, 0.0); | |
private final Slider startYSlider = new Slider(0, INIT_SIZE, 0.0); | |
private final Slider controlX1Slider = new Slider(0, INIT_SIZE, 0.0); | |
private final Slider controlY1Slider = new Slider(0, INIT_SIZE, 0.0); | |
private final Slider controlX2Slider = new Slider(0, INIT_SIZE, 0.0); | |
private final Slider controlY2Slider = new Slider(0, INIT_SIZE, 0.0); | |
private final Slider endXSlider = new Slider(0, INIT_SIZE, 0.0); | |
private final Slider endYSlider = new Slider(0, INIT_SIZE, 0.0); | |
private final CubicCurve bezier = new CubicCurve(); | |
private Scene scene; | |
@Override | |
public void start(Stage stage) { | |
Group root = new Group(); | |
scene = new Scene(root, INIT_SIZE, INIT_SIZE + BOTTOM_PANE_HEIGHT); | |
Group mainPane = new Group(); | |
root.getChildren().add(mainPane); | |
initBezier(mainPane); | |
AnchorPane bottom = new AnchorPane(); | |
bottom.setPrefSize(INIT_SIZE, BOTTOM_PANE_HEIGHT); | |
bottom.translateYProperty().bind(Bindings.subtract(scene.heightProperty(), BOTTOM_PANE_HEIGHT)); | |
root.getChildren().add(bottom); | |
initBottomPane(bottom); | |
stage.setTitle("Bezier Drawer"); | |
stage.setScene(scene); | |
stage.show(); | |
} | |
private void initBezier(Group mainPane) { | |
start.setFill(Color.RED); | |
start.setStroke(null); | |
configurateDrag(start); | |
end.setFill(Color.RED); | |
end.setStroke(null); | |
configurateDrag(end); | |
control1.setFill(Color.CYAN); | |
control1.setStroke(null); | |
configurateDrag(control1); | |
control2.setFill(Color.CYAN); | |
control2.setStroke(null); | |
configurateDrag(control2); | |
line1.setFill(null); | |
line1.setStroke(Color.GRAY); | |
line1.setStrokeWidth(3); | |
line1.setStrokeLineCap(StrokeLineCap.BUTT); | |
line1.getStrokeDashArray().add(8.0); | |
line1.startXProperty().bind(start.centerXProperty()); | |
line1.startYProperty().bind(start.centerYProperty()); | |
line1.endXProperty().bind(control1.centerXProperty()); | |
line1.endYProperty().bind(control1.centerYProperty()); | |
line2.setFill(null); | |
line2.setStroke(Color.GRAY); | |
line2.setStrokeWidth(3); | |
line2.setStrokeLineCap(StrokeLineCap.BUTT); | |
line2.getStrokeDashArray().add(8.0); | |
line2.startXProperty().bind(control2.centerXProperty()); | |
line2.startYProperty().bind(control2.centerYProperty()); | |
line2.endXProperty().bind(end.centerXProperty()); | |
line2.endYProperty().bind(end.centerYProperty()); | |
bezier.setStroke(Color.DARKBLUE); | |
bezier.setStrokeWidth(6); | |
bezier.setFill(null); | |
bezier.startXProperty().bind(start.centerXProperty()); | |
bezier.startYProperty().bind(start.centerYProperty()); | |
bezier.controlX1Property().bind(control1.centerXProperty()); | |
bezier.controlY1Property().bind(control1.centerYProperty()); | |
bezier.controlX2Property().bind(control2.centerXProperty()); | |
bezier.controlY2Property().bind(control2.centerYProperty()); | |
bezier.endXProperty().bind(end.centerXProperty()); | |
bezier.endYProperty().bind(end.centerYProperty()); | |
mainPane.getChildren().addAll(bezier, line1, line2, start, end, control1, control2); | |
} | |
private void configurateDrag(Circle circle) { | |
circle.setOnMouseDragged(event -> { | |
circle.setCenterX(event.getSceneX()); | |
circle.setCenterY(event.getSceneY()); | |
}); | |
circle.setOnTouchMoved(event -> { | |
circle.setCenterX(event.getTouchPoint().getSceneX()); | |
circle.setCenterY(event.getTouchPoint().getSceneY()); | |
}); | |
} | |
private void initBottomPane(AnchorPane pane) { | |
Label startX = new Label("Start X:"); | |
configureAnchor(startX, 20.0, 0.0, 500.0); | |
Label startY = new Label("Start Y:"); | |
configureAnchor(startY, 20.0, 40.0, 500.0); | |
Label controlX1 = new Label("Control1 X:"); | |
configureAnchor(controlX1, 20.0, 80.0, 500.0); | |
Label controlY1 = new Label("Control1 Y:"); | |
configureAnchor(controlY1, 20.0, 120.0, 500.0); | |
Label controlX2 = new Label("Control2 X:"); | |
configureAnchor(controlX2, 20.0, 160.0, 500.0); | |
Label controlY2 = new Label("Control2 Y:"); | |
configureAnchor(controlY2, 20.0, 200.0, 500.0); | |
Label endX = new Label("End X:"); | |
configureAnchor(endX, 20.0, 240.0, 500.0); | |
Label endY = new Label("End Y:"); | |
configureAnchor(endY, 20.0, 280.0, 500.0); | |
configureSlider(startXSlider, start.centerXProperty()); | |
configureAnchor(startXSlider, 100.0, 0.0, 20.0); | |
configureSlider(startYSlider, start.centerYProperty()); | |
configureAnchor(startYSlider, 100.0, 40.0, 20.0); | |
configureSlider(controlX1Slider, control1.centerXProperty()); | |
configureAnchor(controlX1Slider, 100.0, 80.0, 20.0); | |
configureSlider(controlY1Slider, control1.centerYProperty()); | |
configureAnchor(controlY1Slider, 100.0, 120.0, 20.0); | |
configureSlider(controlX2Slider, control2.centerXProperty()); | |
configureAnchor(controlX2Slider, 100.0, 160.0, 20.0); | |
configureSlider(controlY2Slider, control2.centerYProperty()); | |
configureAnchor(controlY2Slider, 100.0, 200.0, 20.0); | |
configureSlider(endXSlider, end.centerXProperty()); | |
configureAnchor(endXSlider, 100.0, 240.0, 20.0); | |
configureSlider(endYSlider, end.centerYProperty()); | |
configureAnchor(endYSlider, 100.0, 280.0, 20.0); | |
pane.getChildren().addAll( | |
startX, startY, | |
controlX1, controlY1, | |
controlX2, controlY2, | |
endX, endY, | |
startXSlider, startYSlider, | |
controlX1Slider, controlY1Slider, | |
controlX2Slider, controlY2Slider, | |
endXSlider, endYSlider); | |
} | |
private void configureAnchor(Node node, double left, double top, double right) { | |
AnchorPane.setLeftAnchor(node, left); | |
AnchorPane.setTopAnchor(node, top); | |
AnchorPane.setRightAnchor(node, right); | |
} | |
private void configureSlider(Slider slider, DoubleProperty target) { | |
slider.valueProperty().bindBidirectional(target); | |
slider.maxProperty().bind( | |
Bindings.max(scene.widthProperty(), | |
Bindings.subtract(scene.heightProperty(), BOTTOM_PANE_HEIGHT))); | |
slider.setShowTickMarks(true); | |
slider.setShowTickLabels(true); | |
slider.setMajorTickUnit(100.0); | |
} | |
public static void main(String... args) { | |
launch(args); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment