→ ZAKAI.COM 

ZAKAI LAB
ANIMATION LIBRARY

IDEAS
DESIGN
TECHNOLOGY
PEOPLE

MOTION
FOR A
BRIGHTER WEB

04

Scroll Energy Path

AI flows. Ideas connect.
Scroll
GSAP
Backgrounds
IDEA
DESIGN
MOTION
EXPERIENCE
				
					<script>
    
document.addEventListener("DOMContentLoaded", function () {

    if (
        typeof gsap === "undefined" ||
        typeof ScrollTrigger === "undefined"
    ) return;

    gsap.registerPlugin(ScrollTrigger);

    const section = document.querySelector(".energy-path");
    const path = document.querySelector(".energy-path__progress");
    const points = gsap.utils.toArray(".energy-point");

    if (!section || !path) return;


    /* PATH SETUP */

    const pathLength = path.getTotalLength();

    gsap.set(path, {
        strokeDasharray: pathLength,
        strokeDashoffset: pathLength
    });


    /* DRAW PATH ON SCROLL */

    gsap.to(path, {

        strokeDashoffset: 0,

        ease: "none",

        scrollTrigger: {
            trigger: section,
            start: "top 70%",
            end: "bottom 80%",
            scrub: 1
        }

    });


    /* ACTIVATE POINTS */

    points.forEach(function(point) {

        ScrollTrigger.create({

            trigger: point,
            start: "top 65%",

            onEnter: function() {

                point.classList.add("is-active");

                gsap.fromTo(
                    point.querySelector(".energy-dot"),
                    {
                        scale: .4
                    },
                    {
                        scale: 1,
                        duration: .55,
                        ease: "back.out(2)"
                    }
                );

                gsap.fromTo(
                    point.querySelector(".energy-label"),
                    {
                        opacity: 0,
                        x: 20
                    },
                    {
                        opacity: 1,
                        x: 0,
                        duration: .6,
                        ease: "power2.out"
                    }
                );

            },

            onLeaveBack: function() {
                point.classList.remove("is-active");
            }

        });

    });

});
</script>
				
			
				
					/* =========================================================
   ZAKAI LAB
   Scroll Progress / Scroll Energy Path
========================================================= */


/* =========================================================
   MAIN STAGE
========================================================= */

.energy-path {
    position: relative;

    width: 100%;
    min-height: 1800px;

    overflow: hidden;

    background:
        radial-gradient(
            circle at 50% 45%,
            rgba(229,111,45,.10),
            transparent 38%
        ),
        #0d0d0d;
}


/* =========================================================
   SVG
========================================================= */

.energy-path__svg {
    position: absolute;

    top: 100px;
    left: 50%;

    width: min(800px, 90vw);
    height: 1400px;

    transform: translateX(-50%);

    overflow: visible;
}


/* BASE PATH */

.energy-path__base {
    fill: none;

    stroke: rgba(221,165,50,.14);
    stroke-width: 2;
}


/* ACTIVE PATH */

.energy-path__progress {
    fill: none;

    stroke: #DDA532;
    stroke-width: 3;

    stroke-linecap: round;

    filter:
        drop-shadow(0 0 5px rgba(229,111,45,.8))
        drop-shadow(0 0 14px rgba(221,165,50,.35));
}


/* =========================================================
   POINTS
========================================================= */

.energy-point {
    position: absolute;

    display: flex;
    align-items: center;

    gap: 18px;

    opacity: .25;
}


/* POINT POSITIONS */

.point-1 {
    top: 260px;
    left: 58%;
}

.point-2 {
    top: 610px;
    left: 32%;
}

.point-3 {
    top: 970px;
    left: 58%;
}

.point-4 {
    top: 1320px;
    left: 35%;
}


/* =========================================================
   DOT
========================================================= */

.energy-dot {
    display: block;

    width: 10px;
    height: 10px;

    flex: 0 0 10px;

    border-radius: 50%;

    background: #DDA532;

    transition:
        box-shadow .35s ease,
        opacity .35s ease;
}


/* =========================================================
   LABEL
========================================================= */

.energy-label {
    color: #fff;

    font-family: monospace;
    font-size: 15px;
    font-weight: 400;

    line-height: 1.3;

    letter-spacing: .22em;

    white-space: nowrap;
}


/* =========================================================
   ACTIVE STATE
========================================================= */

.energy-point.is-active {
    opacity: 1;
}

.energy-point.is-active .energy-dot {
    box-shadow:
        0 0 0 7px rgba(221,165,50,.12),
        0 0 18px rgba(229,111,45,.85),
        0 0 38px rgba(221,165,50,.45);
}


/* =========================================================
   TABLET
========================================================= */

@media (max-width: 1024px) {

    .energy-path {
        min-height: 1600px;
    }

    .energy-path__svg {
        top: 80px;

        width: 760px;
        max-width: 94vw;

        height: 1280px;
    }

    .point-1 {
        top: 240px;
        left: 60%;
    }

    .point-2 {
        top: 560px;
        left: 25%;
    }

    .point-3 {
        top: 880px;
        left: 58%;
    }

    .point-4 {
        top: 1200px;
        left: 28%;
    }
}


/* =========================================================
   MOBILE
========================================================= */

