React を使用したレスポンシブカルーセル

Oluwafisayo Oluwatayo 2023年1月30日
  1. React Slick を使用したレスポンシブカルーセル
  2. React フックを使用したレスポンシブカルーセル
  3. React Material-UI を使用したレスポンシブカルーセル-UI
  4. まとめ
React を使用したレスポンシブカルーセル

React カルーセルは、スライド形式でアイテムを表示できるエフェクトです。このように、見たいアイテムが次々に解かれるので、ページを上下にスクロールしなくても、複数のアイテムを簡単に表示できます。

この素晴らしいデザインは、E コマースの Web サイトに最適です。これは、製品を一度に表示するための優れた方法です。

また、ポートフォリオを作成しようとする人にとって、カルーセル効果は、Web サイトの訪問者がストレスなく提供されるサービスを見ることができるようにするために優れています。

React でこのスライド効果を利用する方法はいくつかあります。矢印ボタン付きのカルーセルを使用できるため、ユーザーは手動で前後にクリックしてアイテムを表示できます。

アイテムを最初から最後まで自動的に表示してから、ループのように再開する自動化することもできます。

そこで、次に、React フレームワーク内でこの関数を呼び出すためのさまざまなメソッドを見てみましょう。

React Slick を使用したレスポンシブカルーセル

この例では、react-slick 依存関係を利用して機能します。新しいプロジェクトフォルダを作成したら、ターミナル内のプロジェクトフォルダに移動してライブラリをインストールします。npm install react-slick --save を使用してインストールします。

また、React slick-carousel をインストールする必要があります。これにより、カルーセルの CSS とフォントを構成できるようになります。この依存関係は、npm install slick-carousel を使用してインストールします。

次に、2つのフォルダを作成します。1つはカルーセル用で、もう 1つは CSS アスペクト用です。Components フォルダを作成します。その中に、Slider.js を作成します。

次に、別のフォルダーを作成します。これを css と呼びます。そして、その中に App.scss ファイルを作成します。

その後、Slider.js ファイルに進み、次のコードを入力します。

コードスニペット(Slider.js):

import React from 'react';
import Slider from "react-slick";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";


function ImageSlider() {
    let settings = {
        dots: true,
        infinite: true,
        speed: 500,
        slidesToShow: 3,
        slidesToScroll: 1,
        cssEase: "linear"
    }
    return (
        <Slider {...settings}>
            <div className="card-wrapper">
                <div className="card">
                    <div className="card-image">
                        <img src="images/1.jpg" />
                    </div>
                    <ul className="social-icons">
                        <li><a href="#"><i className="fa fa-facebook"></i></a></li>
                        <li><a href="#"><i className="fa fa-instagram"></i></a></li>
                        <li><a href="#"><i className="fa fa-twitter"></i></a></li>
                        <li><a href="#"><i className="fa fa-dribbble"></i></a></li>
                    </ul>
                    <div className="details">
                        <h2>BMW <span className="job-title">M5</span></h2>
                    </div>
                </div>
            </div>
            <div className="card-wrapper">
                <div className="card">
                    <div className="card-image">
                        <img src="images/2.png" />
                    </div>
                    <ul className="social-icons">
                        <li><a href="#"><i className="fa fa-facebook"></i></a></li>
                        <li><a href="#"><i className="fa fa-instagram"></i></a></li>
                        <li><a href="#"><i className="fa fa-twitter"></i></a></li>
                        <li><a href="#"><i className="fa fa-dribbble"></i></a></li>
                    </ul>
                    <div className="details">
                        <h2>Graphic <span className="job-title">Design</span></h2>
                    </div>
                </div>
            </div>
            <div className="card-wrapper">
                <div className="card">
                    <div className="card-image">
                        <img src="images/3.png" />
                    </div>
                    <ul className="social-icons">
                        <li><a href="#"><i className="fa fa-facebook"></i></a></li>
                        <li><a href="#"><i className="fa fa-instagram"></i></a></li>
                        <li><a href="#"><i className="fa fa-twitter"></i></a></li>
                        <li><a href="#"><i className="fa fa-dribbble"></i></a></li>
                    </ul>
                    <div className="details">
                        <h2>Embrace<span className="job-title">Your Darkness</span></h2>
                    </div>
                </div>
            </div>
            <div className="card-wrapper">
                <div className="card">
                    <div className="card-image">
                        <img src="images/4.jpg" />
                    </div>
                    <ul className="social-icons">
                        <li><a href="#"><i className="fa fa-facebook"></i></a></li>
                        <li><a href="#"><i className="fa fa-instagram"></i></a></li>
                        <li><a href="#"><i className="fa fa-twitter"></i></a></li>
                        <li><a href="#"><i className="fa fa-dribbble"></i></a></li>
                    </ul>
                    <div className="details">
                        <h2>ML <span className="job-title">Fashion</span></h2>
                    </div>
                </div>
            </div>
        </Slider>
    )
}

