JS изменение исходного изображения с анимацией

У меня проблема с изменением источника изображения с зацикленным появлением / исчезновением в JS и CSS и использованием обратного вызова SetTimeout (). Проблема в том, что последовательность работает странно: иногда изображение меняется до начала перехода, иногда работает нормально, а иногда и наоборот.

Вот мой JS:

const animationTime = 5000;
const transitionTime = 500;

function nextImage() {

  let img = document.getElementById('img1');
  img.classList.remove('hidden');
  setTimeout(function () {
    img.classList.add('hidden');
  },animationTime-transitionTime);
  img.src=randomize();
  setTimeout(nextImage, animationTime);
}
  • Функция рандомизировать () просто получает случайный путь изображения из массива.

Вот HTML:

<div class = "some-class">
    <img class = "some-image" id = "img1" src = "1.png">
</div>

А вот CSS:

.some-image {

  transition: opacity 0.5s linear;
  -webkit-transition: opacity 0.5s linear;
  -o-transition: opacity 0.5s linear;
  -moz-transition: opacity 0.5s linear;
  -moz-border-radius: 15px;
}

.hidden {
opacity: 0;
}

Upd. Итак, я отредактировал файл CSS:

.some-image {
    width: 370px;
    height: 190px;
    animation: fade-out;
    animation-duration: 1s;
}

.hidden {
    animation: fade-out;
    animation-duration: 1s;
}

@keyframes fade-in {
    from {opacity: 0;}
    to {opacity: 1;}
}

@keyframes fade-out {
    from {opacity: 1}
    to {opacity: 0}
}

И JS-файл:

function nextImage() {

        let img = document.getElementById('img1');
        img.classList.remove('hidden');
        setTimeout(function () {
            img.classList.add('hidden');
        },animationTime-1000);
        img.src=randomize();

    }
    setTimeout(nextImage, animationTime);
}

И каким-то образом он отлично работает на локальном компьютере, но на выделенном веб-сайте анимация иногда исчезает до того, как изменится источник изображения.

Можете ли вы предоставить рабочую скрипку, которая обнаружит проблему? jsfiddle.net

Kamil Kiełczewski 20.11.2018 10:27
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
3 257
2

Ответы 2

Вместо этого вам следует попробовать использовать css анимации. Вы можете легко реализовать описанное выше, и это избавит вас от необходимости обрабатывать анимацию в вашем коде.

Думаю, проблема в сроках. Функция setTimeout не гарантирует выполнение точно в то время, которое задано аргументом. Таким образом, существует вероятность того, что вы измените src образа до / после добавления / удаления класса hidden. Такая задержка случается редко, что может быть причиной того, что она работает на вашем компьютере.

Таким образом, эту проблему можно решить, если каждый раз, когда вы меняете изображение, необходимо убедиться, что изображение полностью скрыто.

const nextImage = function () {
  let img = document.querySelector('img')

  img.classList.add('hidden')

  setTimeout(() => {
    img.style.visibility = 'hidden'
    img.src = randomImage()

    // skip to next frame, may be this not necessary to use setTimeout
    setTimeout(() => {
      img.style.visibility = ''
      img.classList.remove('hidden')
    }, 10)
  }, animationDuration)

  setTimeout(nextImage, intervalDuration + animationDuration)
}

Новый цикл будет следующим: исчезновение изображения, ожидание анимации, затем изменение изображения (с установленной видимостью на скрытое) и затем постепенное появление. И цикл.

С таким подходом. Если setTimeout выполняется раньше, чем изображение полностью исчезнет, ​​видимость будет установлена ​​hidden. Если он задерживается, изображение будет скрываться немного дольше.

Живой пример здесь. В этом коде я добавляю немного шума со случайным временем для тестирования.

К сожалению, после того, как я потратил час, чтобы увидеть, что мой ответ правильный, я все еще чувствую, что он все равно не идеален, и будет хуже, если ваше изображение будет большим. Я бы порекомендовал вам вместо этого попробовать два или более тега img.

Другие вопросы по теме