@media (max-width: 767px) {

    .energy-path {
        min-height: 1250px;

        background:
            radial-gradient(
                circle at 50% 45%,
                rgba(229,111,45,.09),
                transparent 42%
            ),
            #0d0d0d;
    }


    /* SVG */

    .energy-path__svg {
        top: 60px;
        left: 50%;

        width: 620px;
        max-width: none;

        height: 1080px;

        transform: translateX(-50%);
    }


    /* PATH */

    .energy-path__base {
        stroke-width: 2;
    }

    .energy-path__progress {
        stroke-width: 3;
    }


    /* POINTS */

    .energy-point {
        gap: 10px;
    }

    .point-1 {
        top: 190px;
        left: 57%;
    }

    .point-2 {
        top: 445px;
        left: 12%;
    }

    .point-3 {
        top: 700px;
        left: 56%;
    }

    .point-4 {
        top: 960px;
        left: 14%;
    }


    /* DOT */

    .energy-dot {
        width: 8px;
        height: 8px;

        flex-basis: 8px;
    }


    /* LABEL */

    .energy-label {
        font-size: 11px;

        letter-spacing: .16em;
    }


    /* MOBILE GLOW */

    .energy-point.is-active .energy-dot {
        box-shadow:
            0 0 0 5px rgba(221,165,50,.12),
            0 0 14px rgba(229,111,45,.75),
            0 0 26px rgba(221,165,50,.35);
    }
}


/* =========================================================
   REDUCED MOTION
========================================================= */

@media (prefers-reduced-motion: reduce) {

    .energy-point {
        opacity: 1;
    }

    .energy-point.is-active .energy-dot {
        box-shadow:
            0 0 0 4px rgba(221,165,50,.12);
    }
}
				
			
				
					<section class="energy-path">

    <svg class="energy-path__svg"
         viewBox="0 0 800 1400"
         preserveAspectRatio="xMidYMid meet">

        <path
            class="energy-path__base"
            d="M400 80
               C650 240 180 360 400 520
               C650 690 180 820 400 980
               C620 1120 300 1240 400 1340"
        />

        <path
            class="energy-path__progress"
            d="M400 80
               C650 240 180 360 400 520
               C650 690 180 820 400 980
               C620 1120 300 1240 400 1340"
        />

    </svg>

    <div class="energy-point point-1">
        <span class="energy-dot"></span>
        <span class="energy-label">IDEA</span>
    </div>

    <div class="energy-point point-2">
        <span class="energy-dot"></span>
        <span class="energy-label">DESIGN</span>
    </div>

    <div class="energy-point point-3">
        <span class="energy-dot"></span>
        <span class="energy-label">MOTION</span>
    </div>

    <div class="energy-point point-4">
        <span class="energy-dot"></span>
        <span class="energy-label">EXPERIENCE</span>
    </div>

</section>
				
			

מה אפשר לשנות.. ואיך ⚙️

EXPLORE / LEARN / REUSE / CREATE

.Costomize to fit your vision

				
					ב־CSS משנים את צבע הקו הפעיל:

.energy-path__progress {
stroke: #DDA532;
}

צבע הנקודות:

.energy-dot {
background: #DDA532;
}

לצבע הזוהר משתמשים ב־rgba() שב־filter וב־box-shadow.
				
			
				
					ב־JavaScript חפשי:

scrub: 1

ערך נמוך יותר = תגובה מהירה וצמודה יותר לגלילה.
ערך גבוה יותר = תנועה רכה ואיטית יותר.

לדוגמה:

scrub: 2
				
			
				
					הכיוון נקבע בעיקר לפי מיקום התחנות ב־CSS:

.point-1 { left: 58%; }
.point-2 { left: 32%; }
.point-3 { left: 58%; }
.point-4 { left: 35%; }

אפשר להעביר כל תחנה ימינה או שמאלה באמצעות left.
				
			
				
					גודל המסלול:

.energy-path__svg {
    width: min(800px, 90vw);
    height: 1400px;
}

גודל הנקודות:

.energy-dot {
    width: 10px;
    height: 10px;
}

וגודל הכיתוב:

.energy-label {
    font-size: 15px;
}
				
			
				
					זוהר הקו:

.energy-path__progress {
    filter:
        drop-shadow(0 0 5px rgba(229,111,45,.8))
        drop-shadow(0 0 14px rgba(221,165,50,.35));
}

זוהר הנקודה הפעילה:

.energy-point.is-active .energy-dot {
    box-shadow:
        0 0 0 7px rgba(221,165,50,.12),
        0 0 18px rgba(229,111,45,.85),
        0 0 38px rgba(221,165,50,.45);
}

מספרים גדולים יותר = זוהר רחב וחזק יותר.
				
			
				
					צורת המסלול

זה השינוי המתקדם יותר.

ב־HTML המסלול מוגדר על ידי d של ה־SVG:

<path
    class="energy-path__progress"
    d="M400 80
       C650 240 180 360 400 520
       C650 690 180 820 400 980
       C620 1120 300 1240 400 1340"
/>

שינוי ערכי ה־d משנה את צורת העקומה.

חשוב: יש אצלנו שני <path> זהים, energy-path__base ו־energy-path__progress. כשמשנים את המסלול, צריך להעתיק את אותו d לשניהם, כדי שהקו הכבוי והקו המואר יישבו בדיוק אחד על השני.
				
			

הערה חשובה  🚩  

האנימציה מבוססת GSAP + ScrollTrigger. יש לוודא ששתי הספריות נטענות באתר לפני הקוד.

				
					<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/ScrollTrigger.min.js"></script>
				
			
מתלבט? בוא/י לדבר איתי בווטסאפ?