export default ImageSlider

使用したいアイテムのデータと写真を含むコンポーネントを作成し、これらすべてを <Slider></Slider> タグで囲みます。これは、以前にインストールしたカルーセルライブラリです。

次に、App.js フォルダに移動して、次のコードを記述します。

コードスニペット(App.js):

import ImageSlider from "./Components/Slider";
import "./css/App.css"
function App() {
  return (
    <div className="container mt-5 carousel">
      <h1 className="slider_title">React Image Carousel</h1>
      <ImageSlider />
    </div>
  );
}

export default App;

カルーセルは Web ページのエフェクトの一種であるため、CSS の側面はセットアップの非常に重要な部分です。各画像の移動方法と通過にかかる時間を制御するために、多くの CSS を実行します。

コードスニペット(App.scss):

* {
    margin: 0;
    padding: 0;
  }

  body {
    display: block;
    width: 100%;
    height: 100vh;
    overflow: hidden;
    font-family: "Raleway", sans-serif;
    position: relative;
    background: #333;
  }

  .slider_title {
    font-size: 5vw;
    color: tomato;
    text-transform: uppercase;
    text-align: center;
    margin-bottom: 2vw;
  }

  .card-wrapper {
    position: relative;
    width: 100%;
    padding: 0 10px;
    -webkit-box-sizing: border-box;
            box-sizing: border-box;
  }

  .card-wrapper:active, .card-wrapper:hover, .card-wrapper:focus {
    outline: none;
    border: none;
  }

  .card {
    width: 100%;
    height: 450px;
    border-radius: 16px;
    overflow: hidden;
    cursor: pointer;
    position: relative;
  }

  .card .card-image {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 2;
    background-color: #000;
    -webkit-transition: .5s;
    transition: .5s;
  }

  .card .card-image img {
    width: 100%;
    height: 100%;
    -o-object-fit: cover;
       object-fit: cover;
  }

  .card:hover img {
    opacity: .4;
    -webkit-transition: .5s;
    transition: .5s;
  }

  .card:hover .card-image {
    -webkit-transform: translateY(-100px);
            transform: translateY(-100px);
    -webkit-transition: all .9s;
    transition: all .9s;
  }

  .social-icons {
    position: absolute;
    top: 50%;
    left: 50%;
    -webkit-transform: translate(-50%, -50%);
            transform: translate(-50%, -50%);
    z-index: 3;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
  }

  .social-icons li {
    list-style: none;
  }

  .social-icons li a {
    position: relative;
    display: block;
    width: 50px;
    height: 50px;
    line-height: 50px;
    text-align: center;
    background: #fff;
    font-size: 23px;
    color: #333;
    font-weight: bold;
    margin: 0 6px;
    -webkit-transition: .4s;
    transition: .4s;
    -webkit-transform: translateY(200px);
            transform: translateY(200px);
    opacity: 0;
  }

  .card:hover .social-icons li a {
    -webkit-transform: translateY(0px);
            transform: translateY(0px);
    opacity: 1;
  }

  .social-icons li a:hover {
    background: #000;
    -webkit-transition: .2s;
    transition: .2s;
  }

  .social-icons li a:hover .fa {
    color: #fff;
  }

  .social-icons li a .fa {
    -webkit-transition: .8s;
    transition: .8s;
  }

  .social-icons li a .fa:hover {
    -webkit-transform: rotateY(360deg);
            transform: rotateY(360deg);
    color: #fff;
  }

  .card:hover li:nth-child(1) a {
    -webkit-transition-delay: .1s;
            transition-delay: .1s;
  }

  .card:hover li:nth-child(2) a {
    -webkit-transition-delay: .2s;
            transition-delay: .2s;
  }

  .card:hover li:nth-child(3) a {
    -webkit-transition-delay: .3s;
            transition-delay: .3s;
  }

  .card:hover li:nth-child(4) a {
    -webkit-transition-delay: .4s;
            transition-delay: .4s;
  }

  .details {
    position: absolute;
    bottom: 400px;
    left: 0;
    background: #fff;
    width: 100%;
    height: 120px;
    z-index: 1;
    padding: 10px;
    -webkit-transition: .6s;
    transition: .6s;
  }

  .details h2 {
    margin: 30px 0;
    padding: 0;
    text-align: center;
  }

  .details h2 .job-title {
    font-size: 16px;
    line-height: 2;
    color: #333;
    font-weight: 300;
    display: block;
  }

  .card:hover .details {
    bottom: 0;
  }

  .carousel .slick-dots {
    bottom: -2.5vw;
  }

  .carousel .slick-dots li button {
    width: 20px;
    height: 20px;
    border: 1px solid #fff;
    border-radius: 20px;
  }

  .carousel .slick-dots li button:before {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 10px;
    height: 10px;
    border-radius: 10px;
    content: "";
    text-align: center;
    opacity: .5;
    color: #000;
    background-color: #fff;
    -webkit-transform: translate(-50%, -50%);
            transform: translate(-50%, -50%);
    -webkit-transition: all .3s ease-in-out;
    transition: all .3s ease-in-out;
  }

  .carousel .slick-dots li.slick-active button, .carousel .slick-dots li:hover button {
    border-color: tomato;
  }

  .carousel .slick-dots li.slick-active button:before, .carousel .slick-dots li:hover button:before {
    background-color: tomato;
    opacity: 1;
  }

  .carousel .slick-prev, .carousel .slick-next {
    width: 50px;
    height: 50px;
    background-color: #fff;
  }

  .carousel .slick-prev:hover, .carousel .slick-prev:focus, .carousel .slick-next:hover, .carousel .slick-next:focus {
    color: #fff;
    outline:
   none;
    background: #fff;
  }

  .carousel .slick-prev:before, .carousel .slick-next:before {
    color: #000;
    font-family: "Raleway", sans-serif;
  }

  .carousel .slick-next {
    right: -55px;
  }

  .carousel .slick-prev {
    left: -55px;
  }

