【问题标题】:JS changing source image with animationJS用动画改变源图像
【发布时间】:2018-11-20 09:24:39
【问题描述】:

我在 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);
}

而且,不知何故,它在本地机器上完美运行,但在专用网站上,动画有时会在图像源更改之前淡入。

【问题讨论】:

  • 你能提供暴露问题的工作小提琴吗? jsfiddle.net

标签: javascript html css css-transitions settimeout


【解决方案1】:

您应该尝试改用css animations。用它就可以轻松实现上面的内容,省去代码中处理动画的麻烦。

【讨论】:

    【解决方案2】:

    我认为问题在于时间。 setTimeout 函数不保证准确执行时间作为参数集。因此,您有可能在添加/删除 hidden 类之前/之后更改图像的 src。这些延迟很少发生,这可能是它在您的机器上运行的原因。

    所以这个问题可以通过每次更改图像时都必须确保图像完全隐藏来解决。

    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 标签。

    【讨论】:

      猜你喜欢
      • 2015-05-30
      • 2011-08-10
      • 1970-01-01
      • 1970-01-01
      • 2021-11-14
      • 2012-05-15
      • 2021-12-31
      • 2013-06-07
      • 1970-01-01
      相关资源
      最近更新 更多