如何在React中创建平滑的背景图像过渡?

时间:2019-01-26 15:42:18

标签: css reactjs

我有一个标题,其标题根据州的不同而变化。每个类都有不同的背景图片,在CSS中指定。一切正常,但没有渐变效果的过渡非常突然。

我写道:

.jumbotron-img-1{
    background-image: url("/images/myImg1.jpg");
    transition: all 1s ease-in-out;

它可以工作,但是很难看。在图像以最终形式显示之前,存在缩放和图像失真。我看过Google上的一些教程,但是没有什么比简单的事情更重要的了,以至于纯CSS或React的背景图像转换都可以。

任何帮助将不胜感激,谢谢!

2 个答案:

答案 0 :(得分:4)

background-image不是可设置动画的属性。我觉得最适合您的目的是呈现多个标头,使所有可用的类名相对于公共父级以position: absolute;相互堆叠,并使用opacity属性(基于哪个类名)仅显示其中的一个处于您的状态并在opacity

上使用过渡

示例工作代码:

render() {
   const {imgClassList} = this.props;
   const {activeimgClass} = this.state;
   return (
     <div className="header-container">
       {imgClassList.map(imgClass => {
         return (
           <div 
             className={`header ${imgClass} ${(imgClass === activeimgClass)? 'active' : ''}`}
           />)
       })}
     </div>
   )
}

css类似于:

.header-container {
  position: relative;
}
.header{
  position: absolute;
  top: 0;
  left: 0;
  opacity: 0
  transition: opacity 1s ease-in-out;
}
.header.active {
  opacity: 1
}
.img-1 {
  background:url('images/img-1')
}
.img-2 {
  background: url('images/img-2')
} ... and so on

答案 1 :(得分:1)

根据CSS规范,没有一种使用CSS转换背景图像的好方法,因为它不是可设置动画的属性。一种方法是让多个图像相互叠加,每个图像都包含您要显示的另一幅图像,然后通过将它们转换为opacity: 0并更改其z来循环浏览它们-索引顺序。

我做了一个快速演示,演示了如何通过操纵不透明度和z索引来实现平滑的更改。在纯Javascript中,这是通过使用DOM操作简单地调整样式并使用setTimeout()来完成的。

当然,在React中,您不想进行DOM操作,因此您可以尝试使用具有不同不透明度级别和转换的多个类来完成此操作。似乎还有一个React组件可以启用所有类型的转换:https://reactcommunity.org/react-transition-group/css-transition

查看Javascript解决方案演示,以了解更改不透明度如何对图像产生淡入淡出效果:

function backgroundScheduler_1() {
  setTimeout(() => {
      document.querySelector(".img1").style.opacity = 0;
      document.querySelector(".img2").style.opacity = 1;
      document.querySelector(".img3").style.opacity = 1;
      order(["-3", "-1", "-2"], () => { backgroundScheduler_2() }, 1000);
  }, 3000);
}

function backgroundScheduler_2() {
  setTimeout(() => {
      document.querySelector(".img1").style.opacity = 1;
      document.querySelector(".img2").style.opacity = 0;
      document.querySelector(".img3").style.opacity = 1;
      order(["-2", "-3", "-1"], () => { backgroundScheduler_3() }, 1000);
  }, 3000);
}

function backgroundScheduler_3() {
  setTimeout(() => {
      document.querySelector(".img1").style.opacity = 1;
      document.querySelector(".img2").style.opacity = 1;
      document.querySelector(".img3").style.opacity = 0;
      order(["-1", "-2", "-3"], () => { backgroundScheduler_1() }, 1000);
  }, 3000);
}

function order(array, callback, time) {
  setTimeout(() => {
      document.querySelector(".img1").style.zIndex = array[0];
      document.querySelector(".img2").style.zIndex = array[1];
      document.querySelector(".img3").style.zIndex = array[2];
      callback();
  }, time);
}

backgroundScheduler_1();
.background-image {
  position: absolute;
  top: 0;
  left: 0;
  opacity: 1;
  transition: 1s;
}

.img1 {
  z-index: -1;
}

.img2 {
  z-index: -2;
}

.img3 {
  z-index: -3;
}
<div class="background-container">
  <img class="background-image img1" src="https://placeimg.com/640/640/nature"></img>
  <img class="background-image img2" src="https://placeimg.com/640/640/animals"></img>
  <img class="background-image img3" src="https://placeimg.com/640/640/tech"></img>
  
  <h2 style="color: white;">WOW!</h2>
</div>

我暂时检查了NPM,但没有看到任何可以保证这种确切功能的东西。希望这会有所帮助!