また、CSS 内で画像サイズを設定します。また、写真やフォントに追加された情報の表示方法も設定しました。

出力:

React Slick を使用したレスポンシブカルーセル

React フックを使用したレスポンシブカルーセル

この例では、カルーセル効果で発生する値の切り替えに役立つ React の useState フックを利用します。

新しい react プロジェクトを作成したら、npm install react-icons を使用して react-icons ライブラリをインストールする必要があります。この依存関係により、画像間をスライドするために使用する左矢印アイコンと右矢印アイコンが提供されます。

次に、プロジェクトフォルダ内の src フォルダに移動し、components という新しいフォルダを作成します。その中に 2つのファイル、つまり SliderData.jsImageSlider を作成します。

まず、ImageSlider.js を使用してコーディングの側面に進みます。

コードスニペット(ImageSlider.js):

import React, { useState } from 'react';
import { SliderData } from './SliderData';
import { FaArrowAltCircleRight, FaArrowAltCircleLeft } from 'react-icons/fa';

const ImageSlider = ({ slides }) => {
  const [current, setCurrent] = useState(0);
  const length = slides.length;

  const nextSlide = () => {
    setCurrent(current === length - 1 ? 0 : current + 1);
  };

  const prevSlide = () => {
    setCurrent(current === 0 ? length - 1 : current - 1);
  };

  if (!Array.isArray(slides) || slides.length <= 0) {
    return null;
  }

  return (
    <section className='slider'>
      <FaArrowAltCircleLeft className='left-arrow' onClick={prevSlide} />
      <FaArrowAltCircleRight className='right-arrow' onClick={nextSlide} />
      {SliderData.map((slide, index) => {
        return (
          <div
            className={index === current ? 'slide active' : 'slide'}
            key={index}>
            {index === current && (
              <img src={slide.image} alt='travel image' className='image' />
            )}
          </div>
        );
      })}
    </section>
  );
};

