בפרקים הקודמים למדתם GSAP, ScrollTrigger, Motion ו-Lenis — כלים שמזיזים אלמנטים על המסך. אבל יש עולם שלם של אנימציות שלא מזיז div-ים אלא מצייר אותם: קווים שנחשפים, צורות שמתמופפות, אייקונים שמשתנים, ואפקטים נוזליים שבלתי אפשרי לבנות עם HTML רגיל. זה עולם ה-SVG Animation. SVG (Scalable Vector Graphics) הוא פורמט גרפיקה וקטורית שחי בתוך ה-DOM — מה שאומר שאפשר לגשת לכל קו, עיגול ונתיב עם CSS ו-JavaScript בדיוק כמו שגוששים ל-div. בפרק הזה תלמדו את כל טכניקות אנימציית SVG: מ-path drawing (קווים שמציירים את עצמם) דרך morphing (צורה שמתמופפת לצורה אחרת), SVG filters (אפקטים נוזליים, טשטוש, ו-Liquid Glass), אייקונים מונפשים, ועד שילוב SVG עם GSAP ו-CSS. תצאו מהפרק עם הידע לבקש מ-AI כל אנימציית SVG שראיתם באתר — ולדעת בדיוק איך היא עובדת מתחת למכסה.
בפרקים 4-5 בניתם hero section עם GSAP ו-ScrollTrigger. בפרק 7 הוספתם גלילה חלקה עם Lenis. עכשיו הגיע הזמן להוסיף שכבה ויזואלית חדשה: SVG animations. תוסיפו לוגו שמצייר את עצמו ב-path drawing כחלק מה-hero, אייקונים מונפשים לניווט (hamburger→X), ואפקט gooey רקע שנותן תחושה נוזלית. בפרק 9 תלמדו Lottie ו-Rive — שלוקחים את עולם האנימציה הוקטורית צעד קדימה עם פורמטים ייעודיים.
| מונח (English) | תרגום | הגדרה |
|---|---|---|
| SVG | גרפיקה וקטורית | Scalable Vector Graphics — פורמט תמונה מבוסס XML שמתאר צורות באמצעות נקודות ונתיבים. נראה חד בכל גודל כי הוא מתמטי, לא פיקסלי |
| path | נתיב | אלמנט <path> ב-SVG — מגדיר צורה חופשית באמצעות פקודות d (Move, Line, Curve, Arc). כמעט כל צורה מורכבת ב-SVG היא path |
| stroke-dasharray | מערך מקפים | CSS property שקובע דפוס של קווים ורווחים לקו (stroke). כשהערך שווה לאורך הנתיב — יוצר "קו אחד שלם" שאפשר לגלות בהדרגה |
| stroke-dashoffset | היסט מקפים | CSS property שמזיז את נקודת ההתחלה של ה-dash pattern. שילוב של dasharray + dashoffset הוא הטריק מאחורי path drawing |
| morph | מיתמור / שינוי צורה | אנימציה שמעבירה צורת SVG אחת לצורה אחרת — כל נקודה "נוסעת" למיקום חדש. דורש מספר נקודות תואם או ספרייה שמתאמת |
| filter | מסנן | אלמנט <filter> ב-SVG שמפעיל אפקטים גרפיים: טשטוש (feGaussianBlur), רעש (feTurbulence), שילוב (feComposite). כמו פילטרים של Photoshop — אבל בקוד |
| viewBox | תיבת תצוגה | attribute של <svg> שמגדיר את מערכת הקואורדינטות הפנימית. viewBox="0 0 100 100" אומר: "תוכן ה-SVG מוגדר במרחב 100x100". ה-SVG ימתח/יתכווץ לפי הגודל בדף |
| preserveAspectRatio | שמירת יחס | attribute שקובע איך ה-SVG מתאים את עצמו כשיחס הגודל של viewBox לא תואם את יחס האלמנט. ברירת מחדל: xMidYMid meet (ממורכז, נכנס בפנים) |
| SVGO | אופטימייזר SVG | כלי שמנקה ומקטין קבצי SVG — מסיר metadata, מפשט paths, ומקטין node count. חיוני לביצועים, במיוחד לאנימציות |
| DrawSVGPlugin | פלאגין ציור SVG | פלאגין GSAP (חינם מ-2024) שמאפשר path drawing animation בשורה אחת. מחליף את הטריק הידני של dasharray/dashoffset |
| MotionPathPlugin | פלאגין נתיב תנועה | פלאגין GSAP (חינם) שמזיז אלמנטים לאורך נתיב SVG. אלמנט "נוסע" על קו מעוגל, כוכב, או כל צורה שמגדירים |
| inline SVG | SVG מוטמע | SVG שמוטמע ישירות ב-HTML (לא כ-<img> או background). זו הדרך היחידה שמאפשרת שליטה מלאה ב-CSS וב-JavaScript על כל אלמנט בתוך ה-SVG |
SVG הוא פורמט גרפיקה מיוחד. בניגוד ל-PNG או JPG (שהם רשת של פיקסלים), SVG מתאר צורות באמצעות מתמטיקה — נקודות, קווים, עקומות. זה אומר שלא משנה כמה תגדילו SVG — הוא תמיד ייראה חד. אבל היתרון הגדול באמת לא קשור לחדות. היתרון הוא שכש-SVG מוטמע ישירות ב-HTML (inline SVG), כל אלמנט בתוכו — כל קו, עיגול, נתיב, טקסט — הוא חלק מה-DOM. ואם הוא חלק מה-DOM, אפשר לגשת אליו עם CSS ו-JavaScript. אפשר לשנות את הצבע שלו ב-hover, להפעיל עליו transition, לאנימט אותו עם GSAP — בדיוק כמו כל div אחר.
למה זה משנה ל-Vibe Coder? כי SVG animation מאפשר דברים שבלתי אפשרי לעשות עם HTML ו-CSS רגיל:
כל הדברים האלה מבוססים על עובדה אחת פשוטה: SVG חי ב-DOM. הנה ההבדל הקריטי:
<!-- דרך 1: SVG כתמונה — אי אפשר לאנימט חלקים פנימיים -->
<img src="logo.svg" alt="logo">
<!-- ה-SVG הוא "קופסה שחורה" — אי אפשר לגעת במה שבפנים -->
<!-- דרך 2: inline SVG — שליטה מלאה -->
<svg viewBox="0 0 200 100" xmlns="http://www.w3.org/2000/svg">
<circle class="my-circle" cx="50" cy="50" r="40" fill="#3b82f6"/>
<path class="my-path" d="M 10 80 C 40 10, 65 10, 95 80" stroke="#000" fill="none"/>
</svg>
<!-- עכשיו אפשר: .my-circle { transition: fill 0.3s; } -->
<!-- ואפשר: gsap.to(".my-path", { strokeDashoffset: 0 }); -->
מבנה בסיסי של SVG: כל SVG מתחיל עם אלמנט <svg> שמגדיר את "הבד" — השטח שעליו מציירים. בתוכו יש אלמנטים גרפיים:
<circle> — עיגול (cx, cy, r)<rect> — מלבן (x, y, width, height)<line> — קו ישר (x1, y1, x2, y2)<polyline> / <polygon> — קווים מחוברים / צורה סגורה<path> — נתיב חופשי (d="M... L... C... Z"). זה האלמנט הכי חשוב — כמעט כל צורה מורכבת היא path<text> — טקסט וקטורי (scalable, stylable)<g> — קבוצה (כמו div ל-SVG — מאפשר לאנימט קבוצת אלמנטים ביחד)ה-attribute הכי חשוב הוא viewBox. הוא מגדיר את מערכת הקואורדינטות הפנימית של ה-SVG. למשל, viewBox="0 0 100 100" אומר: "התוכן מוגדר במרחב 100x100 יחידות". אחר כך ה-SVG יתאים את עצמו לכל גודל שתתנו לו בדף — בלי לאבד חדות. זה ה-"Scalable" ב-SVG.
אם תטמיעו SVG כ-<img src="logo.svg"> או כ-background-image: url(logo.svg) — לא תוכלו לאנימט שום דבר בפנים. ה-SVG הוא "קופסה סגורה". לאנימציות SVG חייבים inline SVG — את הקוד של ה-SVG ישירות ב-HTML. אם יש לכם קובץ SVG, פתחו אותו בעורך טקסט, העתיקו את הקוד, והדביקו ב-HTML. או בקשו מ-AI: "תמיר את ה-SVG הזה ל-inline SVG ותוסיף classes לכל path."
<svg viewBox="0 0 200 200" width="200" height="200"><circle cx="100" cy="100" r="80" fill="#3b82f6" class="ball"/></svg>.ball { transition: fill 0.5s, r 0.5s; } .ball:hover { fill: #ef4444; r: 60; }Path drawing הוא כנראה אפקט ה-SVG הכי מפורסם ברשת. ראיתם את זה מיליון פעמים: לוגו שנחשף קו אחרי קו, כאילו יד בלתי נראית מציירת אותו. טקסט שנכתב בפניכם. אייקון שמופיע באנימציית ציור. האפקט הזה נראה מורכב — אבל הטריק מאחוריו פשוט להפליא. הוא מבוסס על שני CSS properties בלבד: stroke-dasharray ו-stroke-dashoffset.
הרעיון: כל path ב-SVG יכול לקבל stroke — קו מתאר. ל-stroke יש דפוס של "מקפים ורווחים" (dashes and gaps), שנשלט על ידי stroke-dasharray. הטריק: אם מגדירים את ה-dash array לאורך הכולל של הנתיב — מקבלים "מקף אחד" שמכסה את כל הנתיב. אחר כך עם stroke-dashoffset מזיזים את המקף הזה "מחוץ למסך" — כך שלא רואים כלום. ואז מאנימטים את ה-offset חזרה ל-0 — והנתיב "נחשף" בהדרגה, כאילו מישהו מצייר אותו.
<!-- HTML: SVG עם path -->
<svg viewBox="0 0 200 200" width="200" height="200">
<path class="draw-me"
d="M 10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80"
stroke="#3b82f6"
stroke-width="3"
fill="none"/>
</svg>
/* CSS: Path Drawing Animation */
.draw-me {
/* שלב 1: dash שמכסה את כל הנתיב */
stroke-dasharray: 300; /* אורך הנתיב (בערך) */
stroke-dashoffset: 300; /* מוסט לגמרי — לא רואים כלום */
/* שלב 2: אנימציה שמחזירה את ה-offset ל-0 */
animation: draw 2s ease-in-out forwards;
}
@keyframes draw {
to {
stroke-dashoffset: 0; /* הנתיב נחשף בהדרגה */
}
}
איך מגלים את אורך הנתיב? ב-JavaScript: document.querySelector('.draw-me').getTotalLength(). זה מחזיר את האורך המדויק בפיקסלים. תריצו את זה ב-console, תקבלו מספר (למשל 287.5), ותשימו אותו ב-dasharray ו-dashoffset. או פשוט שימו מספר גדול מספיק (כמו 1000) — זה עובד כי dash ארוך מהנתיב פשוט "ממשיך" מעבר לקצה.
// JavaScript: חישוב אוטומטי של אורך הנתיב
const path = document.querySelector('.draw-me');
const length = path.getTotalLength();
// הגדרה דינמית
path.style.strokeDasharray = length;
path.style.strokeDashoffset = length;
// אנימציה עם requestAnimationFrame או CSS
// הגישה הדינמית מדויקת יותר — לא צריך לנחש את האורך
| גישה | מתי להשתמש | יתרונות | חסרונות |
|---|---|---|---|
| CSS בלבד | path בודד, אנימציה פשוטה, ללא scroll trigger | אפס JavaScript, ביצועים מעולים, פשוט | צריך לנחש את אורך הנתיב, אין שליטה ב-timing מדויק |
| JavaScript ידני | מספר paths ברצף, חישוב אורך אוטומטי | אורך מדויק, שליטה ברצף | יותר קוד, צריך לנהל timing ידנית |
| GSAP DrawSVGPlugin | logo reveals, line art מורכב, שילוב עם timeline | שורה אחת, stagger מובנה, שילוב עם ScrollTrigger | תלות בספרייה (אבל חינם מ-2024) |
Path drawing עם GSAP — DrawSVGPlugin: הדרך הקלה ביותר. במקום לחשב dasharray/dashoffset ידנית, DrawSVGPlugin עושה את הכל בשורה אחת:
// רישום הפלאגין
gsap.registerPlugin(DrawSVGPlugin);
// ציור path מ-0% ל-100%
gsap.from(".draw-me", {
drawSVG: "0%", // מתחיל מ-0% (לא רואים כלום)
duration: 2,
ease: "power2.inOut"
});
// או: ציור חלקי — מ-0% ל-50% ואז ל-100%
gsap.fromTo(".draw-me",
{ drawSVG: "0% 0%" }, // מתחיל — אין כלום
{ drawSVG: "0% 100%", // מסתיים — הכל גלוי
duration: 2,
ease: "none"
}
);
// logo reveal — מספר paths ב-stagger
gsap.from(".logo path", {
drawSVG: "0%",
duration: 1.5,
stagger: 0.2, // כל path מתחיל 0.2s אחרי הקודם
ease: "power2.inOut"
});
<svg viewBox="0 0 100 100" width="150" height="150"><path class="checkmark" d="M 20 50 L 40 70 L 80 30" stroke="#22c55e" stroke-width="5" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg>stroke-dasharray: 150; stroke-dashoffset: 150; ו-animation של draw 1s ease forwards@keyframes draw { to { stroke-dashoffset: 0; } }Path drawing עובד רק על stroke (קו מתאר). אם ל-path יש fill (מילוי), ה-fill ייראה מהרגע הראשון — וזה ישבור את האפקט. תמיד הגדירו fill="none" על paths שרוצים לצייר. אם צריך fill — הוסיפו אותו אחרי שהציור מסתיים, באנימציה נפרדת: gsap.to(".path", { fill: "#3b82f6", delay: 2 });
Morphing הוא אנימציה שבה צורת SVG אחת "זורמת" לצורה אחרת. עיגול שמתמופף למלבן. אייקון של לב שהופך לכוכב. מפת מדינה שמתמרפת למפת עולם. זה אפקט שמשדר "קסם" — כי בניגוד ל-fade או slide, הצורה עצמה משתנה. זה לא אותו אלמנט שזז, זה אלמנט שהופך למשהו אחר.
הרעיון הבסיסי: כל path ב-SVG מוגדר על ידי attribute d — רצף של פקודות שמתארות נקודות ועקומות. morphing אומר: לקחת את הנקודות של path A ו"להזיז" אותן לנקודות של path B. אם לשני ה-paths יש אותו מספר נקודות ואותו סוג פקודות — אפשר פשוט לאנימט את ה-attribute d ממצב למצב.
הבעיה: ברוב המקרים, שני paths לא חולקים את אותו מספר נקודות. עיגול יכול להיות מוגדר עם 4 נקודות bezier, בעוד כוכב צריך 10 נקודות. אם פשוט מאנימטים את d — התוצאה תהיה משובשת. לכן צריך כלי שיודע "להתאים" את הנקודות בין שני paths שונים.
<!-- morphing פשוט: שני paths עם אותו מספר פקודות -->
<svg viewBox="0 0 200 200" width="200" height="200">
<path class="morph-shape"
d="M 100 10 L 190 190 L 10 190 Z"
fill="#3b82f6">
<!-- משולש -->
</path>
</svg>
<style>
.morph-shape {
transition: d 0.8s ease-in-out;
}
.morph-shape:hover {
/* מעבר למשולש הפוך — אותו מספר נקודות */
d: path("M 100 190 L 190 10 L 10 10 Z");
}
</style>
<!-- שימו לב: CSS d property transition עובד ב-Chrome/Edge/Firefox -->
<!-- אבל רק אם שני ה-paths זהים במבנה (אותן פקודות, אותו מספר) -->
GSAP MorphSVGPlugin — morphing ללא מגבלות: MorphSVGPlugin של GSAP פותר את בעיית "מספר הנקודות". הוא לוקח כל שני paths — בלי קשר למבנה שלהם — ומייצר מעבר חלק. הוא מוסיף נקודות חסרות, מסדר את הכיוון, ומייצר אנימציה שנראית טבעית:
// רישום
gsap.registerPlugin(MorphSVGPlugin);
// morphing בסיסי — משולש למעגל
gsap.to("#triangle", {
morphSVG: "#circle", // יעד ה-morph — path אחר ב-DOM
duration: 1.5,
ease: "power2.inOut"
});
// morphing עם shapeIndex — שליטה בנקודת ההתחלה
gsap.to("#star", {
morphSVG: {
shape: "#heart",
shapeIndex: 2 // משנה מאיפה ה-morph "מתחיל"
}, // נסו ערכים 0-10 ותראו תוצאות שונות
duration: 2,
ease: "elastic.out(1, 0.5)"
});
// morphing ב-timeline — רצף של צורות
const tl = gsap.timeline({ repeat: -1, yoyo: true });
tl.to("#shape", { morphSVG: "#star", duration: 1 })
.to("#shape", { morphSVG: "#heart", duration: 1 })
.to("#shape", { morphSVG: "#circle", duration: 1 });
flubber.js — חלופה חינמית ל-MorphSVGPlugin: אם מסיבה כלשהי אתם לא משתמשים ב-GSAP, flubber.js היא ספרייה קטנה ומעולה למורפינג. היא מייצרת interpolator שמחזיר path חדש לכל שלב באנימציה:
// flubber.js — morphing ללא GSAP
import { interpolate } from 'flubber';
const triangle = "M 100 10 L 190 190 L 10 190 Z";
const circle = "M 100 10 C 155 10 190 45 190 100 ..."; // path של עיגול
const interpolator = interpolate(triangle, circle, { maxSegmentLength: 10 });
// שימוש עם requestAnimationFrame
function animate(progress) {
const path = interpolator(progress); // progress: 0 → 1
document.querySelector('.shape').setAttribute('d', path);
}
// או שילוב עם CSS/WAAPI לשליטה ב-timing
<svg viewBox="0 0 200 200" width="200"><path class="morph" d="M 100 20 C 144 20 180 56 180 100 C 180 144 144 180 100 180 C 56 180 20 144 20 100 C 20 56 56 20 100 20 Z" fill="#8b5cf6"/></svg>.morph { transition: d 0.6s ease-in-out; cursor: pointer; }.morph:hover { d: path("M 100 20 C 100 20 180 20 180 100 C 180 100 180 180 100 180 C 100 180 20 180 20 100 C 20 100 20 20 100 20 Z"); }CSS d property transition עובד — אבל רק אם שני ה-paths משתמשים באותן פקודות SVG path באותו סדר. אם path A הוא M L L Z ו-path B הוא M C C C Z — ה-transition לא יעבוד. בפרויקטים אמיתיים, צורות שונות כמעט תמיד שונות במבנה. לכן לפרויקטים אמיתיים השתמשו ב-GSAP MorphSVGPlugin או flubber.js — הם יודעים לטפל בכל זוג paths.
SVG filters הם מנוע אפקטים שחי בתוך ה-DOM. תחשבו על Photoshop filters — אבל שאפשר להפעיל עליהם אנימציה. כל filter מוגדר בתוך אלמנט <filter> ומכיל רצף של "פרימיטיבים" — פעולות גרפיות שמופעלות אחת אחרי השנייה. הפרימיטיבים הכי שימושיים לאנימציה:
אפקט Gooey — ה-filter הכי פופולרי באנימציית SVG: אפקט gooey ("דביק") גורם לאלמנטים שנוגעים אחד בשני "להתמזג" כמו טיפות מים. הוא מבוסס על שלושה שלבים: (1) טשטוש כל האלמנטים, (2) הגברת הקונטרסט כך שהטשטוש הופך ל"גשר" בין אלמנטים קרובים, (3) הרכבה מחדש. זה נראה כמו קסם — אבל זה 5 שורות SVG:
<!-- Gooey Filter Definition -->
<svg style="position: absolute; width: 0; height: 0;">
<defs>
<filter id="gooey">
<!-- שלב 1: טשטוש -->
<feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur"/>
<!-- שלב 2: הגברת קונטרסט — מה שיוצר את ה"חיבור" בין אלמנטים -->
<feColorMatrix in="blur" mode="matrix"
values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 20 -10" result="gooey"/>
<!-- שלב 3: הרכבה עם המקור -->
<feComposite in="SourceGraphic" in2="gooey" operator="atop"/>
</filter>
</defs>
</svg>
<!-- שימוש: הפעלת הפילטר על container -->
<div class="gooey-container" style="filter: url(#gooey);">
<div class="blob blob-1"></div>
<div class="blob blob-2"></div>
<div class="blob blob-3"></div>
</div>
/* CSS: אנימציית ה-blobs */
.gooey-container {
position: relative;
width: 400px;
height: 400px;
}
.blob {
position: absolute;
width: 80px;
height: 80px;
border-radius: 50%;
background: #3b82f6;
}
.blob-1 { animation: float-1 4s ease-in-out infinite; }
.blob-2 { animation: float-2 5s ease-in-out infinite; left: 120px; }
.blob-3 { animation: float-3 6s ease-in-out infinite; left: 240px; }
@keyframes float-1 {
0%, 100% { transform: translate(0, 0); }
50% { transform: translate(60px, 80px); }
}
@keyframes float-2 {
0%, 100% { transform: translate(0, 50px); }
50% { transform: translate(-40px, -30px); }
}
@keyframes float-3 {
0%, 100% { transform: translate(0, 20px); }
50% { transform: translate(-80px, 60px); }
}
/* כשה-blobs מתקרבים — הם "מתמזגים" בזכות ה-gooey filter */
feTurbulence — רעש אורגני: feTurbulence יוצר טקסטורה של "רעש" — גלים, עשן, ענני עשן. כשמאנימטים את ה-baseFrequency שלו, מקבלים תנועה אורגנית שנראית כמו מים או אש:
<!-- Turbulence Animation -->
<svg viewBox="0 0 400 300" width="400">
<defs>
<filter id="liquid">
<feTurbulence id="turbulence"
type="fractalNoise"
baseFrequency="0.01"
numOctaves="3"
result="noise"/>
<feDisplacementMap
in="SourceGraphic"
in2="noise"
scale="30"
xChannelSelector="R"
yChannelSelector="G"/>
</filter>
</defs>
<text x="200" y="150"
text-anchor="middle"
font-size="60"
font-weight="bold"
fill="#3b82f6"
filter="url(#liquid)">
LIQUID
</text>
</svg>
<script>
// אנימציית ה-turbulence עם GSAP
gsap.to("#turbulence", {
attr: { baseFrequency: "0.03" },
duration: 4,
repeat: -1,
yoyo: true,
ease: "sine.inOut"
});
</script>
Liquid Glass Effect — הטרנד של 2025-2026: אפקט Liquid Glass (שהושק עם iOS 26 וממשיך להתפשט ברשת) משתמש בשילוב של feGaussianBlur + feDisplacementMap + backdrop-filter. הרעיון: אלמנט שקוף-למחצה שמעוות את מה שמאחוריו, כאילו מסתכלים דרך זכוכית נוזלית. ב-SVG, אפשר ליצור את האפקט עם filter מותאם:
<!-- Liquid Glass Effect -->
<svg viewBox="0 0 500 300" width="500">
<defs>
<filter id="glass" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur in="SourceGraphic" stdDeviation="4" result="blur"/>
<feTurbulence type="fractalNoise" baseFrequency="0.015"
numOctaves="2" result="noise"/>
<feDisplacementMap in="blur" in2="noise" scale="15"
xChannelSelector="R" yChannelSelector="G" result="distort"/>
<feGaussianBlur in="distort" stdDeviation="1" result="final"/>
<feComposite in="final" in2="SourceGraphic" operator="over"/>
</filter>
</defs>
<rect x="50" y="50" width="400" height="200" rx="20"
fill="rgba(255,255,255,0.15)"
stroke="rgba(255,255,255,0.3)"
stroke-width="1"
filter="url(#glass)"/>
</svg>
filter: url(#gooey)stdDeviation ל-5 ול-20 וראו איך זה משפיעבנו אפקט "טקסט נוזלי" — טקסט שנראה כאילו הוא עשוי ממים:
<text> — שם האתר שלכם או כל טקסטfeTurbulence + feDisplacementMapbaseFrequency בין 0.01 ל-0.04 (אם CSS — השתמשו ב-seed attribute עם JavaScript)scale של ה-displacement — כך שב-hover האפקט מתגברSVG filters הם כבדים מבחינת חישוב. feGaussianBlur עם stdDeviation גבוה, feTurbulence עם numOctaves גבוה, ו-feDisplacementMap עם scale גדול — כולם דורשים הרבה חישוב לכל frame. כללי אצבע: (1) אל תפעילו filter על אלמנטים גדולים מ-500x500px. (2) הגבילו numOctaves ל-3 מקסימום. (3) אם ה-animation לא חלקה — הקטינו stdDeviation ו-scale. (4) בדקו ב-DevTools → Performance. (5) ב-mobile, שקלו להשבית filters מורכבים לחלוטין.
אייקונים מונפשים הם כנראה ה-SVG animation הכי נפוץ באתרים — והכי שימושי מבחינת UX. כשמשתמש לוחץ על כפתור hamburger והוא "מתמופף" ל-X, זה לא רק יפה — זה מעביר מידע. "התפריט פתוח, לחץ כאן לסגור." כשאייקון play מתמופף ל-pause, המשתמש מבין מיד מה קורה. אנימציות על אייקונים הן micro-interactions — קטנות, מהירות, ומשפרות את ה-UX בצורה משמעותית.
Hamburger → X — הקלאסיקה: כפתור ה-hamburger (שלושה קווים) שמתמופף ל-X כשלוחצים הוא הדוגמה הכי נפוצה. יש כמה גישות, אבל הנפוצה ביותר היא SVG עם שלוש שורות שעוברות transform:
<!-- Hamburger → X (SVG) -->
<button class="menu-toggle" aria-label="תפריט" aria-expanded="false">
<svg viewBox="0 0 100 100" width="40" height="40">
<line class="line line-top"
x1="20" y1="30" x2="80" y2="30"
stroke="currentColor" stroke-width="6" stroke-linecap="round"/>
<line class="line line-middle"
x1="20" y1="50" x2="80" y2="50"
stroke="currentColor" stroke-width="6" stroke-linecap="round"/>
<line class="line line-bottom"
x1="20" y1="70" x2="80" y2="70"
stroke="currentColor" stroke-width="6" stroke-linecap="round"/>
</svg>
</button>
/* CSS: Hamburger → X transition */
.line {
transition: transform 0.3s ease, opacity 0.3s ease;
transform-origin: center;
}
/* כשהתפריט פתוח — class "open" מתווסף ל-button */
.menu-toggle.open .line-top {
transform: rotate(45deg) translate(0, 14.14px);
/* 14.14 = 20 / √2 — כדי שהקו ממורכז */
}
.menu-toggle.open .line-middle {
opacity: 0; /* הקו האמצעי נעלם */
}
.menu-toggle.open .line-bottom {
transform: rotate(-45deg) translate(0, -14.14px);
}
// JavaScript: toggle
document.querySelector('.menu-toggle').addEventListener('click', function() {
this.classList.toggle('open');
const expanded = this.getAttribute('aria-expanded') === 'true';
this.setAttribute('aria-expanded', !expanded);
});
Play → Pause — morphing אייקון: אייקון play (משולש) שמתמופף לאייקון pause (שני פסים). זה morph קלאסי — אבל כי שני paths שונים במבנה, עדיף להשתמש ב-opacity swap עם transform:
<!-- Play ↔ Pause Toggle -->
<button class="play-toggle" aria-label="נגן">
<svg viewBox="0 0 100 100" width="48" height="48">
<!-- Play icon (משולש) -->
<polygon class="icon-play"
points="30,20 30,80 80,50"
fill="currentColor"/>
<!-- Pause icon (שני פסים) -->
<g class="icon-pause" opacity="0">
<rect x="25" y="20" width="16" height="60" rx="3" fill="currentColor"/>
<rect x="59" y="20" width="16" height="60" rx="3" fill="currentColor"/>
</g>
</svg>
</button>
<style>
.icon-play, .icon-pause {
transition: opacity 0.2s ease, transform 0.3s ease;
}
.play-toggle.playing .icon-play {
opacity: 0;
transform: scale(0.5);
}
.play-toggle.playing .icon-pause {
opacity: 1;
transform: scale(1);
}
.icon-pause { transform: scale(0.5); }
</style>
Loading States — אנימציות טעינה מותאמות: במקום loading spinner גנרי, SVG מאפשר ליצור loading animations מותאמות למותג. הנה spinner פשוט עם path drawing:
<!-- Custom Loading Spinner -->
<svg class="spinner" viewBox="0 0 50 50" width="40" height="40">
<circle class="spinner-ring"
cx="25" cy="25" r="20"
fill="none"
stroke="#3b82f6"
stroke-width="3"
stroke-linecap="round"/>
</svg>
<style>
.spinner {
animation: spinner-rotate 1.4s linear infinite;
}
.spinner-ring {
stroke-dasharray: 90, 150; /* dash של 90, gap של 150 */
stroke-dashoffset: 0;
animation: spinner-dash 1.4s ease-in-out infinite;
}
@keyframes spinner-rotate {
to { transform: rotate(360deg); }
}
@keyframes spinner-dash {
0% { stroke-dasharray: 1, 150; stroke-dashoffset: 0; }
50% { stroke-dasharray: 90, 150; stroke-dashoffset: -35; }
100% { stroke-dasharray: 90, 150; stroke-dashoffset: -124; }
}
</style>
<!-- זה בדיוק הספינר של Material Design / Google -->
Lordicon — ספריית אייקונים מונפשים מוכנה: אם אתם לא רוצים לבנות אייקונים מונפשים מאפס, Lordicon מציעה ספרייה של אלפי אייקונים מונפשים מוכנים. הם מבוססים Lottie (שתלמדו בפרק 9), אבל שימושיים כבר עכשיו:
<lord-icon src="..." trigger="hover"></lord-icon>stroke לצבע המותג שלכםstroke-width ל-5 — ראו spinner עבה יותרLine art animation היא ההרחבה הטבעית של path drawing (סעיף 8.2) — אבל במקום path בודד, מדובר באיור שלם שמכיל עשרות ואפילו מאות paths שמציירים את עצמם בזה אחר זה. תחשבו על logo reveal של חברה עם לוגו מורכב, אנימציית "about us" שמציגה איור של צוות, או ציור של מוצר שמתגלה שלב אחרי שלב. האפקט הוא כמו לצפות בציור שנוצר לפניכם — והוא מרשים במיוחד כי הוא נדיר ויקר מבחינת זמן ייצור.
האתגר: באיור מורכב יש הרבה paths, ולכל אחד אורך שונה. אם כל ה-paths יצטיירו באותו duration — paths קצרים ייראו מהירים מדי ו-paths ארוכים ייראו איטיים מדי. הפתרון: לחשב את אורך כל path ולהתאים את ה-duration, או להשתמש ב-DrawSVGPlugin שעושה את זה אוטומטית.
// Line Art Animation — JavaScript ידני
function animateLineArt(svgSelector, totalDuration = 5) {
const paths = document.querySelectorAll(`${svgSelector} path`);
const pathData = [];
let totalLength = 0;
// שלב 1: חישוב אורך כל path
paths.forEach(path => {
const length = path.getTotalLength();
pathData.push({ element: path, length });
totalLength += length;
// הגדרת מצב התחלתי — נסתר
path.style.strokeDasharray = length;
path.style.strokeDashoffset = length;
path.style.fill = 'none';
});
// שלב 2: אנימציה ברצף — כל path מתחיל כשהקודם נגמר
let delay = 0;
pathData.forEach(({ element, length }) => {
// duration פרופורציונלי לאורך — paths ארוכים לוקחים יותר זמן
const duration = (length / totalLength) * totalDuration;
element.style.transition = `stroke-dashoffset ${duration}s ease-in-out ${delay}s`;
// trigger: הגדרת dashoffset ל-0 (מופעל מיד — או ב-scroll/click)
requestAnimationFrame(() => {
element.style.strokeDashoffset = '0';
});
delay += duration; // ה-path הבא מתחיל כשהנוכחי נגמר
});
}
// שימוש:
animateLineArt('.line-art-illustration', 6);
עם GSAP — הרבה יותר פשוט:
// Line Art עם GSAP DrawSVGPlugin
gsap.registerPlugin(DrawSVGPlugin, ScrollTrigger);
// כל ה-paths מציירים את עצמם ב-stagger
gsap.from(".illustration path", {
drawSVG: "0%",
duration: 1,
stagger: 0.15, // כל path מתחיל 0.15s אחרי הקודם
ease: "power2.inOut",
scrollTrigger: {
trigger: ".illustration",
start: "top 70%", // מתחיל כשהאיור נכנס ל-viewport
}
});
// או: line art שצמוד לגלילה — scrub
gsap.from(".hero-illustration path", {
drawSVG: "0%",
stagger: 0.1,
scrollTrigger: {
trigger: ".hero-illustration",
start: "top 80%",
end: "bottom 20%",
scrub: 1, // האיור מצטייר תוך כדי גלילה
}
});
הכנת SVG לאנימציית line art: לא כל SVG מתאים לאנימציית ציור. SVG שמיוצא מ-Illustrator או Figma צריך הכנה:
בנו אנימציית logo reveal מלאה — לוגו שמצייר את עצמו:
animateLineArt מלמעלה, או ב-GSAP DrawSVGPluginGSAP ו-SVG הם שילוב מושלם. GSAP יודע לאנימט כל attribute של SVG — לא רק CSS properties, אלא גם SVG-specific attributes כמו cx, cy, r, d, viewBox, ועוד. בנוסף, GSAP מציע שני פלאגינים ייעודיים ל-SVG שמייצרים אנימציות שאי אפשר לבנות אחרת: DrawSVGPlugin ו-MotionPathPlugin. שניהם חינמיים מאז שWebflow רכשה את GSAP ב-2024.
DrawSVGPlugin — כבר הכרתם בסעיף 8.2: הפלאגין הזה מפשט path drawing לשורה אחת. אבל יש לו עוד יכולות שכדאי להכיר:
gsap.registerPlugin(DrawSVGPlugin);
// 1. ציור מכיוון ספציפי — מהאמצע החוצה
gsap.fromTo(".path",
{ drawSVG: "50% 50%" }, // מתחיל מנקודה אחת באמצע
{ drawSVG: "0% 100%", // נפרש לשני הכיוונים
duration: 2 }
);
// 2. ציור חלקי — רק 60% של הנתיב
gsap.to(".path", {
drawSVG: "20% 80%", // מציג רק מ-20% עד 80%
duration: 1.5
});
// 3. "ציור הפוך" — הנתיב נמחק
gsap.to(".visible-path", {
drawSVG: "100% 100%", // "סוגר" את הנתיב מההתחלה
duration: 1
});
// 4. שילוב עם ScrollTrigger — path שנחשף בגלילה
gsap.from(".scroll-path", {
drawSVG: "0%",
scrollTrigger: {
trigger: ".scroll-section",
start: "top center",
end: "bottom center",
scrub: 1 // הציור צמוד לגלילה
}
});
MotionPathPlugin — תנועה לאורך נתיב: MotionPathPlugin מזיז אלמנט (כל אלמנט — לא רק SVG) לאורך נתיב SVG. הדמיינו: אלמנט שנע בקו מעוגל, בצורת כוכב, או לאורך כל path חופשי שתציירו. זה מושלם לאנימציות של מטוסים, רכבות, כדורים, או כל אובייקט שנע במסלול מעוגל.
gsap.registerPlugin(MotionPathPlugin);
// 1. תנועה לאורך path קיים ב-DOM
gsap.to(".airplane", {
motionPath: {
path: "#flight-path", // path SVG שמגדיר את המסלול
align: "#flight-path", // ממורכז על הנתיב
autoRotate: true, // האלמנט מסתובב בכיוון התנועה
alignOrigin: [0.5, 0.5] // נקודת העיגון — מרכז האלמנט
},
duration: 5,
ease: "power1.inOut"
});
// 2. תנועה לאורך path שמוגדר ב-JavaScript
gsap.to(".ball", {
motionPath: {
path: [
{ x: 0, y: 0 },
{ x: 100, y: -50 },
{ x: 200, y: 20 },
{ x: 300, y: -30 },
{ x: 400, y: 0 }
],
curviness: 1.5 // כמה "עגול" המסלול (0 = ישר, 2 = מאוד עגול)
},
duration: 3,
ease: "none"
});
// 3. motion path + ScrollTrigger — אובייקט שנע עם הגלילה
gsap.to(".scroll-indicator", {
motionPath: {
path: "#scroll-track",
align: "#scroll-track",
autoRotate: 90
},
scrollTrigger: {
trigger: ".content-section",
start: "top top",
end: "bottom bottom",
scrub: 0.5 // האובייקט נע לאורך הנתיב תוך כדי גלילה
}
});
אנימציית SVG attributes עם GSAP: מעבר לפלאגינים, GSAP יכול לאנימט כל SVG attribute ישירות באמצעות attr: {}:
// אנימציית SVG attributes
gsap.to("circle", {
attr: {
cx: 150, // מזיז את מרכז העיגול
cy: 100,
r: 60, // משנה את הרדיוס
fill: "#ef4444" // משנה צבע (דרך attr, לא CSS)
},
duration: 2,
ease: "elastic.out(1, 0.3)"
});
// אנימציית viewBox — "zoom in" על חלק מה-SVG
gsap.to("svg", {
attr: { viewBox: "50 50 100 100" }, // מתקרב לפינה
duration: 2,
ease: "power2.inOut",
scrollTrigger: {
trigger: "svg",
scrub: true
}
});
// שינוי fill עם stagger — כל אלמנט משנה צבע ברצף
gsap.to(".bar", {
attr: { fill: "#22c55e" },
stagger: 0.1,
duration: 0.5,
ease: "power2.out"
});
<path id="orbit" d="M 150 50 A 100 100 0 1 1 149.99 50" fill="none" stroke="#ddd" stroke-width="1"/> (b) עיגול קטן: <circle class="planet" cx="0" cy="0" r="8" fill="#3b82f6"/>gsap.registerPlugin(MotionPathPlugin); gsap.to(".planet", { motionPath: { path: "#orbit", align: "#orbit", alignOrigin: [0.5, 0.5] }, duration: 4, repeat: -1, ease: "none" });| פלאגין | מה עושה | שימושים נפוצים | חינם? |
|---|---|---|---|
| DrawSVGPlugin | path drawing — שליטה באחוזי הנתיב הגלויים | logo reveals, line art, progress indicators, signature drawing | כן (מ-2024) |
| MorphSVGPlugin | morphing בין שני paths — ללא מגבלת מבנה | icon transitions, shape morphing, data viz transitions | כן (מ-2024) |
| MotionPathPlugin | תנועה לאורך path SVG | orbit animations, guided tours, game paths, decorative motion | כן (תמיד היה) |
| attr: {} | אנימציית כל SVG attribute | viewBox zoom, radius changes, position shifts, color changes | כן (GSAP core) |
לא כל אנימציית SVG דורשת JavaScript. הרבה אפקטים מרשימים אפשר להשיג עם CSS בלבד — transitions, @keyframes, ו-hover effects. ב-Vibe Coding, הגישה הנכונה היא: התחילו עם CSS. עברו ל-GSAP רק כשצריך שליטה שאי אפשר לקבל ב-CSS.
מה CSS יכול לעשות עם SVG:
מה CSS לא יכול לעשות עם SVG:
<!-- SVG עם CSS hover effects -->
<svg viewBox="0 0 300 200" width="300" class="icon-set">
<!-- אייקון 1: עיגול שגדל ב-hover -->
<circle class="icon-circle" cx="50" cy="100" r="30"
fill="#3b82f6" cursor="pointer"/>
<!-- אייקון 2: כוכב שמסתובב -->
<polygon class="icon-star" points="150,70 162,98 192,98 168,114 178,142 150,126 122,142 132,114 108,98 138,98"
fill="#f59e0b" cursor="pointer"/>
<!-- אייקון 3: לב שפועם -->
<path class="icon-heart"
d="M250 95 C250 75 270 70 280 80 C290 70 310 75 310 95 C310 120 280 140 280 140 C280 140 250 120 250 95 Z"
fill="#ef4444" cursor="pointer"/>
</svg>
/* CSS: SVG Hover Animations */
/* חשוב! ב-SVG, transform-origin ברירת מחדל הוא 0 0 */
/* חייבים להגדיר אותו מפורשות לכל אלמנט */
.icon-circle {
transition: r 0.3s ease, fill 0.3s ease;
/* r = רדיוס — אפשר לאנימט ב-CSS! */
}
.icon-circle:hover {
r: 40;
fill: #2563eb;
}
.icon-star {
transform-origin: 150px 106px; /* מרכז הכוכב — חייבים px ב-SVG */
transition: transform 0.5s ease;
}
.icon-star:hover {
transform: rotate(72deg) scale(1.2);
/* סיבוב של 72° = 1/5 סיבוב — כי לכוכב 5 קודקודים */
}
.icon-heart {
transform-origin: 280px 105px;
animation: none;
}
.icon-heart:hover {
animation: heartbeat 0.6s ease infinite;
}
@keyframes heartbeat {
0%, 100% { transform: scale(1); }
25% { transform: scale(1.15); }
50% { transform: scale(1); }
75% { transform: scale(1.1); }
}
CSS @keyframes על SVG — pulse, glow, rotate:
/* Pulsing ring */
.pulse-ring {
transform-origin: center;
animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { r: 20; opacity: 1; stroke-width: 2; }
50% { r: 35; opacity: 0.3; stroke-width: 0.5; }
}
/* Glowing element */
.glow-element {
filter: drop-shadow(0 0 3px #3b82f6);
animation: glow 2s ease-in-out infinite alternate;
}
@keyframes glow {
to { filter: drop-shadow(0 0 12px #3b82f6); }
}
/* Rotating cog/gear */
.cog {
transform-origin: center; /* חשוב! */
animation: spin 10s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
/* Dash animation — loading indicator */
.dash-loader {
stroke-dasharray: 40 60; /* dash 40, gap 60 */
animation: dash-move 1.5s linear infinite;
}
@keyframes dash-move {
to { stroke-dashoffset: -200; } /* ה-dashes "זזים" לאורך הנתיב */
}
ב-HTML, transform-origin ברירת המחדל הוא center (50% 50%). ב-SVG, ברירת המחדל היא 0 0 — הפינה השמאלית העליונה של ה-SVG! זה אומר שאם תסובבו אלמנט SVG בלי להגדיר transform-origin — הוא יסתובב סביב הפינה, לא סביב עצמו. תמיד הגדירו transform-origin מפורשות על אלמנטי SVG שמסתובבים או מתכווצים. שימו לב: ב-SVG צריך px (לא אחוזים) עבור תוצאות עקביות cross-browser.
cubic-bezier(0.34, 1.56, 0.64, 1) (overshoot) — ראו הבדלSVG animation יכול להיות חלק כמשי או כבד כמו עופרת — הכל תלוי באיך שמטמיעים אותו, כמה nodes יש ב-SVG, ומה מאנימטים. סעיף זה נותן לכם את הכללים ליצירת SVG animations שרצים ב-60fps גם ב-mobile.
שלוש דרכי הטמעת SVG — ומה כל אחת מאפשרת:
<!-- דרך 1: inline SVG — שליטה מלאה, הכי טוב לאנימציה -->
<svg viewBox="0 0 100 100">
<circle class="animate-me" cx="50" cy="50" r="40"/>
</svg>
<!-- ✅ CSS animation ✅ JavaScript ✅ hover ✅ GSAP ✅ filters -->
<!-- ⚠️ מגדיל את ה-HTML, לא cacheable בנפרד -->
<!-- דרך 2: <img> — cacheable, אבל "קופסה סגורה" -->
<img src="logo.svg" alt="Logo" width="100">
<!-- ✅ cacheable ✅ lazy loading ✅ SMIL animation בתוך ה-SVG -->
<!-- ❌ אי אפשר CSS/JS מבחוץ ❌ אין hover ❌ אין GSAP -->
<!-- דרך 3: <object> — middle ground -->
<object type="image/svg+xml" data="logo.svg"></object>
<!-- ✅ cacheable ✅ CSS/JS בתוך ה-SVG עובדים ✅ SMIL -->
<!-- ❌ מנותק מה-DOM הראשי ❌ לא יכול לגשת מבחוץ -->
| מצב | הדרך הנכונה | למה |
|---|---|---|
| SVG עם אנימציה (path drawing, morph, filter) | inline SVG | חייבים גישה מ-CSS/JS לאלמנטים הפנימיים |
| אייקון סטטי שלא צריך אנימציה | <img> או CSS background | cacheable, לא מנפח את ה-HTML |
| SVG עם SMIL animation עצמית | <img> או <object> | SMIL רצה בפנים, לא צריך גישה מבחוץ |
| איור מורכב (50+ paths) בלי אנימציה | <img> | inline SVG עם מאות nodes מכביד על ה-DOM |
| SVG שמשתנה ב-hover מבחוץ | inline SVG | רק inline מאפשר CSS hover/focus מבחוץ |
SVGO — אופטימיזציה קריטית לפני אנימציה: SVG שמגיע מ-Figma, Illustrator, או Sketch מכיל המון "זבל": metadata, editor data, empty groups, hidden elements, ו-paths עם יותר nodes מהנדרש. SVGO (SVG Optimizer) מנקה את כל זה. SVGOMG הוא ה-GUI המומלץ — גרור SVG, כוונן הגדרות, והורד קובץ נקי.
# SVGO CLI — אופטימיזציה מהטרמינל
npm install -g svgo
# אופטימיזציה בסיסית
svgo input.svg -o output.svg
# אופטימיזציה עם הגדרות מותאמות
svgo input.svg -o output.svg --config='{
"plugins": [
"preset-default",
{ "name": "removeViewBox", "active": false },
{ "name": "removeDimensions", "active": true },
{ "name": "convertPathData", "params": { "floatPrecision": 2 } }
]
}'
# חשוב: אל תסירו viewBox! (removeViewBox: false)
# חשוב: אל תסירו classes ו-IDs אם צריכים אותם לאנימציה
כמה nodes זה יותר מדי? אין מספר קסום, אבל הנה כללי אצבע:
טיפים לביצועים בהנפשת SVG:
transform: translateX(100px) עובר ב-GPU. שינוי cx attribute מכריח layout recalculation<use> לשכפול: במקום לשכפל paths, השתמשו ב-<use href="#my-path"/> — חוסך DOM nodesSVG נגישות היא נושא שרוב המפתחים מתעלמים ממנו — ומחמיצים. SVG שלא מסומן כראוי הוא "בלתי נראה" לקוראי מסך. משתמש עיוור שנכנס לדף רואה — כלום. ב-Vibe Coding, נגישות היא לא "bonus" — היא חלק מהמוצר. הכללים פשוטים, וההטמעה לוקחת דקה אחת.
שני סוגי SVG — שני טיפולים:
<!-- SVG מידעי — נגישות מלאה -->
<svg viewBox="0 0 200 200" role="img" aria-labelledby="logo-title logo-desc">
<title id="logo-title">לוגו חברת Nova</title>
<desc id="logo-desc">כוכב כחול עם שם החברה Nova מתחתיו</desc>
<!-- ... אלמנטי ה-SVG ... -->
</svg>
<!-- קורא מסך: "לוגו חברת Nova: כוכב כחול עם שם החברה Nova מתחתיו" -->
<!-- SVG דקורטיבי — מוסתר מקוראי מסך -->
<svg viewBox="0 0 400 400" aria-hidden="true" role="presentation"
focusable="false">
<!-- אנימציית רקע gooey — לא מעבירה מידע -->
<!-- ... -->
</svg>
<!-- קורא מסך: מתעלם לחלוטין -->
<!-- אייקון בתוך כפתור — ה-button מספק את הנגישות -->
<button aria-label="סגור תפריט">
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
<path d="M6 6L18 18M6 18L18 6" stroke="currentColor" stroke-width="2"/>
</svg>
</button>
<!-- ה-SVG מוסתר כי ה-button עצמו מתאר את הפעולה -->
prefers-reduced-motion — כיבוי אנימציות למשתמשים רגישים: חלק מהמשתמשים סובלים מ-motion sickness — תנועה על המסך גורמת להם סחרחורת. חובה לכבד את ההעדפה שלהם:
/* CSS: כיבוי כל אנימציות SVG למשתמשים רגישים */
@media (prefers-reduced-motion: reduce) {
svg * {
animation: none !important;
transition: none !important;
}
/* אלטרנטיבה רכה: שמירת transitions קצרים */
/* svg * { animation-duration: 0.01ms !important; } */
}
/* JavaScript: בדיקה לפני הפעלת אנימציה */
const prefersReducedMotion =
window.matchMedia("(prefers-reduced-motion: reduce)").matches;
if (!prefersReducedMotion) {
// הפעילו SVG animations
animateLineArt('.illustration', 5);
gsap.from(".logo path", { drawSVG: "0%", stagger: 0.2 });
} else {
// הציגו את ה-SVG במצבו הסופי — בלי אנימציה
gsap.set(".logo path", { drawSVG: "100%" });
}
צ'קליסט נגישות SVG — 6 כללים:
role="img" ל-SVG מידעי. role="presentation" ל-SVG דקורטיבי<title> (כותרת קצרה) ו-<desc> (תיאור מפורט). חברו ל-SVG עם aria-labelledbyaria-hidden="true" — קוראי מסך מתעלמיםfocusable="false" על SVG דקורטיבי — מונע focus ב-IE/Edge ישן<title> ו-<desc> בתוך ה-SVG, ו-role="img" aria-labelledby="..."aria-hidden="true" role="presentation" focusable="false"SVG animation הוא תחום שבו AI באמת מצטיין — כי הוא מבוסס קוד, לא עיצוב. AI יודע לייצר SVG paths, להוסיף CSS animations, ולהטמיע GSAP plugins. אבל כמו תמיד, המפתח הוא הפרומפט. "add SVG animation" ייתן תוצאה גנרית. הפרומפטים הבאים נותנים תוצאות מקצועיות כי הם משתמשים במונחים הנכונים:
פרומפט 1: Logo Reveal עם Path Drawing
/* פרומפט ל-Bolt / Lovable / v0 / Claude */
"Create a logo reveal animation using SVG path drawing:
- The logo should be inline SVG with stroke paths (no fills initially)
- Use stroke-dasharray and stroke-dashoffset for the drawing effect
- Each path draws sequentially with 0.2s stagger between paths
- Total animation duration: 3 seconds
- Easing: power2.inOut (use CSS cubic-bezier(0.77, 0, 0.175, 1))
- After all paths finish drawing, fade in the fill colors over 0.5s
- Add a 0.5s initial delay before animation starts
- Include aria-hidden='true' since it's decorative
- The SVG should be centered on the page with max-width: 300px
Use CSS @keyframes only — no JavaScript required for this animation."
פרומפט 2: Gooey Navigation Menu
/* פרומפט ל-Bolt / Lovable / v0 / Claude */
"Build a navigation menu with a gooey SVG filter effect:
- 5 circular menu items arranged horizontally
- Apply an SVG gooey filter (feGaussianBlur + feColorMatrix with
high alpha contrast, values matrix '1 0 0 0 0 0 1 0 0 0 0 0 1 0 0
0 0 0 18 -7')
- On hover, the hovered item expands slightly and 'merges' visually
with adjacent items through the gooey filter
- Each item has an icon (use simple SVG shapes — circle, star,
triangle, square, pentagon)
- Active item gets a different color
- Include smooth transition: 0.3s ease
- Make it responsive — stack vertically on mobile
- Filter should only apply to the menu container, not the whole page"
פרומפט 3: Animated SVG Icon Set
/* פרומפט ל-Bolt / Lovable / v0 / Claude */
"Create a set of 4 animated SVG icons with hover interactions:
1. Hamburger → X: three horizontal lines that morph to X on click,
using CSS transform (rotate + translate) on each line.
Include aria-expanded toggle.
2. Play → Pause: triangle morphs to two vertical bars. Use opacity
swap with scale transition.
3. Loading spinner: circular SVG path with stroke-dasharray animation,
similar to Material Design spinner (rotating + dash growing/shrinking)
4. Heart with pulse: heart SVG that scales on hover with a heartbeat
@keyframes animation (scale 1 → 1.15 → 1 → 1.1 → 1).
All icons should be 48x48px, use currentColor for theming,
and include proper SVG accessibility (aria-hidden when inside buttons)."
פרומפט 4: Morphing Shape Background
/* פרומפט ל-Bolt / Lovable / v0 / Claude */
"Create an animated SVG background with morphing organic shapes:
- 3 large blob shapes (organic, amoeba-like) using SVG paths
- Each blob slowly morphs between 3 different shapes in an infinite loop
- Use CSS @keyframes with the d property for morphing
(all shapes must have the same number and type of path commands)
- Blobs should have semi-transparent gradient fills (#3b82f6, #8b5cf6,
#ec4899) with mix-blend-mode: multiply
- Animation duration: 8-12 seconds per blob, different for each
to avoid synchronization
- Position: fixed, full viewport, z-index: -1 (behind content)
- Add prefers-reduced-motion: reduce to disable animation
- Performance: use will-change: d on each path"
פרומפט 5: Motion Path Scroll Animation
/* פרומפט ל-Cursor / Claude (דורש GSAP) */
"Build an SVG motion path animation connected to scroll:
- Create a winding road/path SVG that spans the full page height
- A small car/rocket icon follows this path as the user scrolls
- Use GSAP MotionPathPlugin with ScrollTrigger (scrub: 0.5)
- The path should be visible as a dashed line (stroke-dasharray: 10 5)
- The icon should autoRotate to follow the path direction
- As the icon moves, the path behind it changes color (from gray
to blue) using DrawSVGPlugin
- Add 5 'milestone' circles along the path that light up as the icon
passes them
- Include GSAP registerPlugin for MotionPathPlugin, DrawSVGPlugin,
ScrollTrigger
- Make the path responsive with preserveAspectRatio='xMidYMid meet'"
אחרי שלמדתם את כל הטכניקות, הגיע הזמן לראות איך הן מתחברות לפטרנים שלמים — דברים שאתם רואים באתרים מקצועיים כל יום. שלושה פטרנים שכל Vibe Coder צריך להכיר:
פטרן 1: Logo Reveal — חשיפת לוגו
ה-pattern הכי נפוץ: הלוגו של האתר מתגלה באנימציה בטעינת הדף, או כחלק מ-hero section. המבנה הקלאסי: (1) path drawing של קווי המתאר, (2) fade-in של ה-fill, (3) tagline שנכנס. זה מושלם ל-preloader, hero, או about page:
// Logo Reveal Pattern — הקוד המלא
gsap.registerPlugin(DrawSVGPlugin);
const logoReveal = gsap.timeline({
defaults: { ease: "power2.inOut" }
});
// שלב 1: ציור קווי המתאר (1.5 שניות)
logoReveal.from(".logo-svg path", {
drawSVG: "0%",
duration: 1.5,
stagger: 0.15
});
// שלב 2: fade in של ה-fill (0.8 שניות, מתחיל 0.3s לפני שהציור נגמר)
logoReveal.to(".logo-svg path", {
fill: "#3b82f6", // צבע המותג
stroke: "none", // מסתירים את ה-stroke
duration: 0.8,
stagger: 0.05
}, "-=0.3");
// שלב 3: tagline נכנס (0.6 שניות)
logoReveal.from(".tagline", {
opacity: 0,
y: 20,
duration: 0.6
}, "-=0.2");
// שלב 4: כל ה-hero מתייצב
logoReveal.to(".logo-container", {
scale: 0.8, // מתכווץ לגודל הסופי
duration: 0.5,
ease: "power2.out"
}, "+=0.3");
פטרן 2: Data Visualization Animation — גרפים שנבנים
גרפים סטטיים משעממים. גרפים שנבנים בפני המשתמש — מרתקים. הטכניקה: (1) bar chart שבו כל bar "גדל" מ-0 לגובה הסופי, (2) line chart שמצטייר ב-path drawing, (3) pie chart שמתמלא. הנה bar chart מונפש:
<!-- Animated Bar Chart -->
<svg viewBox="0 0 400 300" width="400" role="img"
aria-labelledby="chart-title chart-desc">
<title id="chart-title">מכירות לפי רבעון</title>
<desc id="chart-desc">גרף עמודות: Q1 40%, Q2 65%, Q3 80%, Q4 55%</desc>
<!-- ציר X -->
<line x1="50" y1="250" x2="380" y2="250" stroke="#666" stroke-width="1"/>
<!-- Bars — גובה 0 בהתחלה -->
<rect class="bar" x="70" y="250" width="60" height="0" fill="#3b82f6" rx="4"/>
<rect class="bar" x="150" y="250" width="60" height="0" fill="#3b82f6" rx="4"/>
<rect class="bar" x="230" y="250" width="60" height="0" fill="#3b82f6" rx="4"/>
<rect class="bar" x="310" y="250" width="60" height="0" fill="#3b82f6" rx="4"/>
<!-- Labels -->
<text x="100" y="270" text-anchor="middle" font-size="12">Q1</text>
<text x="180" y="270" text-anchor="middle" font-size="12">Q2</text>
<text x="260" y="270" text-anchor="middle" font-size="12">Q3</text>
<text x="340" y="270" text-anchor="middle" font-size="12">Q4</text>
</svg>
// Bar Chart Animation
const bars = document.querySelectorAll('.bar');
const values = [100, 162, 200, 137]; // גובהים סופיים
gsap.to(bars, {
attr: {
height: (i) => values[i],
y: (i) => 250 - values[i] // זזים למעלה כי SVG y=0 למעלה
},
duration: 1.2,
stagger: 0.15,
ease: "power2.out",
scrollTrigger: {
trigger: "svg",
start: "top 70%"
}
});
פטרן 3: Illustrated Storytelling — איור שמספר סיפור
הפטרן הכי מרשים ו"יקר": איור מלא שמתגלה שלב אחר שלב תוך כדי גלילה. כשגוללים — חלקים שונים של האיור מציירים את עצמם, צבעים נכנסים, ואלמנטים מופיעים. זה שילוב של path drawing + ScrollTrigger + stagger. אתרים כמו Apple, Stripe, ו-Linear משתמשים בטכניקה הזו כדי להציג מוצרים:
// Illustrated Storytelling Pattern
gsap.registerPlugin(DrawSVGPlugin, ScrollTrigger);
// האיור מחולק ל-"שכבות" לפי קבוצות (g elements)
const storyTimeline = gsap.timeline({
scrollTrigger: {
trigger: ".story-illustration",
start: "top 60%",
end: "bottom 20%",
scrub: 1, // צמוד לגלילה
pin: true // האיור "נעוץ" בזמן הציור
}
});
// שכבה 1: קווי מתאר של הרקע
storyTimeline.from(".bg-lines path", {
drawSVG: "0%",
stagger: 0.05,
duration: 1
});
// שכבה 2: צבעי הרקע נכנסים
storyTimeline.to(".bg-fills", {
opacity: 1,
duration: 0.5
});
// שכבה 3: הדמויות מציירות את עצמן
storyTimeline.from(".characters path", {
drawSVG: "0%",
stagger: 0.08,
duration: 1
});
// שכבה 4: צבעי הדמויות + פרטים קטנים
storyTimeline.to(".characters", {
fill: (i) => colors[i], // כל דמות מקבלת צבע
duration: 0.5
});
// שכבה 5: טקסט ו-call to action
storyTimeline.from(".story-text", {
opacity: 0,
y: 30,
duration: 0.5
});
בחרו אחד מ-3 הפטרנים למעלה ובנו אותו מאפס:
דרישות לכולם: נגישות (title/desc או aria-hidden), prefers-reduced-motion, ו-SVGO optimization.
בדקו 3 אתרים שאתם אוהבים וזהו את אנימציות ה-SVG בהם:
<svg> tags<filter>)?| שלב | פעולה | זמן |
|---|---|---|
| 1. תכנון | זהו אילו אלמנטים בדף מתאימים ל-SVG animation: לוגו, אייקונים, איורים, גרפים. סמנו את סוג האנימציה לכל אחד (path drawing, morph, filter, hover) | 10 דקות |
| 2. הכנת SVG | ייצוא מ-Figma/Illustrator → SVGO → בדיקת node count → הוספת classes → הטמעה inline | 15 דקות |
| 3. CSS first | נסו CSS בלבד: transitions, @keyframes, hover effects. אם מספיק — לא צריך JS | 15 דקות |
| 4. GSAP if needed | אם CSS לא מספיק: DrawSVGPlugin, MorphSVGPlugin, MotionPathPlugin, attr:{} | 20 דקות |
| 5. Accessibility | title/desc ל-SVG מידעי, aria-hidden ל-SVG דקורטיבי, prefers-reduced-motion | 5 דקות |
| 6. Test | Chrome + Firefox + Safari. Mobile. Performance tab. קורא מסך (VoiceOver/NVDA) | 10 דקות |
בפרק הזה למדתם SVG animation — גרפיקה וקטורית שחיה ב-DOM ונגישה ל-CSS/JS. הטכניקות שלמדתם (path drawing, morphing, filters) מאפשרות דברים שבלתי אפשרי עם HTML רגיל. בפרק 9 תלמדו Lottie & Rive — שתי טכנולוגיות שלוקחות את עולם האנימציה הוקטורית צעד קדימה. Lottie מייבא אנימציות מ-After Effects לדפדפן בפורמט JSON. Rive מאפשר ליצור אנימציות אינטראקטיביות עם state machine — אנימציות שמגיבות לאירועים, לא רק רצות. שניהם קלים יותר מ-SVG animation ידני — ומאפשרים אנימציות שהיו לוקחות שעות ב-SVG, בדקות.