反応カルーセルをゼロからコーディング


私は最近、ミュージシャンのためのアプリケーションに接続し、同様の設定に基づいて一致するように取り組んでいる.私はUX/UIは、別のプロファイルカードをスクロールすることができますtinder swiperのようなものであった.過去に、私はブートストラップのような図書館をカルーセルのようなプレゼンテーションを達成するために使用しました、しかし、私は私の反応アプリの中でバニラJSでそれ自体を構築するために、私自身に挑戦したかったです.
私の最初の考えは、画面の中と外にカードを移動するためにトグルされたクラスでCSSアニメーションを使用することでした、しかし、私はすぐにこの方法を無効にしました.私はすぐに私はこの問題を解決するためにJSを使用する必要があります知っていた.それで、私を私のプロセスを通してあなたに歩かせてください.
開始するには、私はデータの配列をする必要がありました-強打を介してミュージシャンをお勧めします.これは私のredux状態にそれらの推薦を格納したならば、これは比較的簡単でした.注意してください、このためにreduxを必要としません、私が私のアプリケーションのより大きい文脈のために実装されたreduxを持っているので、私はちょうどそれを使用しています.あなたが本当に必要なのは、マップする配列です.
reduxのために、私がしなければならなかったすべては、私の州を推薦されたユーザ構成要素の柱のように写像することでした:
const mapStateToProps = (state) => {
  return {
    currentUser: state.currentUser.currentUser,
    recommendedUsers: state.currentUser.recommendedUsers,
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    fetchUserRecs: () => dispatch(fetchUserRecs()),
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(RecommendedUsers);
私はFETCH推奨ユーザディスパッチ機能をpropsにマップしたので、このコンポーネントがアプリケーションにマウントされたとき、このデータを取得します.
今はカルーセルのような振る舞いを実際に実行する方法を理解しなければならなかった.いくつかの実験の後、私はすべての推奨されたユーザープロファイルのコンテナーをオーバーフロー隠しプロパティを持っていたDIVであることを決めました、Nowrap Whiteスペースプロパティで.これは、divがそのラインを壊すことができず、水平に続くことを意味しました.次に、どのようなカードが表示されているかについて、何が表示されているかをシフトするために、JSでコンテナのスクロール左マージンを操作できました.これはCSSがカードコンテナdivのように見えたのと同様です.
.cards-container {
    height: 100%;
    overflow: hidden;
    white-space: nowrap;
  }

 .card {
    display: inline-block;
    width: 100%;
    height: 100%;
    padding: 1rem;
  }
次に、コンポーネント自体でローカル変数を定義しなければなりませんでした.私はアクティブなカードの推奨ユーザーの配列のインデックスが何であるかを理解する必要があったので、それは変数です.そして、現在のスクロールマージンを実装するための変数を必要とします.それで、私のコンポーネントの状態は次のようになります.
state = {
    activeIndex: 0,
    margin: 0,
 };
レンダリング関数は以下のようになりました.
 const shownUserId = this.props?.recommendedUsers[this.state.activeIndex]?.id || null;
      return (
        <div className="recommended-users">
          <div className="cards-container">
            {this.props?.recommendedUsers?.map((u, index) => (
              <div>
                <PreviewUserCard
                  user={u}
                  currentUser={this.props.currentUser}
                  key={u.id}
                  cardChange={this.cardChange}
                  shownUserId={shownUserId}
                />
              </div>
            ))}
          </div>
        </div>
      );

基本的には、PreviewUserCardというコンポーネントをマッピングし、推奨される配列内のすべてのユーザの情報をレンダリングしました.PreviewUserCardコンポーネント内で実行できるcardChangeというコールバック関数を渡しました.PreviewUserCardでは、クリックするユーザーがこのコールバックをトリガーするボタンがあります.この関数は、スクロール左マージンを制御し、アクティブなインデックスを変更します.
  cardChange = (e) => {
    if (this.state.activeIndex === this.props.recommendedUsers.length - 1) {
      this.setState({ activeIndex: 0 });
      this.setState({ margin: 0 });
    } else {
      this.setState((state) => ({
        activeIndex: state.activeIndex + 1,
        margin: state.margin + window.innerWidth
      }));

    }
  };

基本的に、この関数は最初に現在のActiveIndexが推奨されたユーザー配列の末尾にあるかどうかをチェックし、アクティブなインデックスを最初のカード- 0にリセットし、マージンを0に設定します.さもなければ、それは配列の次のユーザに1でActiveIndexを増やして、前のマージンに加えてマージンをウインドウ幅にセットします.これは、カードがウィンドウの幅であり、スクロール左マージンを100 %増加させることによって、本質的に次のカードを分割することです.
このパズルの最後の部分は、インクリメンタルにScrollLeft値を設定します.一度にすべてを変えたら、カルーセル効果は全くないだろう.それで、私は、コンポーネントが更新されるたびに実行される関数を書くことに決めました.この重要な関数はsetmarginと呼ばれています.そして、それは本質的により小さなチャンクで現在のscrollleft値を増やして、それに良い流れとスワイプの感覚を与えます.次のようになります.
  setMargin = () => {
    const container = document.querySelector(".cards-container");
    let interval = setInterval(() => {
      let i = container.scrollLeft;
      if (i < this.state.margin) {
        container.scrollLeft = i + window.innerWidth / 100;
        if (container.scrollLeft >= this.state.margin) {
          clearInterval(interval);
        }
      } else {
        container.scrollLeft = i - window.innerWidth / 50;
        if (container.scrollLeft <= this.state.margin) {
          clearInterval(interval);
        }
      }
    }, 1);
  };

まず、カードコンテナ要素を取得し、変数に設定します.次に、そのコンテナーの現在の値を取得する間隔を設定します.それから、この現在のスクロール値がコンポーネント州のマージン値(我々の目標値)未満である間、我々が目標ScrollLeft値を打って、それから間隔をクリアするまで、現在のScrollLeft値を少しずつ増やすことは言います.コンテナの現在のスクロール値が我々の目標値より多いならば、それは我々が我々の配列の終わりに達して、0にリセットしたことを意味します.それから、我々は我々の目標に達するまで、現在のスクロール値を変えることと同様のことをします、しかし、今度は、我々は減少しています(そして、良い影響のためにより速くそれをしています).
そして、それ!成功した場合は、この方法を実装する方法を知っている.おそらくこれを行うには良い方法があり、私はタッチイベントを実装し、スムージングをスムージング(今ではすべての線形であるので、より自然なことができる)が、私はこのメソッドを思い付いて誇りに思っています.それはおそらく反応カルーセル、またはブートストラップのカルーセルのようなライブラリを使用するには、より速くなるだろうが、これは楽しさと楽しい挑戦だった.あなたがカルーセルのようなプレゼンテーションを作成する必要があります他の任意のソリューションをコメントしてください.読書ありがとう!