Skip to content

Instantly share code, notes, and snippets.

@kazuhito-m
Forked from skrb/IrofDrawingSong.java
Last active December 10, 2015 05:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kazuhito-m/e551498586adb97ff70b to your computer and use it in GitHub Desktop.
Save kazuhito-m/e551498586adb97ff70b to your computer and use it in GitHub Desktop.
package irofdrawingsong;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.ParallelTransition;
import javafx.animation.PathTransition;
import javafx.animation.SequentialTransition;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Arc;
import javafx.scene.shape.Circle;
import javafx.scene.shape.CubicCurve;
import javafx.scene.shape.Line;
import javafx.scene.shape.Polygon;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.StrokeLineCap;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;
public class IrofDrawingSong extends Application {
private Text lyrics;
private Group startButton;
private Group container;
@Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root, 300, 360);
container = new Group();
root.getChildren().add(container);
initStartButton(root, container);
lyrics = new Text("");
lyrics.setLayoutX(24);
lyrics.setLayoutY(330);
lyrics.setFont(Font.font(null, 16));
root.getChildren().add(lyrics);
stage.setTitle("Irof Drawing Song");
stage.setScene(scene);
stage.show();
}
private void initStartButton(Group root, final Group container) {
startButton = new Group();
startButton.setLayoutX(50);
startButton.setLayoutY(50);
Circle circle = new Circle(100, 100, 80);
circle.setStrokeWidth(10.0);
circle.setStroke(Color.LIGHTGRAY);
circle.setFill(Color.WHITE);
startButton.getChildren().add(circle);
Polygon triangle = new Polygon();
triangle.getPoints().addAll(new Double[]{
180.0, 100.0,
60.0, 100 + Math.sqrt(4_800),
60.0, 100 - Math.sqrt(4_800) });
triangle.setFill(Color.LIGHTGRAY);
startButton.getChildren().add(triangle);
startButton.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent t) {
startAnimation(container);
startButton.setOpacity(0.0);
}
});
root.getChildren().add(startButton);
}
private void startAnimation(final Group container) {
container.getChildren().clear();
new Timeline(
new KeyFrame(Duration.ZERO, new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
drawFrameBorder(container, 3_000L);
lyrics.setText("これっくらいの♪ canvas にっ♪");
}
}),
new KeyFrame(new Duration(4_000), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
drawOutline(container, 3_500L);
lyrics.setText("ぐるっと輪郭ちょっと描いて♪");
}
}),
new KeyFrame(new Duration(7_200), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
drawMouse(container, 2_000L);
lyrics.setText("ぱっくぱっく開いたお口をつっけて♪");
}
}),
new KeyFrame(new Duration(10_800), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
drawBalloon(container, 3_750L);
lyrics.setText("ふっきだしはっ♪ベジェきょっくせんっ♪");
}
}),
new KeyFrame(new Duration(16_200), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
drawLeader(container, 1_500L);
lyrics.setText("点、点、点、点、つっぶやっいて♪");
}
}),
new KeyFrame(new Duration(19_700), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
drawEye(container, 2_000L);
lyrics.setText("あーなを開ーけたらいろふさん♪");
}
}),
new KeyFrame(new Duration(30_000), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
startButton.setOpacity(0.5);
}
})
).play();
}
private void drawFrameBorder(final Group container, final long duration) {
Line topBorder = new Line(0.0, 0.0, 0.0, 0.0);
topBorder.setStrokeWidth(5.0);
container.getChildren().add(topBorder);
final Line rightBorder = new Line(300.0, 0.0, 300.0, 0.0);
rightBorder.setStrokeWidth(5.0);
final Line bottomBorder = new Line(300.0, 300.0, 300.0, 300.0);
bottomBorder.setStrokeWidth(5.0);
final Line leftBorder = new Line(0.0, 300.0, 0.0, 300.0);
leftBorder.setStrokeWidth(5.0);
new SequentialTransition(
new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(topBorder.endXProperty(), 0.0)),
new KeyFrame(new Duration(duration/4), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
container.getChildren().add(rightBorder);
}
},
new KeyValue(topBorder.endXProperty(), 300.0))
),
new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(rightBorder.endYProperty(), 0.0)),
new KeyFrame(new Duration(duration/4), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
container.getChildren().add(bottomBorder);
}
},
new KeyValue(rightBorder.endYProperty(), 300.0))
),
new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(bottomBorder.endXProperty(), 300.0)),
new KeyFrame(new Duration(duration/4), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
container.getChildren().add(leftBorder);
}
},
new KeyValue(bottomBorder.endXProperty(), 0.0))
),
new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(leftBorder.endYProperty(), 300.0)),
new KeyFrame(new Duration(duration/4), new KeyValue(leftBorder.endYProperty(), 0.0))
)
).play();
}
private void drawOutline(final Group container, long duration) {
Arc arc = new Arc(242.0, 250.0, 117.0, 117.0, 188.0, 0.0);
arc.setClip(new Rectangle(0, 0, 300, 300));
arc.setFill(null);
arc.setStroke(Color.BLACK);
arc.setStrokeWidth(10.0);
arc.setStrokeLineCap(StrokeLineCap.ROUND);
container.getChildren().add(arc);
final Line upperJaw = new Line(146, 184.5, 146, 184.5);
upperJaw.setStrokeWidth(10.0);
upperJaw.setStrokeLineCap(StrokeLineCap.ROUND);
final Line lowerJaw = new Line(210, 255, 210, 255);
lowerJaw.setStrokeWidth(10.0);
lowerJaw.setStrokeLineCap(StrokeLineCap.ROUND);
new SequentialTransition(
new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(arc.lengthProperty(), 0.0)),
new KeyFrame(new Duration(duration/2), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
container.getChildren().add(upperJaw);
}
},
new KeyValue(arc.lengthProperty(), 318.0))
)
).play();
}
private void drawMouse(final Group container, long duration) {
Arc arc = new Arc(242.0, 250.0, 117.0, 117.0, 188.0, 0.0);
arc.setClip(new Rectangle(0, 0, 300, 300));
arc.setFill(null);
arc.setStroke(Color.BLACK);
arc.setStrokeWidth(10.0);
arc.setStrokeLineCap(StrokeLineCap.ROUND);
container.getChildren().add(arc);
final Line upperJaw = new Line(146, 184.5, 146, 184.5);
upperJaw.setStrokeWidth(10.0);
upperJaw.setStrokeLineCap(StrokeLineCap.ROUND);
final Line lowerJaw = new Line(210, 255, 210, 255);
lowerJaw.setStrokeWidth(10.0);
lowerJaw.setStrokeLineCap(StrokeLineCap.ROUND);
new SequentialTransition(
new Timeline(
new KeyFrame(new Duration(duration/2), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
container.getChildren().add(upperJaw);
}
},
new KeyValue(arc.lengthProperty(), 318.0))
),
new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(upperJaw.endXProperty(), 146),
new KeyValue(upperJaw.endYProperty(), 184.5)),
new KeyFrame(new Duration(duration/4), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
container.getChildren().add(lowerJaw);
}
},
new KeyValue(upperJaw.endXProperty(), 210),
new KeyValue(upperJaw.endYProperty(), 255))
),
new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(lowerJaw.endXProperty(), 210),
new KeyValue(lowerJaw.endYProperty(), 255)),
new KeyFrame(new Duration(duration/4), new KeyValue(lowerJaw.endXProperty(), 126),
new KeyValue(lowerJaw.endYProperty(), 266))
)
).play();
}
private void drawBalloon(final Group container, final long duration) {
Line upperLine = new Line(50.0, 30.0, 50.0, 30.0);
upperLine.setStrokeWidth(10.0);
container.getChildren().add(upperLine);
Arc rightArc = new Arc(153, 60, 30, 30, 90, 0);
rightArc.setFill(null);
rightArc.setStroke(Color.BLACK);
rightArc.setStrokeWidth(10.0);
container.getChildren().add(rightArc);
final Line bottomLine1 = new Line(153.0, 90.0, 153.0, 90.0);
bottomLine1.setStrokeWidth(10.0);
bottomLine1.setStrokeLineCap(StrokeLineCap.ROUND);
final CubicCurve curve1 = new CubicCurve(105, 90, 105, 90, 90, 105, 105, 90);
curve1.setFill(null);
curve1.setStroke(Color.BLACK);
curve1.setStrokeWidth(10.0);
curve1.setStrokeLineCap(StrokeLineCap.ROUND);
final CubicCurve curve2 = new CubicCurve(129, 141, 90, 135, 66, 120, 129, 141);
curve2.setFill(null);
curve2.setStroke(Color.BLACK);
curve2.setStrokeWidth(10.0);
curve2.setStrokeLineCap(StrokeLineCap.ROUND);
final CubicCurve drawPath = new CubicCurve(129, 141, 90, 135, 66, 120, 81, 90);
final Circle circle = new Circle(129, 141, 1);
curve2.endXProperty().bind(Bindings.add(circle.centerXProperty(),
circle.translateXProperty()));
curve2.endYProperty().bind(Bindings.add(circle.centerYProperty(),
circle.translateYProperty()));
final Line bottomLine2 = new Line(81.0, 90.0, 81.0, 90.0);
bottomLine2.setStrokeWidth(10.0);
bottomLine2.setStrokeLineCap(StrokeLineCap.ROUND);
Arc leftArc = new Arc(50, 60, 30, 30, 270, 0);
leftArc.setFill(null);
leftArc.setStroke(Color.BLACK);
leftArc.setStrokeWidth(10.0);
container.getChildren().add(leftArc);
PathTransition transition = new PathTransition(new Duration(300), drawPath);
transition.setNode(circle);
new SequentialTransition(
new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(upperLine.endXProperty(), 50)),
new KeyFrame(new Duration(duration/6), new KeyValue(upperLine.endXProperty(), 153))
),
new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(rightArc.lengthProperty(), 0)),
new KeyFrame(new Duration(duration/6), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
container.getChildren().add(bottomLine1);
}
},
new KeyValue(rightArc.lengthProperty(), -180))
),
new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(bottomLine1.endXProperty(), 153)),
new KeyFrame(new Duration(duration/12), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
container.getChildren().add(curve1);
}
},
new KeyValue(bottomLine1.endXProperty(), 105))
),
new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(curve1.endXProperty(), 105),
new KeyValue(curve1.endYProperty(), 90)),
new KeyFrame(new Duration(duration/6), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
container.getChildren().add(curve2);
}
},
new KeyValue(curve1.endXProperty(), 129),
new KeyValue(curve1.endYProperty(), 141))
),
new ParallelTransition(transition,
new Timeline(
new KeyFrame(new Duration(0), new KeyValue(curve2.controlX1Property(), 129),
new KeyValue(curve2.controlY1Property(), 141),
new KeyValue(curve2.controlX2Property(), 129),
new KeyValue(curve2.controlY2Property(), 141)),
new KeyFrame(new Duration(duration/6), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
container.getChildren().add(bottomLine2);
}
},
new KeyValue(curve2.controlX1Property(), 90),
new KeyValue(curve2.controlY1Property(), 135),
new KeyValue(curve2.controlX2Property(), 66),
new KeyValue(curve2.controlY2Property(), 120)))),
new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(bottomLine2.endXProperty(), 81)),
new KeyFrame(new Duration(duration/12), new KeyValue(bottomLine2.endXProperty(), 50))
),
new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(leftArc.lengthProperty(), 0)),
new KeyFrame(new Duration(duration/6), new KeyValue(leftArc.lengthProperty(), -180))
)
).play();
}
private void drawLeader(final Group container, final long duration) {
final Circle leader1 = new Circle(51, 60, 5, Color.BLACK);
final Circle leader2 = new Circle(84, 60, 5, Color.BLACK);
final Circle leader3 = new Circle(120, 60, 5, Color.BLACK);
final Circle leader4 = new Circle(154, 60, 5, Color.BLACK);
new Timeline(
new KeyFrame(Duration.ZERO, new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
container.getChildren().add(leader1);
}
}),
new KeyFrame(new Duration(duration/3), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
container.getChildren().add(leader2);
}
}),
new KeyFrame(new Duration(duration*2/3), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
container.getChildren().add(leader3);
}
}),
new KeyFrame(new Duration(duration), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
container.getChildren().add(leader4);
}
})
).play();
}
private void drawEye(final Group container, long duration) {
Arc arc = new Arc(255.0, 204.0, 15.0, 15.0, 0.0, 0.0);
arc.setFill(null);
arc.setStroke(Color.BLACK);
arc.setStrokeWidth(10.0);
arc.setStrokeLineCap(StrokeLineCap.ROUND);
container.getChildren().add(arc);
new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(arc.lengthProperty(), 0.0)),
new KeyFrame(new Duration(duration), new KeyValue(arc.lengthProperty(), 360.0))
).play();
}
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