Как создавать последовательные анимации чтобы это было слаженно
UPD: Мне подойдет любой вариант кода благодаря которому я смогу создать необходимую анимацию. Не обязательно отталкиваться от моих вариантов.
Я пытаюсь сделать анимацию где в окошке крутятся изображения и никак не получается сделать её процесс плавным.
По стандарту в панели имеется 5 изображений (пятое справа, за пределами экрана).

По ходу анимации планировалось что все элементы сдвигаются влево на -150 (размер изображений) и по окончанию данного Timeline активируется onFinished метод, который удаляет с панели первое имеющиеся изображение и добавляет новое, а затем создает новый таймлайн по тому же принципу и с тем же ивентом по окончанию.
Но проблема в том что после первой итерации таймлайна добавленные картинки уже появляются на расстоянии в те же 150 width. И в дополнение происходит небольшой визуальный рывок всех изображений. Я понимаю что это происходит почти наверняка из-за действия удаления первого изображения, но и другого варианта придумать не могу не засоряя панель сотней картинок.
Вот как это начинает выглядеть дальше:

Как мне исправить мой код чтобы в анимации изображения шли без рывком и увеличения пространства между ними? Если есть вариант реализовать мою идею в виде одной анимации то этот вариант тоже подошел бы.
Код отвечающий за создание изначальной анимации по нажатию кнопки:
Timeline mainTimeline = new Timeline();
for(int f = 0; f<5; f++) {
if(f==0) {
KeyFrame key = new KeyFrame(DURATION,evt -> {
heroSpin.getChildren().remove(0);
heroSpin.getChildren().add(allWorkingIM.get(ImageViewCount));
ImageViewCount++;
makeNewTimeLine(allWorkingIM);}
, new KeyValue(heroSpin.getChildren().get(f).translateXProperty(), STEP));
mainTimeline.getKeyFrames().add(key);
} else {
KeyFrame key = new KeyFrame(DURATION, new KeyValue(heroSpin.getChildren().get(f).translateXProperty(), STEP));
mainTimeline.getKeyFrames().add(key);
}}
mainTimeline.setCycleCount(1);
mainTimeline.play();
И практически такой же код метода вызываемого по окончанию этой анимации:
Timeline newTimeline = new Timeline();
for(int g = 0; g<5; g++) {
if(g==0) {
KeyFrame key = new KeyFrame(DURATION,evt -> {
heroSpin.getChildren().remove(0);
heroSpin.getChildren().add(iva.get(ImageViewCount));
ImageViewCount++;
makeNewTimeLine(iva);}
, new KeyValue(heroSpin.getChildren().get(g).translateXProperty(), heroSpin.getChildren().get(g).getTranslateX()-150,Interpolator.LINEAR));
newTimeline.getKeyFrames().add(key);
} else {
KeyFrame key = new KeyFrame(DURATION, new KeyValue(heroSpin.getChildren().get(g).translateXProperty(), heroSpin.getChildren().get(g).getTranslateX()-150,Interpolator.LINEAR));
newTimeline.getKeyFrames().add(key);
}
}
newTimeline.setCycleCount(1);
newTimeline.play();
Ответы (1 шт):
Как и предполагал решение оказалось проще изначального варианта.
Перебирая варианты немного изменил подход и вместо при начале анимации стал добавлять в контейнер сразу все ImageView, а вместо удаления изображений ушедших из зоны видимости просто позволил им собираться на финальной точке.
Возможно при работе с огромными количествами изображений это будет иметь побочные эффекты, но в моем случае все стало прогружаться даже быстрее и решило проблему с пустотами между изображениями.
Вот так это выглядит у меня в итоге:
Первым шагом добавляю все
ImageViewв контейнерЗатем создаю
Timelineв котором для каждого элемента контейнера создаюFrameKeyс соответственно увеличивающимся числом продолжительности и изменения координатыXдля каждого следующего изображения:Timeline mainTimeline = new Timeline(); for(int c = 0, translateNum = -256, durationNum = 1000; c < heroSpin.getChildren().size(); c++, translateNum = translateNum-256,durationNum= durationNum+1000) { KeyFrame key = new KeyFrame(new Duration(durationNum), new KeyValue(heroSpin.getChildren().get(c).translateXProperty(), translateNum)); mainTimeline.getKeyFrames().add(key); } mainTimeline.setCycleCount(1); mainTimeline.play();
В результате получаю равномерную анимацию:
