Negin Basiri
Negin Basiri

Reputation: 1375

Direction of Slide animation in React

I am creating a carousel and there are 2 buttons Next and Previous. on clicking Next it should slide from left to right and on clicking Previous it should slide from right to left. (I don't want to use any plugin)

My React container:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { prevItem, nextItem, initItem } from '../actions/index';
import { bindActionCreators } from 'redux';
import CSSTransitionGroup from 'react-transition-group/CSSTransitionGroup';

class Carousel extends Component{

    previous(){
        this.props.prevItem();
    }

    next(){
        this.props.nextItem();
    }


    componentDidMount(){
        this.props.initItem();
    }

    renderItem(){
        const  {item} = this.props;
        const webLink = `http://${item.link}`;
        const transitionOptions = {
            transitionName: 'slide',
            transitionEnterTimeout: 1000,
            transitionLeaveTimeout: 1000
        };


        return(
            <CSSTransitionGroup {...transitionOptions}>
                <div className="carousel__item" key={item.id}>
                    <img className="carousel__image" src={item.imageurl}/>
                    <div className="carousel__text">
                        <h3>{item.title}</h3>
                        <p>{item.synopsis}</p>
                        <a href={webLink} target="_black">{item.link}</a>
                    </div>
                </div>
            </CSSTransitionGroup>
        )

    }
    render(){


        return(

                <div className="carousel">
                    {this.renderItem()}
                    <div className="carousel__prev" onClick={this.previous.bind(this)}>
                        <i className="fa fa-chevron-left"></i>
                    </div>
                    <div className="carousel__next" onClick={this.next.bind(this)}>
                        <i className="fa fa-chevron-right"></i>
                    </div>
                </div>

        )
    }
}

function mapStateToProps(state){
    return {item: state.item};
}

function mapDispatchToProps(dispatch){
    return bindActionCreators({
        initItem: initItem,
        nextItem: nextItem,
        prevItem: prevItem
    }, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(Carousel);

Any my Style.css is:

.carousel{
    width: 100%;
    border: 1px solid #ccc;
    margin-top: 100px;
    position: relative;
}

.carousel__item{
    width: 100%;
    color: #fff;
    position: relative;
}

.carousel__item img{
    width: 100%;
    background: rgba(0,0,0,.6);
}

.carousel__text{
    text-align: center;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.carousel__text a:hover,
.carousel__text a{
    color: #fff;
}

.carousel__prev{
    position: absolute;
    left: 0;
    top: 50%;
    color: #fff;
    margin-left: 10px;
    cursor: pointer;
    font-size: 25px;
}

.carousel__next{
    position: absolute;
    right: 0;
    top: 50%;
    color: #fff;
    margin-right: 10px;
    cursor: pointer;
    font-size: 25px;
}

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

.slide-enter-active{
    transform: translate(0%);
    transition: transform 1000ms ease-in-out;
}

.slide-leave{
    transform: translate(0%);
}

.slide-leave-active{
    transform: translate(-100%);
    transition: transform 1000ms ease-in-out;
}

Apart from the direction, the current slide animation is not correct. when it slides the previous slide is showing below. So basically 2 slides are showing on screen on transition. Do you know how to fix this problem and also address the direction of slide?

Upvotes: 2

Views: 7802

Answers (2)

KARTHIKEYAN.A
KARTHIKEYAN.A

Reputation: 20098

We can create slide animation in the following way using slide for Dialog

const Transition = React.forwardRef(function Transition(props, ref) {
    return <Slide direction='up' ref={ref} {...props} />
})

<Dialog
    open={open}
    TransitionComponent={Transition} // Transition fade 
    keepMounted
    onClose={handleClose}
    aria-labelledby='alert-dialog-slide-title'
    aria-describedby='alert-dialog-slide-description'
    fullWidth
></Dialog>

Upvotes: 0

sh3nan1gans
sh3nan1gans

Reputation: 2356

I just worked through this problem.

In order to slide in the correct direction, you'll need to maintain some state and apply this state to your items via className. Something like this:

render () {
    <CSSTransitionGroup
        component={MenuWrapper}
        transitionName="slide"
        transitionEnterTimeout={500}
        transitionLeaveTimeout={500}>
        {this._renderMenu(this.props.selectedSubMenus[menuIdx], menuIdx)}
      </CSSTransitionGroup>
}


_renderMenu = (menu, idx) => {
    return (
        <Menu key={idx} className={this.state.animationDirection} order={idx}>
            content      
       </Menu>
    )
}

Your css should look something like this (note that I'm using styled-components for a few elements):

const menuWidth = "256px";
const MenuWrapper = styled.div`
    display: flex;
    overflow: hidden;
    max-width: ${menuWidth};
`

const Menu = styled.div`
    min-width: ${menuWidth};
    order: ${props => props.order};
`
.slide-enter.left {
    transform: translate(-100%);
}
.slide-enter.slide-enter-active.left {
    transform: translate(0%);
    transition: transform 500ms ease-in-out;
}
.slide-leave.left {
    transform: translate(-100%);
}
.slide-leave.slide-leave-active.left {
    transform: translate(0%);
    transition: transform 500ms ease-in-out;
}
.slide-enter.right {
    transform: translate(0%);
}
.slide-enter.slide-enter-active.right {
    transform: translate(-100%);
    transition: transform 500ms ease-in-out;
}
.slide-leave.right {
    transform: translate(0%);
}
.slide-leave.slide-leave-active.right {
    transform: translate(-100%);
    transition: transform 500ms ease-in-out;
}

Note that I used flexbox in order to fix the display problem (as well as some hard-coded widths)

Hope this helps

Upvotes: 2

Related Questions