<div class="reveal">
Hello, World!
</div>
<div class="reveal">
<div class="cover"></div>
Welcome to the show!
</div>
<div class="reveal">
<div class="cover"></div>
This is a test.
</div>
body,
html {
height: 300%;
}
.reveal {
position: relative;
top: 200px;
width: 50%;
margin: 200px auto;
font-size: 30px;
overflow: hidden;
font-weight: bold;
}
.cover {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: black;
clip-path: inset(0 0% 0 0); /* 初期状態でカバーが全面にあるように */
}
document.addEventListener("DOMContentLoaded", function () {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const cover = entry.target.querySelector(".cover");
const duration = 300; // アニメーションの継続時間 (ミリ秒)
let start = null;
function step(timestamp) {
if (!start) start = timestamp;
const progress = timestamp - start;
const percentage = Math.min(100, (progress / duration) * 100);
cover.style.clipPath = `inset(0 0 0 ${0 + percentage}%)`;
if (progress < duration) {
window.requestAnimationFrame(step);
} else {
observer.unobserve(entry.target); // アニメーション完了後に監視を停止
}
}
window.requestAnimationFrame(step);
}
});
},
{
threshold: 1, // 要素が50%表示された時にトリガー
}
);
const elements = document.querySelectorAll(".reveal");
elements.forEach((element) => observer.observe(element));
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.