TEST-web-siteの1のjsコーディング

TEST 1のコーディングです。参考にできます

jsでhamburger.jsの部分

document.addEventListener("DOMContentLoaded", function () {
  // header.jsでボタンが移動されている可能性があるため、少し待ってから取得
  setTimeout(() => {
    const openBtn = document.querySelector(".openbtn");
    const openBtnMv = document.querySelector(".openbtn_mv");
    const gNav = document.getElementById("g-nav");
    const overlay = document.getElementById("overlay");

    if (!gNav || !overlay) {
      return;
    }

    // ========================================
    // 共通処理
    // ========================================

    // メニュー開閉処理
    function toggleMenu(button) {
      if (button) {
        button.classList.toggle("active");
      }
      gNav.classList.toggle("panelactive");
      overlay.classList.toggle("active");
      document.documentElement.classList.toggle("no-scroll");
    }

    // メニュー閉じる処理
    function closeMenu() {
      if (openBtn) openBtn.classList.remove("active");
      if (openBtnMv) openBtnMv.classList.remove("active");
      gNav.classList.remove("panelactive");
      overlay.classList.remove("active");
      document.documentElement.classList.remove("no-scroll");
    }

    // オーバーレイクリックでメニューを閉じる
    overlay.addEventListener("click", closeMenu);

    // ナビゲーション内リンククリックで閉じる
    const navLinks = gNav.querySelectorAll("a");
    navLinks.forEach(function (link) {
      link.addEventListener("click", closeMenu);
    });

    // ========================================
    // openbtn(header内のハンバーガーボタン)の処理
    // ========================================

    if (openBtn) {
      // クリックでメニュー開閉
      openBtn.addEventListener("click", function () {
        toggleMenu(openBtn);
      });
    }

    // ========================================
    // openbtn_mv(MVヘッダー内のハンバーガーボタン)の処理
    // ========================================

    if (openBtnMv) {
      // クリックでメニュー開閉
      openBtnMv.addEventListener("click", function () {
        toggleMenu(openBtnMv);
      });

      // 初期表示設定
      openBtnMv.style.display = "block";

      // スクロール時の表示/非表示制御
      window.addEventListener("scroll", function () {
        const currentScrollY = window.scrollY;

        if (window.innerWidth <= 768) {
          // スクロール位置が5px以上なら非表示、それ以下なら表示
          if (currentScrollY > 5) {
            openBtnMv.style.display = "none";
            // メニューが開いていたら閉じる
            if (openBtnMv.classList.contains("active")) {
              closeMenu();
            }
          } else {
            openBtnMv.style.display = "block";
          }
        }
      });
    }
  }, 10);
});


jsでheader.jsの部分

document.addEventListener("DOMContentLoaded", () => {
  const header = document.getElementById("header");
  const openBtn = document.querySelector(".openbtn");
  let lastScrollY = 0;

  // ハンバーガーボタンをbody直下に移動してスタッキングコンテキストから独立させる
  if (openBtn && window.innerWidth <= 768) {
    document.body.appendChild(openBtn);
    // 初期状態で非表示にする
    openBtn.style.transform = "translateY(-100px)";
    openBtn.style.transition = "transform 0.3s ease-in-out";
  }

  window.addEventListener("scroll", () => {
    const currentScrollY = window.scrollY;

    if (currentScrollY > 100) {
      header.style.transform = "translateY(0)";
      header.style.transition = "transform 0.3s ease-in-out";
      // ハンバーガーボタンも表示
      if (openBtn && window.innerWidth <= 768) {
        openBtn.style.transform = "translateY(0)";
      }
    } else {
      header.style.transform = "translateY(-100%)";
      // ハンバーガーボタンも非表示
      if (openBtn && window.innerWidth <= 768) {
        openBtn.style.transform = "translateY(-100px)";
      }
    }

    lastScrollY = currentScrollY;
  });
});


jsでのmv-anime.jsの部分

document.addEventListener("DOMContentLoaded", () => {
    const images = document.querySelectorAll(".mv_image");
    let currentIndex = 0;

    // 最初の画像に "active" クラスを追加
    if (images.length > 0) {
        images[currentIndex].classList.add("active");
    }

    setInterval(() => {
        // 現在の画像を非表示にする
        images[currentIndex].classList.remove("active");

        // 次の画像を表示する
        currentIndex = (currentIndex + 1) % images.length;
        images[currentIndex].classList.add("active");
    }, 4000); // 4秒ごとに切り替え
});


jsでcard_animationの部分