export default ImageSlider;

useState 関数を適用して、nextSlide を増やすように設定します。つまり、次のアイテムに移動しますが、prevSlide は正反対です。次に、onClick イベントリスナーを呼び出して、対応する矢印がクリックされるたびにこれらの関数をアクティブにします。

次に、SliderData.js に進みます。ここで、カルーセル効果で表示したい画像の配列を作成します。

コードスニペット(SliderData.js):

export const SliderData = [
    {
        image:
            'https://images.unsplash.com/photo-1546768292-fb12f6c92568?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=crop&w=1350&q=80'
    },
    {
        image:
            'https://images.unsplash.com/photo-1501446529957-6226bd447c46?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&auto=format&fit=crop&w=1489&q=80'
    },
    {
        image:
            'https://images.unsplash.com/photo-1483729558449-99ef09a8c325?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&auto=format&fit=crop&w=1350&q=80'
    },
    {
        image:
            'https://images.unsplash.com/photo-1475189778702-5ec9941484ae?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&auto=format&fit=crop&w=1351&q=80'
    },
    {
        image:
            'https://images.unsplash.com/photo-1503177119275-0aa32b3a9368?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&auto=format&fit=crop&w=1350&q=80'
    }
];

次に、App.js に移動し、コードを少し追加します。

コードスニペット(App.js):

import './App.css';
import ImageSlider from './components/ImageSlider';
import { SliderData } from './components/SliderData';

function App() {
  return <ImageSlider slides={SliderData} />;
}

export default App;

前述の CSS は、カルーセル効果が希望どおりに機能することを確認する上で重要な役割を果たします。そのため、App.css ファイル内に移動して、いくつかの調整を行います。

コードスニペット(App.css):

