Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@skrb
Created December 24, 2014 13:34
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 skrb/d2f112802cae801420f4 to your computer and use it in GitHub Desktop.
Save skrb/d2f112802cae801420f4 to your computer and use it in GitHub Desktop.
Irod Drawing Song by JavaFX
package irofdrawingsong;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Arc;
import javafx.scene.shape.ArcTo;
import javafx.scene.shape.Circle;
import javafx.scene.shape.ClosePath;
import javafx.scene.shape.CubicCurveTo;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
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);
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
if (event.getCode() == KeyCode.ENTER) {
startAnimation(container);
}
}
});
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 event) {
startAnimation(container);
}
});
root.getChildren().add(startButton);
}
private void startAnimation(final Group container) {
container.getChildren().clear();
startButton.setOpacity(0.0);
new Timeline(
new KeyFrame(Duration.ZERO, new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
drawFrameBorder(container, 4_000L);
lyrics.setText("これっくらいの canvas にっ");
}
}),
new KeyFrame(new Duration(5_000), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
drawOutline(container, 2_000L);
lyrics.setText("ぐるっと輪郭ちょっと描いて\nぱっくぱっく開いたお口をつっけて");
}
}),
new KeyFrame(new Duration(8_000), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
drawBalloon(container, 3_000L);
lyrics.setText("ふっきだっしはっベッジェきょっくせんっ");
}
}),
new KeyFrame(new Duration(12_000), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
drawLeader(container, 1_500L);
lyrics.setText("点、点、点、点、つっぶやっいて");
}
}),
new KeyFrame(new Duration(15_000), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
drawEye(container, 1_000L);
lyrics.setText("あーなを開ーけたらいろふさん");
}
}),
new KeyFrame(new Duration(17_000), new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent t) {
startButton.setOpacity(0.5);
}
})
).play();
}
private void drawFrameBorder(Group container, long duration) {
// 枠線
Rectangle rectangle = new Rectangle(0, 0, 300, 300);
rectangle.setStrokeWidth(5.0);
rectangle.setStroke(Color.BLACK);
rectangle.setFill(null);
rectangle.getStrokeDashArray().add(1200.0);
rectangle.setStrokeDashOffset(1200.0);
rectangle.setStrokeLineCap(StrokeLineCap.ROUND);
container.getChildren().add(rectangle);
Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(rectangle.strokeDashOffsetProperty(), 1200.0)),
new KeyFrame(Duration.millis(duration), new KeyValue(rectangle.strokeDashOffsetProperty(), 2400.0))
);
timeline.play();
}
private void drawOutline(final Group container, long duration) {
// 輪郭
Path path = new Path();
path.setStrokeWidth(10.0);
path.setStroke(Color.BLACK);
// 輪郭の始点
path.getElements().add(new MoveTo(146.0, 184.5));
// 円弧
ArcTo arc = new ArcTo();
arc.setX(126.5); arc.setY(267.0);
arc.setRadiusX(117); arc.setRadiusY(117);
arc.setLargeArcFlag(true);
arc.setSweepFlag(true);
path.getElements().add(arc);
// 口の部分の直線
path.getElements().add(new LineTo(210, 255));
// パスを閉じる
path.getElements().add(new ClosePath());
path.setClip(new Rectangle(0, 0, 300, 300));
path.setStrokeLineCap(StrokeLineCap.ROUND);
container.getChildren().add(path);
path.getStrokeDashArray().add(830.0);
path.setStrokeDashOffset(830.0);
new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(path.strokeDashOffsetProperty(), 830.0)),
new KeyFrame(Duration.millis(duration), new KeyValue(path.strokeDashOffsetProperty(), 0.0))
).play();
}
private void drawBalloon(final Group container, final long duration) {
// 吹き出し
Path path = new Path();
path.setStrokeWidth(10.0);
path.setStroke(Color.BLACK);
path.getElements().add(new MoveTo(50, 30));
path.getElements().add(new LineTo(153, 30));
ArcTo arc = new ArcTo();
arc.setX(153); arc.setY(90);
arc.setRadiusX(30); arc.setRadiusY(30);
arc.setSweepFlag(true);
path.getElements().add(arc);
path.getElements().add(new LineTo(105, 90));
// 吹き出しの飛び出ている部分はベジェ曲線で記述
path.getElements().add(new CubicCurveTo(105, 90, 90, 105, 129, 141));
path.getElements().add(new CubicCurveTo(90, 135, 66, 120, 81, 90));
path.getElements().add(new LineTo(57, 90));
arc = new ArcTo();
arc.setX(50); arc.setY(30);
arc.setRadiusX(30); arc.setRadiusY(30);
arc.setSweepFlag(true);
path.setStrokeLineCap(StrokeLineCap.ROUND);
path.getElements().add(arc);
container.getChildren().add(path);
path.getStrokeDashArray().add(520.0);
path.setStrokeDashOffset(520.0);
new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(path.strokeDashOffsetProperty(), 520.0)),
new KeyFrame(Duration.millis(duration), new KeyValue(path.strokeDashOffsetProperty(), 0.0))
).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