🌊

ReactでBefore & AfterのUIを実装してみた

に公開

実装したもの


ドリブルから

海外のウェブサイトでスライダーを動かすことでbefore & afterの比較ができるUIを見たので「作ってみたい!」という気持ちになりreactで実装してみることにした。

実装結果はこちら↓
https://codesandbox.io/p/sandbox/tktcd4

コード説明

変数の準備

const container = useRef<HTMLDivElement | null>(null); // イメージの外側のコンテナ
const [sliderPosition, setSliderPosition] = useState(0); // スライダーのポジション。カーソルの位置によって変わる
const [containerWidth, setContainerWidth] = useState(0); // コンテナのwidthを保存・ブラウザの幅が変わった時にも対応したいため

イベントリスナー設定・コンテナの初期値設定


  useEffect(() => {
    const updateWidth = () => {
      if (container.current) {
        setContainerWidth(container.current.offsetWidth);
      }
    };

    updateWidth(); // 初期値設定
    window.addEventListener("resize", updateWidth);

    return () => window.removeEventListener("resize", updateWidth);
  }, []);

マウス移動時に実行される関数

const onMouseMove = (e: React.MouseEvent) => {
    if (!container.current) {
      return;
    }

    const containerLeftSide = e.clientX - container.current.offsetLeft; // paddingとかがあることを考慮
    const containerWidth = container.current.offsetWidth;
    const percentage = (containerLeftSide / containerWidth) * 100;
    setSliderPosition(percentage);
};

レンダー部分

  return (
    <div className="App">
      <div ref={container} className="container" onMouseMove={onMouseMove}>
        <img className="afterImage" src="/assets/rizadon.jpg" />
        <div
          className={"beforeImageBox"}
          style={{ width: `${sliderPosition}%` }}
        >
          <img
            className="beforeImage"
            src="/assets/hitokage.jpg"
            width={containerWidth}
          />
        </div>
        <div className="slider" style={{ left: `${sliderPosition}%` }}></div>
      </div>
    </div>
  );

感想

スライダーの部分をマウスクリック → ドラッグ方式に変えても良さそうだが、今回私はこの方式が気に入ったのでスライダーは自動追従方式にした。

Discussion