codepens/jumping-gooey-navigation/dist/script.js

63 lines
1.5 KiB
JavaScript

console.clear();
gsap.registerPlugin(MotionPathPlugin);
let targets = gsap.utils.toArray("#icons g");
let dotCenters = [50, 150, 250, 350, 450, 550];
let yCenter = 112;
let maxTravel = 500;
let minTravel = 100;
let mapper = gsap.utils.mapRange(minTravel, maxTravel, 0.5, 1);
let anim;
let activeDot = 0;
let targetDot;
let maxDur = 1;
let maxArc = 150;
let staggers = [0.2, 0.16, 0.135, 0.12, 0.11];
targets.forEach((obj, i) => {
obj.index = i;
obj.addEventListener("click", letsGoo);
});
function letsGoo() {
targetDot = this.index;
if (targetDot != activeDot) {
if (anim && anim.isActive()) {
anim.progress(1);
}
let oldX = dotCenters[activeDot];
let newX = dotCenters[targetDot];
let travel = Math.abs(oldX - newX);
let factor = mapper(travel);
let newArc = yCenter - maxArc * factor;
let dur = maxDur * factor;
let newStagger = staggers[travel / 100 - 1];
let newPath = `M${oldX},${yCenter} Q${
travel / 2 + Math.min(oldX, newX)
},${newArc} ${newX},${yCenter}`;
gsap.set("#main", { attr: { d: newPath } });
anim = gsap
.timeline()
.to(".jumper", {
motionPath: {
path: "#main",
align: "#main",
alignOrigin: [0.5, 0.5]
},
stagger: newStagger,
duration: dur,
ease: "sine.inOut"
})
.to(
".jumper",
{ duration: dur / 2, attr: { rx: 40, ry: 40 }, yoyo: true, repeat: 1 },
0
);
} else {
return;
}
activeDot = targetDot;
}