<div class="description panel">
<div>
<h1>Callbacks</h1>
<ul>
<li><code>onEnter</code> - forward past "start" (typically when <code>trigger</code> is scrolled into view)</li>
<li><code>onLeave</code> - forward past "end" (typically when <code>trigger</code> is scrolled out of view)</li>
<li><code>onEnterBack</code> - backward past "end" (typically when <code>trigger</code> is scrolled back into view)</li>
<li><code>onLeaveBack</code> - backward past "start" (typically when <code>trigger</code> goes backward out of view)</li>
<li><code>onUpdate</code> - every time the scroll position changes while between "start" and "end".</li>
<li><code>onToggle</code> - passes the start or end in either direction</li>
<li><code>onRefreshInit</code> - immediately before measurements are recalculated (typically on resize)</li>
<li><code>onRefresh</code> - after measurements are recalculated (typically on resize)</li>
</ul>
<div class="scroll-down">Scroll down<div class="arrow"></div>
</div>
</div>
</div>
<section class="panel border toggle">
<div class="line-cont">
<span class="line line-1"></span>
</div>
<p>When this panel's top edge reaches 100px from the top of the viewport, the ScrollTrigger will start (<code>start: "top 100px"</code>)<br/>It will end when its bottom is 100px from the bottom of the viewport (<code>end: "bottom bottom-=100px"</code>). Callbacks and progress are logged below:</p>
<div>
<span class="red-progress">progress: 0</span>
<div class="log red-log"></div>
</div>
</section>
<section class="panel">
<p>All callbacks receive one parameter - the <strong>ScrollTrigger instance</strong> itself which has properties like <code>progress</code>, <code>direction</code>, and <code>isActive</code>.</p>
</section>
/*
Demo Styles
*/
.line-cont {
width: 80%;
max-width: 60ch;
padding: 0.5rem 1rem;
border-radius: 10px;
background-color: #2c2c2c;
}
.line {
width: 100%;
height: 8px;
position: relative;
display: block;
background-color: #fffce1;
}
.toggle {
flex-direction: column;
}
.log {
width: 200px;
height: 250px;
padding: 1rem;
border-radius: 8px;
text-align: left;
font-size: 18px;
font-family: fraktion mono;
font-weight: 300;
max-height: 90%;
overflow-y: scroll;
margin-top: 1rem;
background-color: var(--grey)
}
.red-progress {
display: block;
width: 200px;
padding: 1rem;
border-radius: 8px;
text-align: left;
font-size: 18px;
font-family: fraktion mono;
font-weight: 300;
max-height: 90%;
overflow-y: scroll;
margin-top: 1rem;
background-color: var(--grey)
}
.toggle .green-progress {
font-weight: 400;
padding-top: 14px;
display: inline-block;
}
.panel {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
position: relative;
box-sizing: border-box;
padding: 10px;
}
.panel.align-top {
align-items: flex-start;
}
.panel h1 {
margin: 0 auto;
}
.panel.description {
padding-bottom: 60px;
}
.panel p, .panel li {
font-weight: 400;
text-align: left;
line-height: 1.5em;
margin: 0.3em 0 1em 0;
}
.panel li {
margin: 0;
}
h1, h2, p, li {
max-width: 800px;
}
gsap.registerPlugin(ScrollTrigger);
const redLog = document.querySelector(".red-log"),
redProgress = document.querySelector(".red-progress");
function logRed(text) {
redLog.innerHTML += text + "<br>";
}
var animation = gsap.from(".line-1", {
scaleX: 0,
transformOrigin: "left center",
ease: "none"
});
ScrollTrigger.create({
trigger: ".toggle",
start: "top 100px",
end: "bottom bottom-=100px",
markers: {startColor: "#fffce1", endColor: "#fffce1"},
scrub: true,
animation: animation,
onEnter: () => logRed("onEnter"),
onLeave: () => logRed("onLeave"),
onEnterBack: () => logRed("onEnterBack"),
onLeaveBack: () => logRed("onLeaveBack"),
onRefresh: () => logRed("onRefresh"),
onUpdate: self => redProgress.innerText = "progress: " + self.progress.toFixed(3)
});