document.addEventListener("DOMContentLoaded", function () {
  const toggleBtn = document.getElementById("carouselToggle");
  const prevBtn = document.getElementById("prevBtn");
  const nextBtn = document.getElementById("nextBtn");
  const wrapper = document.querySelector(".product_card_wrapper");

  let currentIndex = 0;
  let isAutoPlaying = true;
  let animationStartTime = Date.now();
  let pausedPosition = 0; // 停止時の位置を保存

  // スワイプ用の変数
  let touchStartX = 0;
  let touchEndX = 0;
  let touchStartY = 0;
  let touchEndY = 0;
  let isSwiping = false;

  if (wrapper) {
    // カードを複製して無限ループを作成
    const cards = wrapper.querySelectorAll(".product_card");
    const originalCardCount = cards.length;

    // 元のカードを2回複製(合計3セット)
    for (let i = 0; i < 2; i++) {
      cards.forEach((card) => {
        const clone = card.cloneNode(true);
        wrapper.appendChild(clone);
      });
    }

    // 1枚分の移動距離を計算
    function getCardDistance() {
      const firstCard = wrapper.querySelector(".product_card");
      const cardWidth = firstCard.offsetWidth;
      const gap = parseFloat(window.getComputedStyle(wrapper).gap) || 0;
      return cardWidth + gap;
    }

    // 指定インデックスに移動
    function moveToIndex(index) {
      const distance = getCardDistance();
      wrapper.style.transform = `translateX(-${index * distance}px)`;
      currentIndex = index;
    }

    // 次へ
    if (nextBtn) {
      nextBtn.addEventListener("click", function () {
        // 自動再生を停止して手動モードに
        if (isAutoPlaying) {
          wrapper.classList.add("paused");
          wrapper.classList.add("manual-control");
          toggleBtn.classList.add("paused");
          isAutoPlaying = false;
        }

        currentIndex++;
        // 2セット目の終わり(8枚目)まで行ったら1セット目の最初に戻る
        if (currentIndex >= originalCardCount * 2) {
          // 瞬時に1セット目の同じ位置に移動
          wrapper.style.transition = "none";
          currentIndex = currentIndex - originalCardCount;
          moveToIndex(currentIndex);

          // 次のフレームで通常の遷移を再開
          requestAnimationFrame(() => {
            wrapper.style.transition = "transform 0.5s ease";
            currentIndex++;
            moveToIndex(currentIndex);
          });
        } else {
          wrapper.style.transition = "transform 0.5s ease";
          moveToIndex(currentIndex);
        }
      });
    }

    // 前へ
    if (prevBtn) {
      prevBtn.addEventListener("click", function () {
        // 自動再生を停止して手動モードに
        if (isAutoPlaying) {
          wrapper.classList.add("paused");
          wrapper.classList.add("manual-control");
          toggleBtn.classList.add("paused");
          isAutoPlaying = false;
        }

        currentIndex--;
        // 最初より前に戻ろうとしたら2セット目の最後に移動
        if (currentIndex < 0) {
          wrapper.style.transition = "none";
          currentIndex = originalCardCount * 2 - 1;
          moveToIndex(currentIndex);

          requestAnimationFrame(() => {
            wrapper.style.transition = "transform 0.5s ease";
            currentIndex--;
            moveToIndex(currentIndex);
          });
        } else {
          wrapper.style.transition = "transform 0.5s ease";
          moveToIndex(currentIndex);
        }
      });
    }
  }

  if (toggleBtn && wrapper) {
    toggleBtn.addEventListener("click", function () {
      toggleBtn.classList.toggle("paused");
      isAutoPlaying = !isAutoPlaying;

      // アニメーションを再開する場合
      if (isAutoPlaying) {
        wrapper.classList.remove("paused");
        wrapper.classList.remove("manual-control");

        const distance = getCardDistance();
        const oneSetWidth =
          (distance * wrapper.querySelectorAll(".product_card").length) / 3;
        const animationDuration = 30000;

        // 停止位置からの残り距離を計算
        const remainingDistance = oneSetWidth + pausedPosition; // pausedPositionは負の値
        const remainingProgress = remainingDistance / oneSetWidth;
        const remainingTime = remainingProgress * animationDuration;

        // 停止位置から最初に戻るまでのカスタムアニメーションを作成
        wrapper.style.animation = "none";
        wrapper.style.transform = `translateX(${pausedPosition}px)`;

        requestAnimationFrame(() => {
          wrapper.style.transition = `transform ${remainingTime}ms linear`;
          wrapper.style.transform = `translateX(-${oneSetWidth}px)`;

          // アニメーション終了後、通常のループアニメーションに戻す
          setTimeout(() => {
            wrapper.style.transition = "";
            wrapper.style.transform = "";
            wrapper.style.animation = "";
            animationStartTime = Date.now();
            pausedPosition = 0;
          }, remainingTime);
        });
      } else {
        // 停止時:アニメーションの進行度から現在位置を計算
        wrapper.classList.add("manual-control");

        const distance = getCardDistance();
        const oneSetWidth =
          (distance * wrapper.querySelectorAll(".product_card").length) / 3;
        const animationDuration = 30000;

        // アニメーション開始からの経過時間
        const elapsed = (Date.now() - animationStartTime) % animationDuration;
        const progress = elapsed / animationDuration;

        // 現在の位置を計算
        pausedPosition = -oneSetWidth * progress;

        wrapper.style.animation = "none";
        wrapper.style.transform = `translateX(${pausedPosition}px)`;
        wrapper.style.transition = "none";

        requestAnimationFrame(() => {
          wrapper.classList.add("paused");
        });
      }
    });

    // ホバーで一時停止
    wrapper.addEventListener("mouseenter", function () {
      wrapper.classList.add("paused");
    });

    wrapper.addEventListener("mouseleave", function () {
      if (isAutoPlaying) {
        wrapper.classList.remove("paused");
      }
    });

    // スワイプ機能
    wrapper.addEventListener(
      "touchstart",
      function (e) {
        touchStartX = e.changedTouches[0].screenX;
        touchStartY = e.changedTouches[0].screenY;
        isSwiping = false;
      },
      { passive: true }
    );

    wrapper.addEventListener(
      "touchmove",
      function (e) {
        if (!isSwiping) {
          const diffX = Math.abs(e.changedTouches[0].screenX - touchStartX);
          const diffY = Math.abs(e.changedTouches[0].screenY - touchStartY);

          // 横方向のスワイプが縦方向より大きい場合、画面スクロールを防止
          if (diffX > diffY && diffX > 10) {
            isSwiping = true;
          }
        }

        if (isSwiping) {
          e.preventDefault();
        }
      },
      { passive: false }
    );

    wrapper.addEventListener(
      "touchend",
      function (e) {
        touchEndX = e.changedTouches[0].screenX;
        touchEndY = e.changedTouches[0].screenY;
        handleSwipe();
        isSwiping = false;
      },
      { passive: true }
    );

    function handleSwipe() {
      const diffX = touchStartX - touchEndX;
      const diffY = touchStartY - touchEndY;

      // 横方向のスワイプが縦方向より大きい場合のみ反応
      if (Math.abs(diffX) > Math.abs(diffY) && Math.abs(diffX) > 50) {
        // 自動再生を停止して手動モードに
        if (isAutoPlaying) {
          wrapper.classList.add("paused");
          wrapper.classList.add("manual-control");
          toggleBtn.classList.add("paused");
          isAutoPlaying = false;
        }

        const originalCardCount =
          wrapper.querySelectorAll(".product_card").length / 3;

        if (diffX > 0) {
          // 左にスワイプ = 次へ
          currentIndex++;
          if (currentIndex >= originalCardCount * 2) {
            wrapper.style.transition = "none";
            currentIndex = currentIndex - originalCardCount;
            moveToIndex(currentIndex);

            requestAnimationFrame(() => {
              wrapper.style.transition = "transform 0.5s ease";
              currentIndex++;
              moveToIndex(currentIndex);
            });
          } else {
            wrapper.style.transition = "transform 0.5s ease";
            moveToIndex(currentIndex);
          }
        } else {
          // 右にスワイプ = 前へ
          currentIndex--;
          if (currentIndex < 0) {
            wrapper.style.transition = "none";
            currentIndex = originalCardCount * 2 - 1;
            moveToIndex(currentIndex);

            requestAnimationFrame(() => {
              wrapper.style.transition = "transform 0.5s ease";
              currentIndex--;
              moveToIndex(currentIndex);
            });
          } else {
            wrapper.style.transition = "transform 0.5s ease";
            moveToIndex(currentIndex);
          }
        }
      }
    }

    function moveToIndex(index) {
      const distance = getCardDistance();
      wrapper.style.transform = `translateX(-${index * distance}px)`;
      currentIndex = index;
    }

    function getCardDistance() {
      const firstCard = wrapper.querySelector(".product_card");
      const cardWidth = firstCard.offsetWidth;
      const gap = parseFloat(window.getComputedStyle(wrapper).gap) || 0;
      return cardWidth + gap;
    }
  }
});


