Search code examples
reactjshorizontal-scrollingsmooth-scrolling

Horizontal Scrolling using buttons in Reactjs


I'm making a horizontal scroll on a div element using left and right buttons.

I initially achieved the same with refs.

onClickLeft = () => {
    this.props.refELement.current.scrollLeft -= 300;
}
onClickRight = () => {
    this.props.refElement.current.scrollLeft += 300;
}

But I can't seem to find a way to set animation duration to this.

Using jquery, this can be achieved as:

$('.swipeRight').click(function(){
     $('.swipeBox').animate( { scrollLeft: '+=460' }, 1000);
});

$('.swipeLeft').click(function(){
     $('.swipeBox').animate( { scrollLeft: '-=460' }, 1000);
});

But this code is not reproducable in reactjs.

I want to achieve this in reactjs basically.

Any help with this?


Solution

  • you can use this code

    document.getElementById('left-button').onclick = function () {
       scrollLeft(document.getElementById('content'), -300, 1000);   
    }
    
    document.getElementById('right-button').onclick = function () {
       scrollLeft(document.getElementById('content'), 300, 1000);   
    }
        
    function scrollLeft(element, change, duration) {
        var start = element.scrollLeft,
            currentTime = 0,
            increment = 20;
            
            console.log(start)
            
        var animateScroll = function(){        
            currentTime += increment;
            var val = Math.easeInOutQuad(currentTime, start, change, duration);
            element.scrollLeft = val;
            if(currentTime < duration) {
                setTimeout(animateScroll, increment);
            }
        };
        animateScroll();
    }
    
    //t = current time
    //b = start value
    //c = change in value
    //d = duration
    Math.easeInOutQuad = function (t, b, c, d) {
      t /= d/2;
    	if (t < 1) return c/2*t*t + b;
    	t--;
    	return -c/2 * (t*(t-2) - 1) + b;
    };
    .left{
     float: left; 
     width: 30%;
     height: 200px;
     border: 1px solid black;
    }
    
    .internal{
     width: 31.75%;
     height: 100%;
     border: 1px solid black;
     display: inline-block;
    }
    
    .center{
     float: left; 
     width: 38.9%;
     height: 200px;
     border: 1px solid black;
     margin: 1px;
     overflow: hidden;
     /*will change this to hidden later to deny scolling to user*/
     white-space: nowrap;
    }
    
    .right{
     float: right; 
     width: 30%;
     height: 200px;
     border: 1px solid black;
    }
    <div class="left">
      left div
      <button id="left-button">
        swipe left
      </button>
    </div>
    <div class="center" id="content">
    <div class=internal>
      div 1
    </div>
     <div class=internal>
      div 2
    </div>
     <div class=internal>
      div 3
    </div>
     <div class=internal>
      div 4
    </div>
     <div class=internal>
      div 5
    </div>
     <div class=internal>
      div 6
    </div>
     <div class=internal>
      div 7
    </div>
     <div class=internal>
      div 8
    </div>
    </div>
    <div class="right">
    <button id="right-button">
        swipe right
      </button>
      right div
    </div>

    Based in this code