M-021 Animation moderate

3D Tilt Scroll Reveal Cards 3Dチルトスクロールカードリビール

Cards pivot upright with tactile 3D perspective transforms upon scrolling into viewport. CSS 3Dパースペクティブとtransform-originを活用した触感豊かなスクロールイン演出。

ライブデモ Live Demo

⚡ Speed

Next-Gen Rendering Engine

Sub-millisecond frame dispatch with zero CPU layout thrashing.

💎 Design

Spatial Depth & Dimension

Hardware-accelerated CSS 3D transforms evoke tactile physical layering.

🔒 Security

Zero-Knowledge Cryptography

End-to-end data encryption secured by mathematical invariants.

🚀 Scale

Planetary Edge CDN

Instantaneous multi-region edge caching with 99.999% uptime guarantees.

概要・用途・特徴Overview, Usage & Features

何ができるかWhat it does

A 3D perspective scroll effect where cards enter leaning backward in depth space and rotate upright as they enter the view.

スクロールに応じて奥側に傾いていたカードが、視界中央に入ると滑らかに起き上がってフラットに着地する3Dスクロールリビール演出です。

どこで使うかWhere to use

Ideal for landing page feature sections, Apple-inspired device showcases, portfolio case studies, and modern marketing sites.

製品機能のプレゼンテーション、モダンなSaaSのトップページ、実績紹介カードなど、視覚的インパクトを与えたいエリアに適しています。

特徴Key features

Hardware-accelerated CSS 3D transforms, customizable perspective focal distance, smooth cubic-bezier easing, prefers-reduced-motion fallback.

GPUアクセラレーションによるCSS 3D変形、パースペクティブ距離の調整、上質なcubic-bezierイージング、prefers-reduced-motion時の静的表示。

調整可能パラメータ Adjustable Parameters

Parameter Default Description
perspective1000px3D perspective focal depth
accent-color#38bdf8Accent highlight for active cards

実装コード Implementation Code

<div class="m021-scroll-viewport">
  <div class="m021-cards-list">
    <div class="m021-card is-flat"><h4>Next-Gen Engine</h4><p>Details...</p></div>
    <div class="m021-card is-tilted"><h4>Spatial Depth</h4><p>Details...</p></div>
  </div>
</div>
.m021-scroll-viewport {
  height: 320px;
  overflow-y: auto;
  padding: 36px 20px 48px;
  perspective: var(--m021-perspective, 1000px);
  perspective-origin: center center;
}

.m021-cards-list {
  display: flex;
  flex-direction: column;
  gap: 20px;
  transform-style: preserve-3d;
}

.m021-card {
  padding: 22px 24px;
  border-radius: 14px;
  background: linear-gradient(135deg, rgba(30, 41, 59, 0.75), rgba(15, 23, 42, 0.85));
  border: 1px solid rgba(148, 163, 184, 0.15);
  transform-origin: center bottom;
  transform-style: preserve-3d;
  transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.5s ease;
}

.m021-card.is-tilted {
  opacity: 0.35;
  transform: rotateX(32deg) translateY(24px) scale(0.92);
}

.m021-card.is-flat {
  opacity: 1;
  transform: rotateX(0deg) translateY(0) scale(1);
  border-color: rgba(56, 189, 248, 0.35);
}
import React, { useRef, useEffect } from 'react';
import './M-021.css';

export default function TiltScrollRevealCards({
  cards = [],
  perspective = 1000,
  accentColor = '#38bdf8'
}) {
  const viewportRef = useRef(null);

  useEffect(() => {
    const vp = viewportRef.current;
    if (!vp) return;

    const onScroll = () => {
      const items = vp.querySelectorAll('.m021-card');
      const vBottom = vp.scrollTop + vp.clientHeight;
      items.forEach(card => {
        if (vBottom - card.offsetTop > 90) {
          card.classList.remove('is-tilted');
          card.classList.add('is-flat');
        } else {
          card.classList.remove('is-flat');
          card.classList.add('is-tilted');
        }
      });
    };

    vp.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => vp.removeEventListener('scroll', onScroll);
  }, []);

  return (
    <div className="m021-stage" style={{ '--m021-perspective': `${perspective}px`, '--m021-card-accent': accentColor }}>
      <div className="m021-scroll-viewport" ref={viewportRef}>
        <div className="m021-cards-list">
          {cards.map((c, i) => (
            <div key={i} className="m021-card is-tilted">
              <h4>{c.title}</h4>
              <p>{c.desc}</p>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}
.m021-stage {
  position: relative;
  width: 100%;
  max-width: 620px;
  border-radius: 16px;
  background: #090d16;
  border: 1px solid rgba(148, 163, 184, 0.2);
  overflow: hidden;
}

.m021-scroll-viewport {
  height: 320px;
  overflow-y: auto;
  padding: 36px 20px 48px;
  perspective: var(--m021-perspective, 1000px);
  perspective-origin: center center;
}

.m021-cards-list {
  display: flex;
  flex-direction: column;
  gap: 20px;
  transform-style: preserve-3d;
}

.m021-card {
  padding: 22px 24px;
  border-radius: 14px;
  background: linear-gradient(135deg, rgba(30, 41, 59, 0.75), rgba(15, 23, 42, 0.85));
  border: 1px solid rgba(148, 163, 184, 0.15);
  transform-origin: center bottom;
  transform-style: preserve-3d;
  transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.5s ease;
}

.m021-card.is-tilted {
  opacity: 0.35;
  transform: rotateX(32deg) translateY(24px) scale(0.92);
}

.m021-card.is-flat {
  opacity: 1;
  transform: rotateX(0deg) translateY(0) scale(1);
}

仕組みとカスタマイズHow It Works & Customization

仕組みHow it works

Assigns perspective to the scroll container and rotateX / scale transforms to each card based on its viewport entry threshold.

親コンテナにperspectiveを設定し、カードの下端を基準点(transform-origin: center bottom)として、スクロール進入時にrotateX(32deg)から0degへ遷移させます。

カスタマイズ方法Customization

Adjust perspective depth with --m021-perspective and accent highlight colors with --m021-card-accent.

CSSカスタムプロパティ(--m021-perspective, --m021-card-accent)で奥行き感の強さやアクセントカラーを自由に調整できます。

注意点Caveats

Ensure preserve-3d is set properly and avoid overflow: hidden on intermediate wrapper elements that would flatten the 3D context.

カードの中間親要素に意図しないoverflowやtransformを付与すると3Dコンテキストが平坦化(flatten)されるため階層構造に注意してください。

よくある質問 Frequently Asked Questions

Can I adjust the angle of rotation? 傾斜の角度(傾き度合い)を変更できますか?

Yes, modify rotateX(32deg) in the .is-tilted CSS selector to any desired degrees such as 15deg or 45deg.

はい、.is-tilted セレクタ内の rotateX(32deg) の数値を変更することで、緩やかな15度やダイナミックな45度など自由に調整できます。

How does it behave under prefers-reduced-motion? prefers-reduced-motion設定ではどのように動作しますか?

The 3D transform is bypassed and replaced with a clean 2D fade-in for motion sensitivity.

3D回転とスケール変化が無効化され、シンプルなフェードインのみでアクセシブルに表示されます。

AIへの指示テンプレート AI Prompt Template

以下をAIに貼り付けると実装を依頼できます。 Paste the following into your AI assistant to request implementation.