スクロールスナップスライダーを作成

  • WebDesign
  • スクロールスナップスライダーを作成する方法を紹介します。

    スクロールでもボタンでもスライドの移動ができます。スライドが左端にスナップします。

    スクロールでもボタンでもスライドの移動ができる

    スライドが左端にスナップ

    コード

    <div id = "container">
    	<div id="target">
    		<ul id="sample">
      			<li class="slide">1</li>
    			<li class="slide">2</li>
    			<li class="slide">3</li>
    			<li class="slide">4</li>
    			<li class="slide">5</li>
    			<li class="slide">6</li>
    			<li class="slide">7</li>
    		</ul>
    		<button class="next-arrow"></button>
    		<button class="prev-arrow"></button>
    	</div>
    </div>
    #container{
    	width: 100vw;
    	height: 100vh;
    	background: #eee;
    	display: grid;
    	align-items: center;
    	align-content: center;
    }
    .container {
    	width: 90vw;
    	overflow: auto;
    	scroll-snap-type: x;
    	display: flex;
    	margin: 0 auto;
    	position: relative;
    	background: green;
    }
    .container::-webkit-scrollbar {
    	height: 20px;
    }
    .container::-webkit-scrollbar-thumb {
      background: #276976;
      background-clip: padding-box; 
    }
    .container::-webkit-scrollbar-track {
      background-color: #000;
    }
    .next-arrow{
    	background: red;
    	position: fixed;
    	width: 30px;
    	height: 30px;
    	-webkit-transform: translateY(-50%);
    	transform: translateY(-50%);
    	top: 50%;
    	right: 0;
    	cursor: pointer;
    }
    .next-arrow::before{
    	content: '';
    	position: absolute;
    	-webkit-transform: translate(-50%, -50%)  rotate(45deg);
    	transform: translate(-50%, -50%)  rotate(45deg);
    	transform-origin: center;
    	left: 40%;
    	top: 50%;
    	width: 15px;
    	height: 15px;
    	border-top: solid 1px #fff;
    	border-right: solid 1px #fff;
    }
    .prev-arrow{
    	background: red;
    	position: fixed;
    	width: 30px;
    	height: 30px;
    	-webkit-transform: translateY(-50%);
    	transform: translateY(-50%);
    	top: 50%;
    	left: 0;
    	cursor: pointer;
    	opacity: 0.5;
    	pointer-events: none;
    }
    .prev-arrow::before{
    	content: '';
    	position: absolute;
    	-webkit-transform: translate(-50%, -50%)  rotate(-45deg);
    	transform: translate(-50%, -50%)  rotate(-45deg);
    	transform-origin: center;
    	left: 60%;
    	top: 50%;
    	width: 15px;
    	height: 15px;
    	border-top: solid 1px #fff;
    	border-left: solid 1px #fff;
    }
    #target {
    	overflow: auto;
    	width: 100vw;
    	height: 50svh;
    	scroll-snap-type: x;
    }
    #sample {
    	width: 350vw;
    	height: 100%;
    	background-color: blue;
    	display: flex;
    }
    .slide{
    	width: 50vw;
    	display: grid;
    	align-content: center;
    	align-items: center;
    	background: #666;
    	scroll-snap-align: start;
    	font-size: 4rem;
    	text-align: center;
    	color: #fff;
    }
    ul li.slide:first-child{
    	background: orange;
    }
    ul li.slide:nth-child(2){
    	background: green;
    }
    ul li.slide:nth-child(3){
    	background: blue;
    }
    ul li.slide:nth-child(4){
    	background: gray;
    }
    ul li.slide:nth-child(5){
    	background: violet;
    }
    ul li.slide:last-child{
    	background: green;
    }
    #target::-webkit-scrollbar {
    	height: 15px;
    }
    #target::-webkit-scrollbar-thumb {
      background: #276976;
    }
    #target::-webkit-scrollbar-track {
      background-color: #000;
    }
    let target = document.getElementById('target');
    
    function moveScroll(){
    	const rect = document.documentElement.scrollWidth;
    	const rectWidth = rect / 2;	
    	target.scrollBy({
    		top: 0,
    		left: rectWidth,
    		behavior: "smooth",
    	});
    }
    
    function moveScroll2(){
    	const rect2 = document.documentElement.scrollWidth;
    	const rectWidth2 = rect2 / 2;	
    	target.scrollBy({
    		top: 0,
    		left: -rectWidth2,
    		behavior: "smooth",
    	});
    }
    
    const nextBtn = document.querySelector('.next-arrow');
    const prevBtn = document.querySelector('.prev-arrow');
    
    nextBtn.addEventListener('click', () => {
    	moveScroll();		
    });
    
    const getScroll = () =>{
    	const rect3 = document.documentElement.scrollWidth;
    	const rectWidth3 = rect3 / 2;	
    	let  x = target.scrollLeft;
    	//console.log(x);
    	if( x > rectWidth3 * 5 -1 ){
    		nextBtn.style.pointerEvents=('none');
    		nextBtn.animate(
    			{
    				opacity: [1, 0.5]
    			},
    			{
    				duration: 800,
    				fill: 'forwards',
    				easing: 'ease'
    			}
    		);
    	}else if(x < 1){
    		prevBtn.style.pointerEvents=('none');
    		prevBtn.animate(
    			{
    				opacity: [1, 0.5]
    			},
    			{
    				duration: 800,
    				fill: 'forwards',
    				easing: 'ease'
    			}
    		);
    	}else {
    		prevBtn.style.pointerEvents=('auto');
    		prevBtn.animate(
    			{
    				opacity: [1]
    			},
    			{
    				duration: 800,
    				fill: 'forwards',
    				easing: 'ease'
    			}
    		);
    		nextBtn.style.pointerEvents=('auto');
    		nextBtn.animate(
    			{
    				opacity: [1]
    			},
    			{
    				duration: 800,
    				fill: 'forwards',
    				easing: 'ease'
    			}
    		);
    	}
    }
    
    target.addEventListener('scroll', getScroll);
    
    prevBtn.addEventListener('click', () => {
    	moveScroll2();
    });