jsでscroll-text-animation.jsの部分

// タイトル → 一文字ずつテキスト → 画像の順でフェードインするアニメーション
document.addEventListener("DOMContentLoaded", function () {
  const aboutSection = document.querySelector(".about_shop");
  const titleElement = document.querySelector(".about_shop_title");
  const textElement = document.querySelector(".about_shop_text");
  const imageWrapper = document.querySelector(".about_shop_image_wrapper");

  if (!aboutSection || !titleElement || !textElement || !imageWrapper) return;

  // 初期状態を非表示に設定
  titleElement.style.opacity = "0";
  titleElement.style.transform = "translateY(20px)";
  titleElement.style.transition = "opacity 0.6s ease, transform 0.6s ease";

  imageWrapper.style.opacity = "0";
  imageWrapper.style.transform = "translateY(20px)";
  imageWrapper.style.transition = "opacity 0.6s ease, transform 0.6s ease";

  // 元のテキストを取得してspan要素に分割
  const originalText = textElement.innerText;
  textElement.innerHTML = ""; // 一度クリア

  // テキストを1文字ずつspanで囲む(改行は保持)
  const lines = originalText.split("\n");
  lines.forEach((line, lineIndex) => {
    const chars = line.split("");
    chars.forEach((char) => {
      const span = document.createElement("span");
      span.textContent = char;
      span.classList.add("char");
      span.style.opacity = "0";
      span.style.transform = "translateY(20px)";
      span.style.transition = "opacity 0.2s ease, transform 0.2s ease";
      textElement.appendChild(span);
    });
    // 改行を追加(最後の行以外)
    if (lineIndex < lines.length - 1) {
      textElement.appendChild(document.createElement("br"));
    }
  });

  const chars = textElement.querySelectorAll(".char");
  let animationTriggered = false;

  // スクロールでセクションが表示されたらアニメーション開始
  function checkAndAnimate() {
    if (animationTriggered) return;

    const rect = aboutSection.getBoundingClientRect();
    const windowHeight = window.innerHeight;

    // セクションが画面内に入ったら
    if (rect.top <= windowHeight * 0.8 && rect.bottom >= 0) {
      animationTriggered = true;

      // 1. タイトルをフェードイン
      titleElement.style.opacity = "1";
      titleElement.style.transform = "translateY(0)";

      // 2. タイトル表示後、1文字ずつテキストをフェードイン
      const titleDelay = 600; // タイトルのアニメーション時間
      chars.forEach((char, index) => {
        setTimeout(() => {
          char.style.opacity = "1";
          char.style.transform = "translateY(0)";
        }, titleDelay + index * 50); // タイトル後、50msごとに次の文字を表示
      });

      // 3. 一文字開始から2秒後に画像をフェードイン
      setTimeout(() => {
        imageWrapper.style.opacity = "1";
        imageWrapper.style.transform = "translateY(0)";
      }, titleDelay + 2000); // タイトル後 + 2秒

      // アニメーション開始後はイベントリスナーを削除
      window.removeEventListener("scroll", checkAndAnimate);
    }
  }

  // スクロールイベント
  window.addEventListener("scroll", checkAndAnimate);
  // 初回チェック
  checkAndAnimate();
});


