切换到新选项卡并返回后,幻灯片放映动画将停止并在下方显示图像

时间:2017-08-11 03:05:15

标签: javascript css reactjs animation

我创建了一个图像轮播,每隔几秒钟,旧图像从窗口向外滑动,而新图像从右侧滑入。但是,在切换标签并返回后,旋转木马不再动画,旧图像显示在旋转木马下方而不是滑出屏幕。

Javascript代码

var carouselImages = [
    'https://rm-goldenmedia.imgix.net/f417b6c79aef3008c247ce1f76ed0175.jpg?auto=format',
    'https://rm-goldenmedia.imgix.net/49e0f836260e386a655dae0914985502.jpg?auto=format',
    'https://rm-goldenmedia.imgix.net/4fcda316beec7d5f1b5dbe3f96fd2293.jpg?auto=format',
  'https://rm-goldenmedia.imgix.net/963f4f742ee1b59456827747db253e64.jpg?auto=format'
];

var App = React.createClass({
    render: function () {
        return (
            <div className="main">
                <Carousel images={carouselImages} />
            </div>
        );
    }
});

var Carousel = React.createClass({

    propTypes: {
        images: React.PropTypes.arrayOf([
            React.PropTypes.string
        ]).isRequired,
        showThumbnails: React.PropTypes.bool,
        slideshowActive: React.PropTypes.bool,
        slideshowDelay: React.PropTypes.number
    },

    getDefaultProps: function () {
        return {
            defaultSelectedIndex: 0,
            showThumbnails: true,
            slideshowActive: true,
            slideshowDelay: 4000
        };
    },

    getInitialState: function () {
        return {
            animationDirection: 'previous',
            selectedIndex: this.props.defaultSelectedIndex
        };
    },

    componentDidMount: function() {
        if (this.props.slideshowActive) {
            this.progressSlideshow();
        }
    },

    render: function () {
        var Animation = React.addons.CSSTransitionGroup;

        return (
            <div {...this.getProps()}>
                <div className="carousel--image">

                  <Animation transitionName={'animation--' + this.state.animationDirection}>
                        {this.renderCurrentImage()}
                    </Animation>

                </div>
                {this.renderThumbs()}
            </div>
        );
    },

    renderCurrentImage: function () {
        var selected = this.state.selectedIndex;
        var props = {
            key: selected,
            src: this.props.images[selected]
        };

        return (
            <img {...props} />
        );
    },



    renderThumbs: function () {
        var thumbnails = null;

        if (this.props.showThumbnails) {
            thumbnails = (
                <div className="carousel--thumbs">
                    {this.props.images.map(this.renderThumb)}
                </div>
            );
        }

        return thumbnails;
    },

    renderThumb: function (src, index) {
        var selected = (index === this.state.selectedIndex) ? ' carousel--selected' : '';
        var props = {
            className: 'carousel--thumb' + selected,
            key: index,
            onClick: this.handleThumbClick.bind(null, index),
            src: src
        }
        return <img {...props} />;
    },

    getProps: function () {
        var props = {
            className:'carousel',
            onKeyDown: this.handleKeyDown,
            tabIndex:'0'
        };

        if (this.props.slideshowActive) {
            props.onMouseEnter = this.handleMouseEnter;
            props.onMouseLeave = this.handleMouseLeave;
        }

        return props;
    },

    handleKeyDown: function (event) {
        var left = 37;
        var up = 38;
        var right = 39;
        var down = 40;
        var key = event.which;

        if (key === down || key === left) {
            this.goInDirection('previous');
        } else if (key === up || key === right) {
            this.goInDirection('next');
        }
    },

    handleMouseEnter: function () {
        clearTimeout(this.timeout);
    },

    handleMouseLeave: function () {
        this.progressSlideshow();
    },

    handleThumbClick: function (index) {
        this.goToIndex(index);
    },

    progressSlideshow: function () {
        this.setState({animationDirection: 'next'});

        this.timeout = setTimeout(function () {
            this.goInDirection('next');
            this.progressSlideshow();
        }.bind(this), this.props.slideshowDelay);
    },

    goToIndex: function (index) {
        var direction = (this.state.selectedIndex > index ) ? 'previous' : 'next';

        this.setState({
            animationDirection: direction,
            selectedIndex: index
        });
    },

    goInDirection: function (direction) {
        var totalImages = this.props.images.length;
        var modifier = (direction === 'next') ? 1 : -1;
        var newIndex = this.state.selectedIndex + modifier;

        if (newIndex === totalImages) {
            newIndex = 0;
        } else if (newIndex === -1) {
            newIndex = totalImages - 1;
        }

        this.setState({
            animationDirection: direction,
            selectedIndex: newIndex
        });
    }
});

React.render(<App />, document.getElementById('app'));

CSS代码

body {
  color: white;
  padding: 0;
  background: black;
}

.main {
  font: 16px / 1 Arial;
  position: relative;
}

.carousel {
  display: inline-block;
  overflow: hidden;
  outline: 0;
}

.carousel--thumbs {
  position: absolute;
  top: 370px;
  margin-top: 10px;
  text-align: center;
  display: flex;
  z-index: 3;
  overflow: hidden;
}

.carousel--thumb {
  border: 1px solid transparent;
  cursor: pointer;
  display: inline-block;
  height: 93px;
  width: 247px;
  transition: transform .2s ease-in-out;
}

.carousel--thumb:hover {
  transform: translate(0, -3px);
}

.carousel--selected {
  border-color: #fff;
}

.animation--next-enter {
  transform: translate(100%);
}

.animation--next-enter-active {
  transform: translate(0, 0);
  transition: transform 1500ms ease-in-out;
}

.animation--next-leave {
  left: 0;
  position: absolute;
  top: 0;
  transform: translate(0, 0);
}

.animation--next-leave-active {
  transform: translate(-100%, 0);
  transition: transform 1500ms ease-in-out;
}

.animation--previous-enter {
  transform: translate(-100%, 0);
}

.animation--previous-enter-active {
  transform: translate(0, 0);
  transition: transform 1500ms ease-in-out;
}

.animation--previous-leave {
  left: 0;
  position: absolute;
  top: 0;
  transform: translate(0, 0);
}

.animation--previous-leave-active {
  transform: translate(100%, 0);
  transition: transform 1500ms ease-in-out;
}

HTML代码

<!DOCTYPE html>
<html>

  <head>
    <script data-require="react-with-addons@0.14.3" data-semver="0.14.3" src="https://unpkg.com/react@0.14.3/dist/react-with-addons.js"></script>
    <link rel="stylesheet" href="style.css" />
  </head>

  <body>
      <div id="app"></div>
    <script src="script.js"></script>
  </body>

</html>

0 个答案:

没有答案