ライブデモ Live Demo
下にスクロールすると、要素がふわっと表示されます。
Scroll down to see elements fade in.
Spacer Area
Reward 1
Fade in content as it enters viewport
Spacer Area
Reward 2
Smooth translation and opacity change
Spacer Area
Reward 3
Keep scrolling...
AI向け説明 AI Description
`M-012` は Intersection Observer API を使用して、要素がビューポート(または親コンテナ)に入ったことを検知し、クラスを付与して CSS トランジションを発火させます。パフォーマンスが高く、スクロールイベントリスナーよりも推奨される手法です。
`M-012` utilizes the Intersection Observer API to detect when elements enter the viewport (or a root container), toggling a class to trigger CSS transitions. This approach is more performant than scroll event listeners.
調整可能パラメータ Adjustable Parameters
- --reveal-duration — フェードインにかかる時間Fade-in duration
- --reveal-distance — 出現時の移動距離Vertical travel distance
実装 Implementation
HTML + CSS + JS
<div class="reveal-item">Content</div>
<style>
.reveal-item {
opacity: 0;
transform: translateY(var(--reveal-distance, 40px));
transition: all var(--reveal-duration, 0.8s) cubic-bezier(0.5, 0, 0, 1);
}
.reveal-item.visible {
opacity: 1;
transform: translateY(0);
}
</style>
<!-- Parameters -->
<div class="control-row">
<label for="dur_control">Duration:</label>
<input type="range" id="dur_control" min="0.1" max="2" step="0.1" value="0.8">
<span id="dur_value">0.8s</span>
</div>
<div class="control-row">
<label for="dist_control">Distance:</label>
<input type="range" id="dist_control" min="0" max="100" step="5" value="40">
<span id="dist_value">40px</span>
</div>
<!-- Controls Script -->
<script>
window.addEventListener('vibeui:ready', () => {
const container = document.getElementById('scroll_ctx');
// Duration
const durInput = document.getElementById('dur_control');
const durOutput = document.getElementById('dur_value');
if(durInput) {
durInput.addEventListener('input', (e) => {
const val = e.target.value;
durOutput.textContent = val + 's';
container.style.setProperty('--reveal-duration', val + 's');
});
}
// Distance
const distInput = document.getElementById('dist_control');
const distOutput = document.getElementById('dist_value');
if(distInput) {
distInput.addEventListener('input', (e) => {
const val = e.target.value;
distOutput.textContent = val + 'px';
container.style.setProperty('--reveal-distance', val + 'px');
});
}
});
</script>
<script>
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
}, { threshold: 0.1 }); // rootMargin if needed
document.querySelectorAll('.reveal-item').forEach(el => observer.observe(el));
</script>
React (JSX + CSS)
// react/M-012.jsx
import { useEffect, useRef } from 'react';
import './M-012.css';
export default function ScrollReveal({ children }) {
const ref = useRef(null);
useEffect(() => {
const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
ref.current.classList.add('visible');
}
}, { threshold: 0.1 });
if (ref.current) observer.observe(ref.current);
return () => observer.disconnect();
}, []);
return <div className="reveal-item" ref={ref}>{children}</div>;
}
AIへの指示テンプレート AI Prompt Template
以下のテンプレートをコピーしてAIアシスタントに貼り付けると、このパターンの実装を依頼できます。 Copy the template below and paste it into your AI assistant to request an implementation of this pattern.