JS通过动画更改源图像

时间:2018-11-20 09:24:39

标签: javascript html css css-transitions settimeout

我在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);
}
  • randomize()函数只是从数组中获取随机图像路径。

这是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;
}

已更新。  所以我编辑了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);
}

而且,它以某种方式可以在本地计算机上完美运行,但是在专用网站动画有时会在图像源更改之前淡入。

2 个答案:

答案 0 :(得分:1)

您应该尝试改用css animations。您可以轻松地实现上述内容,这将节省您在代码中处理动画的麻烦。

答案 1 :(得分:0)

我认为问题在于时间安排。 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。如果延迟,则图像将隐藏更长的时间。

实时示例here。在该代码中,我添加了一些噪声,需要随机的时间进行测试。

不幸的是,当我花了一个小时看到我的答案是正确的后,我仍然觉得它并不完美,如果您的图像很大,情况会更糟。我建议您改用两个或多个img标签。