timeline (#1301)
This commit is contained in:
+3
-53
@@ -79,10 +79,6 @@
|
||||
/* no filter, no CSS transition — GSAP owns stroke-dashoffset each frame */
|
||||
}
|
||||
|
||||
.timeline-line .comet {
|
||||
fill: #F5F5DC;
|
||||
filter: drop-shadow(0 0 8px rgba(144, 238, 144, 0.7));
|
||||
}
|
||||
.timeline-line .end-marker {
|
||||
fill: #1b1b1b;
|
||||
stroke: rgba(144, 238, 144, 0.35);
|
||||
@@ -276,7 +272,6 @@
|
||||
<path class="track" id="timelineTrack" d=""></path>
|
||||
<path class="progress" id="timelineProgress" d=""></path>
|
||||
<circle class="end-marker" id="timelineEndMarker" r="5" cx="0" cy="0"></circle>
|
||||
<circle class="comet" id="timelineComet" r="6" cx="0" cy="0" style="opacity:0"></circle>
|
||||
</svg>
|
||||
|
||||
<div class="timeline-grid">
|
||||
@@ -598,7 +593,6 @@
|
||||
<script src="/js/main.js?v=3"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/ScrollTrigger.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/lenis@1.1.14/dist/lenis.min.js"></script>
|
||||
|
||||
<!-- Serpentine timeline renderer -->
|
||||
<script>
|
||||
@@ -607,7 +601,6 @@
|
||||
var svg = document.getElementById('timelineLine');
|
||||
var track = document.getElementById('timelineTrack');
|
||||
var progress = document.getElementById('timelineProgress');
|
||||
var comet = document.getElementById('timelineComet');
|
||||
if (!timeline || !svg) return;
|
||||
|
||||
var nodes = Array.prototype.slice.call(timeline.querySelectorAll('.timeline-node'));
|
||||
@@ -688,37 +681,9 @@
|
||||
endMarker.setAttribute('cx', ep.x.toFixed(1));
|
||||
endMarker.setAttribute('cy', ep.y.toFixed(1));
|
||||
}
|
||||
updateComet(pathLength);
|
||||
return { pts: pts, len: pathLength };
|
||||
}
|
||||
|
||||
function updateComet(len) {
|
||||
if (reduceMotion || drawProgress <= 0 || drawProgress >= 1 || !_samples || !_samples.length) {
|
||||
comet.style.opacity = 0;
|
||||
return;
|
||||
}
|
||||
// Binary search then interpolate — smooth position without getPointAtLength()
|
||||
var target = len * drawProgress;
|
||||
var lo = 0, hi = _samples.length - 1;
|
||||
while (lo < hi) {
|
||||
var mid = (lo + hi) >> 1;
|
||||
if (_samples[mid].l < target) lo = mid + 1; else hi = mid;
|
||||
}
|
||||
var cx, cy;
|
||||
if (lo > 0) {
|
||||
var a = _samples[lo - 1], b = _samples[lo];
|
||||
var t = (b.l > a.l) ? (target - a.l) / (b.l - a.l) : 0;
|
||||
cx = (a.x + (b.x - a.x) * t).toFixed(1);
|
||||
cy = (a.y + (b.y - a.y) * t).toFixed(1);
|
||||
} else {
|
||||
cx = _samples[0].x.toFixed(1);
|
||||
cy = _samples[0].y.toFixed(1);
|
||||
}
|
||||
comet.setAttribute('cx', cx);
|
||||
comet.setAttribute('cy', cy);
|
||||
comet.style.opacity = 1;
|
||||
}
|
||||
|
||||
// Find roughly how far along the path a point sits (coarse sampling).
|
||||
var _samples = null;
|
||||
function lengthAtPoint(target, len) {
|
||||
@@ -785,10 +750,8 @@
|
||||
function renderProgress() {
|
||||
drawProgress = state.progress;
|
||||
progress.style.strokeDashoffset = pathLength * (1 - drawProgress);
|
||||
updateComet(pathLength);
|
||||
revealReachedNodes();
|
||||
if (drawProgress >= 1) {
|
||||
comet.style.opacity = 0;
|
||||
nodes.forEach(function (n, index) {
|
||||
nodeRevealed[index] = true;
|
||||
n.classList.add('is-visible');
|
||||
@@ -859,7 +822,7 @@
|
||||
start: 'top 70%',
|
||||
endTrigger: nodes[nodes.length - 1] || timeline,
|
||||
end: 'top 60%',
|
||||
scrub: 0.6,
|
||||
scrub: true,
|
||||
invalidateOnRefresh: true,
|
||||
onUpdate: function (self) {
|
||||
var p = Math.min(1, preRevealProgress + self.progress * (1 - preRevealProgress));
|
||||
@@ -893,21 +856,8 @@
|
||||
hint = null;
|
||||
}
|
||||
|
||||
if (window.Lenis) {
|
||||
var lenis = new Lenis({
|
||||
duration: 0.9,
|
||||
easing: function (t) { return 1 - Math.pow(1 - t, 3); },
|
||||
smoothWheel: true
|
||||
});
|
||||
lenis.on('scroll', function () {
|
||||
hideScrollHint();
|
||||
ScrollTrigger.update();
|
||||
});
|
||||
gsap.ticker.add(function (time) { lenis.raf(time * 1000); });
|
||||
gsap.ticker.lagSmoothing(0);
|
||||
} else {
|
||||
window.addEventListener('scroll', hideScrollHint, { once: true });
|
||||
}
|
||||
if (window.scrollY > 8) hideScrollHint();
|
||||
window.addEventListener('scroll', hideScrollHint, { once: true, passive: true });
|
||||
} else {
|
||||
advanceTo(1, 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user