【问题标题】:ReactCSSTransition animation isn't smooth for imageReactCSSTransition 动画对图像不流畅
【发布时间】:2018-09-20 00:58:51
【问题描述】:

我尝试使用 ReactCSSTransitionGroup 在 React 中实现淡入/淡出动画。我在之前的 SO 答案中关注了这个solution。我有一个包含图像和文本的组件。动画对于文本来说是平滑的,但对于图像却不是。它看起来像动画期间图像闪烁。

jsfiddle

js

var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;

var items = [
    {id: 1, text: "item1", img: "https://mirrors.creativecommons.org/presskit/icons/cc.large.png"},
  {id: 2, text: "item2", img: "https://mirrors.creativecommons.org/presskit/icons/by.large.png"},
  {id: 3, text: "item3", img: "https://mirrors.creativecommons.org/presskit/icons/nc.large.png"},
  {id: 4, text: "item4", img: "https://mirrors.creativecommons.org/presskit/icons/nc-eu.large.png"},
]

function findObjectByKey(array, key, value) {
    for (var i = 0; i < array.length; i++) {
        if (array[i][key] === value) {
            return array[i];
        }
    }
    return null;
}

var SwitchContent = React.createClass({
    render: function() {
        var obj = findObjectByKey(items, 'id', this.props.id);
        console.log(obj);

        return (
            <div>
        <style
            dangerouslySetInnerHTML={{
              __html: [
                '.backgroundImg {',
                '  background: url('+obj.img+');',
                '  background-size: auto 100px;',
                '}',
              ].join('\n'),
            }}
          />
         <div className="backgroundImg" />
         <div className="textContent">{obj.text}</div>
      </div> 
        );

    }
});

var Switch = React.createClass({
    getInitialState: function() {
        return {
            id: 1,
        };
    },
    toggle: function(e) {
        this.setState({ id: this.state.id === 4 ? 1 : this.state.id + 1 });
    },
    render: function() {
        var key = this.state.id;

        return (
            <div>
              <button onClick={this.toggle}>Toggle</button>
              <ReactCSSTransitionGroup
              transitionAppear
        transitionAppearTimeout={500}
        transitionLeaveTimeout={500}
        transitionEnterTimeout={500}
              className="container"
              transitionName="example">
                <div key={key} className="item_container">
                  <SwitchContent id={key} />
                </div>
              </ReactCSSTransitionGroup>
            </div>
        );

    }
});

React.render(<Switch/>, document.getElementById("switch"));

CSS

.backgroundImg {
  background-repeat: no-repeat;
  background-position: center center;
  background-color: black;
  width: 100px;
  height: 100px;
}

.container {
    position: relative;
}
.container > div {
    position: absolute;
}
.button {
    display: block;
    height: 100px;
    width: 100px;
    border: 1px solid #aaa;
    border-radius: 25px;
    font: bold 20px Helvetica, Arial, sans-serif;
    text-align: center;
    line-height: 100px;
    cursor: pointer;
    color: #fff;
    background-color: #000;
    /* Define transition on the "opacity" property. */    
    transition: opacity 0.5s ease-in;
}
.example-enter {
  opacity: 0.01;
}

.example-enter.example-enter-active {
  opacity: 1;
  transition: opacity 500ms ease-in;
}

.example-leave {
  opacity: 1;
}

.example-leave.example-leave-active {
  opacity: 0.01;
  transition: opacity 500ms ease-in;
}

【问题讨论】:

    标签: reactjs css css-transitions css-animations reactcsstransitiongroup


    【解决方案1】:

    尝试将transition-delay CSS 类和ease-in-outtransition-delay 值设置为transition-timing-function

    .example-enter.example-enter-active {
        opacity: 1;
        transition: opacity 500ms ease-in-out 500ms;
    }
    
    .example-leave.example-leave-active {
       opacity: 0.01;
       transition: opacity 500ms ease-in-out;
     }
    

    这样看起来更流畅。分叉JSFiddle

    【讨论】:

      【解决方案2】:

      不确定您的小提琴到底发生了什么,以及为什么下一张图片看起来没有缓和。

      但是,我确实在最新的 react 和使用生成器中重写了您的示例,一切似乎都正常。

      您错过了 example-appear 类,但我认为还有更多。 你可以在这里查看我的沙盒:https://codesandbox.io/s/zw0xv4vy3x

      如果基于这个工作示例,您能够找出您的问题所在,那就太好了! 如果没有,只需复制并粘贴即可。

      js

      import React, { Component } from "react";
      import ReactCSSTransitionGroup from "react-addons-css-transition-group";
      import { render } from "react-dom";
      import "./main.css";
      
      function* continuosArrayIterator(arr) {
        let idx = 0;
        while (idx < arr.length) {
          let ret = arr[idx];
          idx++;
          if (idx === arr.length) {
            idx = 0;
          }
          yield ret;
        }
      }
      
      class App extends Component {
        constructor() {
          super();
          this.clickHandler = this.clickHandler.bind(this);
          this.items = [
            {
              id: 1,
              text: "item1",
              img: "https://mirrors.creativecommons.org/presskit/icons/cc.large.png"
            },
            {
              id: 2,
              text: "item2",
              img: "https://mirrors.creativecommons.org/presskit/icons/by.large.png"
            },
            {
              id: 3,
              text: "item3",
              img: "https://mirrors.creativecommons.org/presskit/icons/nc.large.png"
            },
            {
              id: 4,
              text: "item4",
              img:
                "https://mirrors.creativecommons.org/presskit/icons/nc-eu.large.png"
            }
          ];
          this.imageIterator = continuosArrayIterator(this.items);
          this.state = {
            image: this.imageIterator.next().value
          };
        }
      
        clickHandler(event) {
          return this.setState({
            image: this.imageIterator.next().value
          });
        }
      
        render() {
          return (
            <div>
              <button onClick={this.clickHandler}>Next Image</button>
              <ReactCSSTransitionGroup
                transitionAppear={true}
                transitionLeaveTimeout={500}
                transitionEnterTimeout={500}
                className="container"
                transitionName="example"
              >
                <div
                  key={this.state.image.id}
                  style={{
                    position: "absolute",
                    backgroundImage: `url(${this.state.image.img}`,
                    backgroundSize: "auto 100px",
                    height: "100px",
                    width: "100px"
                  }}
                />
              </ReactCSSTransitionGroup>
            </div>
          );
        }
      }
      
      render(<App />, document.getElementById("root"));
      

      css

      .container {
        position: absolute;
      }
      
      .example-enter {
        opacity: 0.01;
      }
      
      .example-enter.example-enter-active {
        opacity: 1;
        transition: opacity 500ms ease-in;
      }
      
      .example-leave {
        opacity: 1;
      }
      
      .example-leave.example-leave-active {
        opacity: 0.01;
        transition: opacity 500ms ease-in;
      }
      
      .example-appear {
        opacity: 0.01;
      }
      
      .example-appear.example-appear-active {
        opacity: 1;
        transition: opacity 0.5s ease-in;
      }
      

      【讨论】:

        猜你喜欢
        • 2014-10-30
        • 2010-11-07
        • 2017-07-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-23
        • 1970-01-01
        • 2021-05-17
        • 2018-07-28
        相关资源
        最近更新 更多