本文へスキップ
HELLO!
HIGASHIYUKI®.COM
0   /   100
ヒーロー

ヒーローの背景で色の移る波線がずれながらうねる

デモ

仕様

用途
ヒーロー
動作
DOM
種類
レシピ
動作確認
three 0.186.0・gsap 3.15.0
公開日

しくみと調整

SVG の <path> を t から毎回組み立て直します。ライブラリは使わず、ブラウザの描画のたびに呼ばれる関数で位相を進めるだけで動きます。周波数の違う 2 つの波を重ね、線ごとに位相をわずかにずらすと、束になって揺れながらうねって見えます。

時間の係数(1.5 と 3.2)を整数の比に保つと、ひと巻きで元の形に戻りループがつながります。線の色は、ローズから墨のスレートへ、線ごとに少しずつ移り変えています。色相だけでなく明るさも一緒に移すので、手前と奥の線が重なっても見分けがつきます。

折れ点の数を増やすほど線はなめらかになりますが、増やしすぎると毎フレームの計算が重くなります。線の本数と振れ幅は、置く場所の広さに合わせて調整してください。

つまみは本数・色・振れ幅・折れ点の数です。ヒーローの背景や、セクションの区切りにさりげない揺らぎを添えたいときに向いています。

コード

HTML
<section class="wave-hero">
  <!-- 背景は飾りなので、読み上げからは外す -->
  <svg class="wave-hero__lines" viewBox="0 0 1280 720" preserveAspectRatio="none" aria-hidden="true"></svg>
  <div class="wave-hero__inner">
    <p class="wave-hero__eyebrow">CREATIVE STUDIO</p>
    <h1 class="wave-hero__title">伝えたいことに、<br>動きを添える。</h1>
    <p class="wave-hero__lead">ここに説明文が入ります。</p>
    <a class="wave-hero__button" href="/contact/">相談する</a>
  </div>
</section>

CSS
.wave-hero {
  --bg: #f2f1ed;
  --ink: #262626;
  --line-from: #c26a61; /* 最初の線の色(ローズ) */
  --line-to: #3d5e73; /* 最後の線の色(墨のスレート) */
  --gutter: clamp(24px, 7vw, 96px);
  position: relative;
  display: grid;
  align-items: center;
  min-height: min(90vh, 720px);
  padding: 0 var(--gutter);
  overflow: hidden;
  color: var(--ink);
  background-color: var(--bg);
}

.wave-hero__lines {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

.wave-hero__inner {
  position: relative;
  max-width: 34em;
}

.wave-hero__eyebrow {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.wave-hero__title {
  margin: 24px 0 0;
  font-size: clamp(32px, 8vw, 72px);
  line-height: 1.05;
  letter-spacing: -0.02em;
}

.wave-hero__lead {
  margin: 24px 0 0;
  font-size: 18px;
  line-height: 1.8;
}

.wave-hero__button {
  display: inline-grid;
  place-items: center;
  height: 48px;
  margin-top: 32px;
  padding: 0 32px;
  border-radius: 999px;
  background-color: var(--ink);
  color: var(--bg);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-decoration: none;
}

.wave-hero__button:focus-visible { outline: 2px solid var(--ink); outline-offset: 4px; }

JavaScript
const DURATION = 5.4; // ひと巻きで元の模様に戻るまで(秒)
const LINES = 9;
const POINTS = 80; // 1 本あたりの折れ点。多いほど滑らか
const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches;

// 線ごとに、CSS の --line-from から --line-to へ色を移す
function lineColor(i) {
  return `color-mix(in srgb, var(--line-from), var(--line-to) ${((i / (LINES - 1)) * 100).toFixed(1)}%)`;
}

document.querySelectorAll(".wave-hero__lines").forEach((svg) => {
  const [, , W, H] = svg.getAttribute("viewBox").split(" ").map(Number);
  const paths = Array.from({ length: LINES }, (_, i) => {
    const path = document.createElementNS(svg.namespaceURI, "path");
    path.setAttribute("fill", "none");
    path.style.stroke = lineColor(i);
    path.setAttribute("stroke-width", "2.5");
    path.setAttribute("stroke-linecap", "round");
    svg.append(path);
    return path;
  });

  const draw = (phase) => {
    paths.forEach((path, i) => {
      const base = H * 0.5 + (i - (LINES - 1) / 2) * 18;
      let d = "";
      for (let p = 0; p <= POINTS; p++) {
        const x = (p / POINTS) * W;
        const u = x / W;
        // 周波数の違う 2 つの波を重ねる。時間の係数を整数にするとループがつながる
        const y =
          base +
          Math.sin(u * Math.PI * 2 * 1.5 + phase + i * 0.35) * H * 0.12 +
          Math.sin(u * Math.PI * 2 * 3.2 - phase * 2 + i * 0.6) * H * 0.03;
        d += `${p === 0 ? "M" : "L"}${x.toFixed(1)} ${y.toFixed(1)}`;
      }
      path.setAttribute("d", d);
    });
  };

  if (reduceMotion) {
    draw(0); // 動きを減らす設定では、1 枚だけ描いて止めておく
    return;
  }
  const tick = (ms) => {
    draw(((ms / 1000 / DURATION) * Math.PI * 2) % (Math.PI * 2));
    requestAnimationFrame(tick);
  };
  requestAnimationFrame(tick);
});

インタラクションデザインについて、
お気軽にご相談ください。

ここに並べているのは、Web サイトの中で動く UI のサンプルです。新しく作るサイトに組み込むことも、いま公開中のサイトに、ボタンやヒーロー、スクロールの演出だけを足すこともできます。設計から実装までの進め方はWeb サイト制作、端末ごとの見え方や表示速度の考え方はレスポンシブウェブサイトのページにまとめています。映像として作る動きをお探しの場合はモーショングラフィックスをご覧ください。