private List<AnimationPartBase> searchAnimationWithType(
     Class<? extends AnimationPartBase> clazz, long startTime, long endTime) {
   List<AnimationPartBase> result = new ArrayList<AnimationPartBase>();
   for (AnimationPartBase animation : animations) {
     if (animation.getClass() == clazz
         && !(endTime < animation.startTime || startTime > animation.endTime)) {
       result.add(animation);
     }
   }
   return result;
 }
  private void addAnimation(
      ArrayList<KeyFrame> keyFrames, final AnimationPartBase annimation, long minTime) {
    long startTimeMs = annimation.startTime - minTime;
    long endTimeMs = annimation.endTime - minTime;

    final Node node = annimation.createVisualRepresentation();

    KeyValue keyValueStartX = new KeyValue(node.translateXProperty(), annimation.startx);
    KeyValue keyValueStartY = new KeyValue(node.translateYProperty(), annimation.starty);
    KeyValue keyValueEndX =
        new KeyValue(node.translateXProperty(), annimation.endx, Interpolator.EASE_BOTH);
    KeyValue keyValueEndY =
        new KeyValue(node.translateYProperty(), annimation.endy, Interpolator.EASE_BOTH);

    KeyFrame keyFrame1 =
        new KeyFrame(
            Duration.millis(startTimeMs),
            new EventHandler<ActionEvent>() {
              @Override
              public void handle(ActionEvent event) {
                animationPane.getChildren().add(node);
              }
            },
            new KeyValue(node.opacityProperty(), 0));
    KeyFrame keyFrame2 = new KeyFrame(Duration.millis(startTimeMs), keyValueStartX, keyValueStartY);
    KeyFrame keyFrame3 =
        new KeyFrame(
            Duration.millis(startTimeMs + FADEDURATION), new KeyValue(node.opacityProperty(), 1));
    KeyFrame keyFrame4 =
        new KeyFrame(Duration.millis(startTimeMs + FADEDURATION), keyValueStartX, keyValueStartY);
    KeyFrame keyFrame5 =
        new KeyFrame(Duration.millis(endTimeMs - FADEDURATION), keyValueEndX, keyValueEndY);
    KeyFrame keyFrame6 =
        new KeyFrame(
            Duration.millis(endTimeMs - FADEDURATION), new KeyValue(node.opacityProperty(), 1));
    KeyFrame keyFrame7 =
        new KeyFrame(
            Duration.millis(endTimeMs),
            new EventHandler<ActionEvent>() {
              @Override
              public void handle(ActionEvent event) {
                animationPane.getChildren().remove(node);
              }
            },
            new KeyValue(node.opacityProperty(), 0));

    keyFrames.add(keyFrame1);
    keyFrames.add(keyFrame2);
    keyFrames.add(keyFrame3);
    keyFrames.add(keyFrame4);
    keyFrames.add(keyFrame5);
    keyFrames.add(keyFrame6);
    keyFrames.add(keyFrame7);

    timeline
        .statusProperty()
        .addListener(
            new ChangeListener<Status>() {
              @Override
              public void changed(
                  ObservableValue<? extends Status> observable, Status oldValue, Status newValue) {
                if (newValue == Status.STOPPED) { // clean up when animation stopped
                  animationPane.getChildren().remove(node);
                }
              }
            });
  }