jsのtable_scroll.jsの部分まで

// テーブルのドラッグスクロール機能
document.addEventListener("DOMContentLoaded", function () {
  const scrollContainer = document.querySelector(".table-scroll");

  if (!scrollContainer) return;

  let isDown = false;
  let startX;
  let scrollLeft;

  // マウスカーソルをグラブ(手のひら)に変更
  scrollContainer.style.cursor = "grab";

  scrollContainer.addEventListener("mousedown", (e) => {
    isDown = true;
    scrollContainer.style.cursor = "grabbing";
    startX = e.pageX - scrollContainer.offsetLeft;
    scrollLeft = scrollContainer.scrollLeft;
  });

  scrollContainer.addEventListener("mouseleave", () => {
    isDown = false;
    scrollContainer.style.cursor = "grab";
  });

  scrollContainer.addEventListener("mouseup", () => {
    isDown = false;
    scrollContainer.style.cursor = "grab";
  });

  scrollContainer.addEventListener("mousemove", (e) => {
    if (!isDown) return;
    e.preventDefault();
    const x = e.pageX - scrollContainer.offsetLeft;
    const walk = (x - startX) * 2; // スクロール速度(数値を大きくすると速くなる)
    scrollContainer.scrollLeft = scrollLeft - walk;
  });
});


サイトは

こちらから