.slider {
  position: relative;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.image {
  width: 1000px;
  height: 600px;
  border-radius: 10px;
}

.right-arrow {
  position: absolute;
  top: 50%;
  right: 32px;
  font-size: 3rem;
  color: #000;
  z-index: 10;
  cursor: pointer;
  user-select: none;
}

.left-arrow {
  position: absolute;
  top: 50%;
  left: 32px;
  font-size: 3rem;
  color: #000;
  z-index: 10;
  cursor: pointer;
  user-select: none;
}

.slide {
  opacity: 0;
  transition-duration: 1s ease;
}

.slide.active {
  opacity: 1;
  transition-duration: 1s;
  transform: scale(1.08);
}

これらすべてのコードを指示どおりに配置すると、カルーセル効果がうまく機能するはずです。

出力:

React フックを使用したレスポンシブカルーセル

React Material-UI を使用したレスポンシブカルーセル-UI

React Material-UI は、react カルーセルのナビゲーション矢印を設定するために展開する機能ライブラリです。次に、react 状態フックを使用してジョブを終了します。

新しいプロジェクトを作成したら、npm install @material-ui/corenpm install @material-ui/icons を使用して material-UI をインストールします。

次に、src に移動し、ComponentsHelpers、および Images の 3つのフォルダーを作成します。Components フォルダ内に Carousel.jsCarousel.css を作成します。

Helpers フォルダ内に CarouselData.js を作成し、Images フォルダ内に画像を配置します。Carousel.js フォルダから始めて、次のコードを入力します。

コードスニペット(Carousel.js):

import React, { useState } from "react";
import "./Carousel.css";
import { images } from "../Helpers/CarouselData";
import ArrowBackIosIcon from "@material-ui/icons/ArrowBackIos";
import ArrowForwardIosIcon from "@material-ui/icons/ArrowForwardIos";

function Carousel() {
  const [currImg, setCurrImg] = useState(0);

  return (
    <div className="carousel">
      <div
        className="carouselInner"
        style={{ backgroundImage: `url(${images[currImg].img})` }}
      >
        <div
          className="left"
          onClick={() => {
            currImg > 0 && setCurrImg(currImg - 1);
          }}
        >
          <ArrowBackIosIcon style={{ fontSize: 30 }} />
        </div>
        <div className="center">
          <h1>{images[currImg].title}</h1>
          <p>{images[currImg].subtitle}</p>
        </div>
        <div
          className="right"
          onClick={() => {
            currImg < images.length - 1 && setCurrImg(currImg + 1);
          }}
        >
          <ArrowForwardIosIcon style={{ fontSize: 30 }} />
        </div>
      </div>
    </div>
  );
}

export default Carousel;

ここで、useState を使用してすべてのナビゲーション操作を設定し、いずれかの矢印をクリックしたときに何が起こるかを定義します。これにより、onClick イベントリスナーがトリガーされます。

次に、Carousel.css を使用して対応する CSS を設定します。

コードスニペット(Carousel.css):

.carousel {
    width: 60%;
    height: 700px;
    background-color: black;
}

.carouselInner {
    height: 100%;
    width: 100%;
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
    display: flex;
}

.carouselInner .left {
    flex: 5%;
    height: 100%;
    background-color: rgb(0, 0, 0, 0.6);
    display: grid;
    place-items: center;
    color: white;
    cursor: pointer;
}

.carouselInner .center {
    flex: 80%;
    height: 100%;
    display: grid;
    place-items: center;
    font-family: Arial, Helvetica, sans-serif;
    text-align: justify;
    text-align-last: center;
}

h1 {
    font-size: 5rem;
}

p {
    font-size: 2rem;
}

h1, p {
    background-color: rgb(255, 255, 255, 0.8);
    padding: 20px;
    border-radius: 9px;
}

.carouselInner .right {
    flex: 5%;
    height: 100%;
    background-color: rgb(0, 0, 0, 0.6);
    display: grid;
    place-items: center;
    color: white;
    cursor: pointer;
}

Helpers フォルダには、CarouselData.js ファイルがあります。名前が示すように、ファイルには、Web ページに表示したい画像やその他の情報が含まれています。

コードスニペット(CarouselData.js):

import City from "../Images/city.jpg";
import Salvador from "../Images/salvador.jpg";
import Ubc from "../Images/ubc.jpg";

export const images = [
  { title: "San Diego",
  subtitle: "This is San Diego",
  img: City,
  },
  {
    title: "Salvador, Brazil",
    subtitle: "The Best City in the World",
    img: Salvador,
  },
  {
    title: "UBC (Vancouver)",
    subtitle: "The University of British Columbia",
    img: Ubc,
  },
];

最後に、App.js で少しコーディングします。このファイルは、プロジェクトが適切にレンダリングされることを確認します。

コードスニペット(App.js):

import "./App.css";
import Carousel from "./Components/Carousel";
import React from "react";
function App() {
  return (
    <div className="App">
      <Carousel />
    </div>
  );
}

export default App;

出力:

ReactMaterial を使用したレスポンシブカルーセル-UI

まとめ

カルーセル効果は、使用目的に関係なく Web ページを美しくします。また、React フレームワークは、スライド効果を Web アプリで実行するためのさまざまな方法を探索するための非常に柔軟なプラットフォームを提供します。

Oluwafisayo Oluwatayo avatar Oluwafisayo Oluwatayo avatar

Fisayo is a tech expert and enthusiast who loves to solve problems, seek new challenges and aim to spread the knowledge of what she has learned across the globe.

LinkedIn