לאחרונה יצרתי דפוס קיר לבנים כחלק מהעבודה שלי #PetitePatterns סדרה, אתגר שבו אני יוצר דפוסים או מרקמים בעלי מראה אורגני ב-SVG בתוך 560 בתים (או בערך בגודל של שני ציוצים). כדי להתאים לאילוץ הזה, עברתי מסע שלימד אותי כמה דרכים קיצוניות לאופטימיזציה של דפוסי SVG כך שיכילו כמה שפחות קוד מבלי להשפיע על איכות התמונה הכוללת.
אני רוצה להדריך אותך בתהליך ולהראות לך איך אנחנו יכולים לקחת דפוס SVG שמתחיל ב-197 בתים עד ל-44 בתים בלבד - הפחתה עצומה של 77.7%!
דפוס ה-SVG
זה מה שנקרא דפוס לבנים "ריצת קשר". זוהי תבנית הלבנים הנפוצה ביותר בחוץ, ואחת שבוודאי ראית בעבר: כל שורת לבנים מקוזזת בחצי אורך של לבנה, ויוצרת תבנית מדורגת שחוזרת על עצמה. הסידור די פשוט, מה שהופך את ה-SVG <pattern>
אלמנט בהתאמה מושלמת לשחזר אותו בקוד.
ה-SVG <pattern>
אלמנט משתמש באובייקט גרפי מוגדר מראש שניתן לשכפל (או "לרצף") במרווחים קבועים לאורך הצירים האופקיים והאנכיים. בעיקרו של דבר, אנו מגדירים תבנית אריחים מלבנית וזה חוזר על עצמו כדי לצבוע את אזור המילוי.
ראשית, בואו נגדיר את מידות הלבנה ואת הפער בין כל לבנה. למען הפשטות, בואו נשתמש במספרים נקיים ועגולים: רוחב של 100
וגובה של 30
עבור הלבנה, ו 10
עבור הפערים האופקיים והאנכיים ביניהם.
לאחר מכן, עלינו לזהות את אריח ה"בסיס" שלנו. וב"אריחים" אני מדבר על אריחי דפוס ולא אריחים פיזיים, לא להתבלבל עם הלבנים. בואו נשתמש בחלק המודגש של התמונה למעלה בתור אריח הדפוס שלנו: שתי לבנים שלמות בשורה הראשונה, ואחד שלם דחוס בין שתי חצאי לבנים בשורה השנייה. שים לב כיצד והיכן נכללים הפערים, מכיוון שהם צריכים להיכלל באריח הדפוס החוזר.
כשמשתמש <pattern>
, עלינו להגדיר את הדפוס width
ו height
, התואמים את הרוחב והגובה של אריח הבסיס. כדי לקבל את הממדים, אנחנו צריכים קצת מתמטיקה:
Tile Width = 2(Brick Width) + 2(Gap) = 2(100) + 2(10) = 220
Tile Height = 2(Bright Height) + 2(Gap) = 2(30) + 2(10) = 80
בסדר, אז אריח הדפוס שלנו הוא 220✕80
. אנחנו גם צריכים להגדיר את patternUnits
תכונה, שבו הערך userSpaceOnUse
פירושו בעצם פיקסלים. לבסוף, הוספת an id
לתבנית נחוצה כדי שניתן יהיה להתייחס אליה כאשר אנו מציירים איתה אלמנט אחר.
<pattern id="p" width="220" height="80" patternUnits="userSpaceOnUse"> <!-- pattern content here -->
</pattern>
כעת, לאחר שקבענו את מימדי האריח, האתגר הוא ליצור את הקוד עבור האריח באופן שיציג את הגרפיקה עם מספר הבתים הקטן ביותר האפשרי. זה מה שאנחנו מקווים להגיע אליו בסוף:
סימון ראשוני (197 בתים)
הגישה הפשוטה וההצהרתית ביותר לשחזר את התבנית הזו שעולה במוחי היא לצייר חמישה מלבנים. כברירת מחדל, ה fill
של אלמנט SVG הוא שחור וה- stroke
הוא שקוף. זה עובד היטב עבור אופטימיזציה של דפוסי SVG, מכיוון שאנחנו לא צריכים להכריז במפורש על אלה בקוד.
כל שורה בקוד למטה מגדירה מלבן. ה width
ו height
תמיד מוגדרים, וה x
ו y
מיקומים מוגדרים רק אם מלבן מוסט מה 0
עמדה.
<rect width="100" height="30"/>
<rect x="110" width="100" height="30"/>
<rect y="40" width="45" height="30"/>
<rect x="55" y="40" width="100" height="30"/>
<rect x="165" y="40" width="55" height="30"/>
השורה העליונה של האריח הכילה שתי לבנים ברוחב מלא, הלבנה השנייה ממוקמת ל x="110"
מאפשר 10
פיקסלים של פער לפני הלבנה. באופן דומה יש 10
פיקסלים של פער לאחר, כי הלבנה מסתיימת ב 210
פיקסלים (110 + 100 = 210
) על הציר האופקי למרות שה <pattern>
רוחב הוא 220
פיקסלים. אנחנו צריכים את המעט הזה של שטח נוסף; אחרת הלבנה השנייה תתמזג עם הלבנה הראשונה באריח הסמוך.
הלבנים בשורה השנייה (התחתונה) מקוזזים כך שהשורה מכילה שני חצאי לבנים ולבן אחת שלמה. במקרה זה, אנו רוצים שהלבנים ברוחב חצי יתמזגו כך שלא יהיה פער בהתחלה או בסוף, מה שיאפשר להן לזרום בצורה חלקה עם הלבנים באריחי דפוס צמודים. בעת קיזוז לבנים אלו, עלינו לכלול גם חצאי פערים, ובכך את x
הערכים הם 55
ו 165
, בהתאמה.
שימוש חוזר ברכיב, (-43B, 154B סך הכל)
זה נראה לא יעיל להגדיר כל לבנה בצורה כה מפורשת. האם אין דרך לייעל דפוסי SVG על ידי שימוש חוזר בצורות במקום זאת?
אני לא חושב שזה ידוע ל-SVG יש <use>
אֵלֵמֶנט. אתה יכול להפנות לרכיב אחר איתו ולעבד את הרכיב המורכב הזה בכל מקום <use>
משמש. זה חוסך לא מעט בתים כי אנחנו יכולים להשמיט את ציון הרוחב והגבהים של כל לבנה, למעט הראשון.
עם זאת, <use>
מגיע עם מחיר קטן. כלומר, עלינו להוסיף an id
עבור האלמנט שאנו רוצים לעשות בו שימוש חוזר.
<rect id="b" width="100" height="30"/>
<use href="#b" x="110"/>
<use href="#b" x="-55" y="40"/>
<use href="#b" x="55" y="40"/>
<use href="#b" x="165" y="40"/>
הקצר ביותר id
אפשרי הוא תו אחד, אז בחרתי "ב" ללבנה. ה <use>
ניתן למקם את האלמנט באופן דומה ל <rect>
עם x
ו y
תכונות כקיזוז. מכיוון שכל לבנה היא ברוחב מלא עכשיו שעברנו <use>
(זכור, חצנו במפורש את הלבנים בשורה השנייה של אריח הדפוס), עלינו להשתמש בנגטיב x
ערך בשורה השנייה, ולאחר מכן ודא שהלבנה האחרונה עולה על גדותיה מהאריח לחיבור חלק זה בין לבנים. עם זאת, אלה בסדר, מכיוון שכל דבר שנופל מחוץ לאריח הדפוס מנותק אוטומטית.
האם אתה יכול לזהות כמה מחרוזות חוזרות שניתן לכתוב בצורה יעילה יותר? בואו נעבוד על אלה הבאים.
כתיבה מחדש לנתיב (-54B, סך הכל 100B)
<path>
הוא כנראה האלמנט החזק ביותר ב-SVG. אתה יכול לצייר כמעט כל צורה עם "פקודות" בתוכה d
תְכוּנָה. יש 20 פקודות זמינות, אבל אנחנו צריכים רק את הפשוטות ביותר עבור מלבנים.
כאן נחתתי עם זה:
<path d="M0 0h100v30h-100z M110 0h100v30h-100 M0 40h45v30h-45z M55 40h100v30h-100z M165 40h55v30h-55z"/>
אני יודע, מספרים ואותיות מוזרים במיוחד! לכולם יש משמעות, כמובן. הנה מה שקורה במקרה הספציפי הזה:
M{x} {y}
: עובר לנקודה המבוססת על קואורדינטות.z
: סוגר את הקטע הנוכחי.h{x}
: מצייר קו אופקי מהנקודה הנוכחית, באורך שלx
בכיוון המוגדר על ידי הסימן שלx
. אותיות קטנותx
מציין קואורדינטה יחסית.v{y}
: מצייר קו אנכי מהנקודה הנוכחית, באורך שלy
בכיוון המוגדר על ידי הסימן שלy
. אותיות קטנותy
מציין קואורדינטה יחסית.
הסימון הזה הוא הרבה יותר מתומצת מהקודם (מעברי שורות ורווחי הזחה נועדו רק לקריאה). והי, הצלחנו לחתוך חצי מהגודל הראשוני, והגענו ל-100 בתים. ובכל זאת, משהו גורם לי להרגיש שזה יכול להיות קטן יותר...
עדכון אריח (-38B, 62B סך הכל)
האם לאריח הדפוס שלנו יש חלקים חוזרים? ברור שבשורה הראשונה חוזרת לבנה שלמה, אבל מה עם השורה השנייה? זה קצת יותר קשה לראות, אבל אם נחתוך את הלבנה האמצעית לשניים זה הופך להיות ברור.
ובכן, הלבנה האמצעית לא בדיוק נחתכת לשניים. יש קיזוז קל כי אנחנו צריכים לקחת בחשבון גם את הפער. בכל מקרה, הרגע מצאנו דפוס אריחי בסיס פשוט יותר, כלומר פחות בתים! זה גם אומר שעלינו לצמצם את החצי width
שלנו <pattern>
אלמנט מ-220 עד 110.
<pattern id="p" width="110" height="80" patternUnits="userSpaceOnUse"> <!-- pattern content here -->
</pattern>
עכשיו בואו נראה איך מציירים את האריח הפשוט <path>
:
<path d="M0 0h100v30h-100z M0 40h45v30h-45z M55 40h55v30h-55z"/>
הגודל מצטמצם ל-62 בתים, שזה כבר פחות משליש מהגודל המקורי! אבל למה לעצור כאן כשיש עוד יותר שאנחנו יכולים לעשות!
פקודות קיצור נתיב (-9B, 53B סך הכל)
שווה להיכנס קצת יותר לעומק <path>
אלמנט מכיוון שהוא מספק יותר רמזים לאופטימיזציה של דפוסי SVG. תפיסה מוטעית אחת שהייתה לי כשעבדתי איתה <path>
הוא לגבי איך fill
תכונה עובדת. לאחר ששיחקתי הרבה עם MS Paint בילדותי, למדתי שכל צורה שאני רוצה למלא בצבע אחיד חייבת להיות סגורה, כלומר אין לה נקודות פתוחות. אחרת, הצבע ידלוף מהצורה וישפך על הכל.
ב-SVG, לעומת זאת, זה לא נכון. תן לי לצטט המפרט עצמה:
פעולת המילוי ממלאת תת-נתיבים פתוחים על-ידי ביצוע פעולת המילוי כאילו נוספה לנתיב פקודת "סגור" נוספת כדי לחבר את הנקודה האחרונה של תת-הנתיב עם הנקודה הראשונה של תת-הנתיב.
זה אומר שאנחנו יכולים להשמיט את פקודות הנתיב הסגור (z
), מכיוון שנתיבי המשנה נחשבים לסגורים אוטומטית כאשר הם מלאים.
דבר שימושי נוסף שכדאי לדעת על פקודות נתיב הוא שהן מגיעות באותיות גדולות וקטנות. אותיות קטנות אומרות שמשתמשים בקואורדינטות יחסיות; אותיות רישיות אומרות במקום זאת קואורדינטות מוחלטות.
זה קצת יותר מסובך מזה עם H
ו V
פקודות כי הן כוללות רק קואורדינטה אחת. כך הייתי מתאר את שתי הפקודות הללו:
H{x}
: מצייר קו אופקי מהנקודה הנוכחית כדי לתאםx
.V{y}
: מצייר קו אנכי מהנקודה הנוכחית כדי לתאםy
.
כאשר אנו מציירים את הלבנה הראשונה באריח הדפוס, אנו מתחילים מה- (0,0)
קואורדינטות. לאחר מכן אנו מציירים קו אופקי ל (100,0)
וקו אנכי ל (100,30)
, ולבסוף, צייר קו אופקי ל (0,30)
. השתמשנו ב h-100
הפקודה בשורה האחרונה, אבל היא המקבילה ל H0
, שזה שני בתים במקום חמישה. אנחנו יכולים להחליף שתי התרחשויות דומות ולחתוך את הקוד שלנו <path>
עד זה:
<path d="M0 0h100v30H0 M0 40h45v30H0 M55 40h55v30H55"/>
עוד 9 בתים מגולחים - כמה קטן יותר אנחנו יכולים ללכת?
גישור (-5B, 48B סך הכל)
הפקודות הארוכות ביותר שעומדות בדרכנו לדפוס SVG שעבר אופטימיזציה מלאה הן פקודות "העבר אל" שתופסות 4, 5 ו-6 בתים, בהתאמה. אילוץ אחד שיש לנו הוא ש:
קטע נתוני נתיב (אם יש כזה) חייב להתחיל בפקודה "moveto".
אבל זה בסדר. הראשון הוא הקצר ביותר בכל מקרה. אם נחליף את השורות, נוכל להמציא הגדרת נתיב שבה עלינו רק לנוע אופקית או אנכית בין הלבנים. מה אם נוכל להשתמש ב- h
ו v
פקודות שם במקום M
?
התרשים שלמעלה מראה כיצד ניתן לצייר את שלוש הצורות עם נתיב יחיד. שימו לב שאנו ממנפים את העובדה שה fill
הפעולה סוגרת אוטומטית את החלק הפתוח שביניהם (110,0)
ו (0,0)
. עם הסידור מחדש הזה, הזזנו גם את הפער שמאלה ללבן ברוחב המלא בשורה השנייה. כך נראה הקוד, עדיין מחולק ללבנה אחת בכל שורה:
<path d="M0 0v30h50V0 h10v30h50 v10H10v30h100V0"/>
אין ספק שמצאנו את הפתרון הקטן ביותר עכשיו כשירדנו ל-48 בתים, נכון?! נו…
חיתוך ספרות (-4B, סך הכל 44B)
אם אתה יכול להיות קצת גמיש עם הממדים, יש עוד דרך קטנה שבה נוכל לייעל דפוסי SVG. עבדנו עם רוחב לבנים של 100
פיקסלים, אבל זה שלושה בתים. משנה את זה ל 90
פירושו בית אחד פחות בכל פעם שאנחנו צריכים לכתוב אותו. באופן דומה, השתמשנו בפער של 10
פיקסלים - אבל אם נשנה את זה ל 8
במקום זאת, אנו שומרים בייט בכל אחת מהאירועים הללו.
<path d="M0 0v30h45V0 h8v30h45 v8H8v30h90V0"/>
כמובן, זה גם אומר שעלינו להתאים את ממדי הדפוס בהתאם. להלן קוד דפוס ה-SVG הממוטב האחרון:
<pattern id="p" width="98" height="76" patternUnits="userSpaceOnUse"> <path d="M0 0v30h45V0h8v30h45v8H8v30h90V0"/>
</pattern>
השורה השנייה בקטע הנ"ל - לא סופר את ההזחות - היא הבתים 44. הגענו לכאן מ-197 בתים בשש איטרציות. זה שמנמן הקטנת גודל של 77.7%.!
אבל אני תוהה... האם זה באמת הגודל הקטן ביותר האפשרי? האם בדקנו את כל הדרכים האפשריות לייעל דפוסי SVG?
אני מזמין אותך לנסות ולצמצם עוד יותר את הקוד הזה, או אפילו להתנסות בשיטות חלופיות לאופטימיזציה של דפוסי SVG. אשמח לראות אם נוכל למצוא את המינימום הגלובלי האמיתי עם חוכמת ההמון!
עוד על יצירה ואופטימיזציה של דפוסי SVG
אם אתה מעוניין ללמוד עוד על יצירה ואופטימיזציה של דפוסי SVG, קרא את המאמר שלי בנושא יצירת דפוסים עם מסנני SVG. לחלופין, אם אתה רוצה לבדוק גלריה של 60+ דפוסים, אתה יכול לצפות ב PetitePatterns CodePen Collection. לבסוף, אתה מוזמן לצפות ההדרכות שלי ביוטיוב כדי לעזור לך להיכנס אפילו יותר לתוך דפוסי SVG.
אופטימיזציה של דפוסי SVG לגודלם הקטן ביותר פורסם במקור ב CSS-טריקים. אתה צריך לקבל את הניוזלטר.
- "
- 10
- 100
- 77
- 9
- 98
- אודות
- מוּחלָט
- חֶשְׁבּוֹן
- נוסף
- תעשיות
- מאפשר
- כְּבָר
- אחר
- גישה
- AREA
- מאמר
- תכונות
- זמין
- AXES
- קצת
- שחור
- לאתגר
- שינוי
- סגור
- קוד
- Common
- הקשר
- מכיל
- תוכן
- לתאם
- יכול
- יוצרים
- נוֹכְחִי
- נתונים
- עמוק יותר
- מטה
- מסתיים
- נוסד
- הכל
- דוגמה
- אלא
- לְנַסוֹת
- בסופו של דבר
- ראשון
- מתאים
- תזרים
- מצא
- נוסף
- פער
- מקבל
- גלוֹבָּלִי
- יש
- גובה
- לעזור
- כאן
- מודגש
- איך
- HTTPS
- לזהות
- תמונה
- לכלול
- כלול
- IT
- עצמו
- ידוע
- לדלוף
- לִלמוֹד
- למד
- מינוף
- קו
- קְצָת
- נראה
- אהבה
- עושה
- עשייה
- הצליח
- מתמטיקה
- אכפת לי
- יותר
- רוב
- המהלך
- MS
- מספר
- מספרים
- לקזז
- בסדר
- לפתוח
- אופטימיזציה
- אַחֶרֶת
- תבנית
- גופני
- נקודה
- מיקום
- אפשרי
- חזק
- יפה
- מחיר
- תהליך
- מספק
- איכות
- עגול
- ריצה
- אמר
- בצורה חלקה
- סדרה
- סט
- צורות
- דומה
- פָּשׁוּט
- שישה
- מידה
- So
- פִּתָרוֹן
- משהו
- מֶרחָב
- מסחרי
- התחלה
- התחלות
- נתמך
- מדבר
- דרך
- חלק עליון
- שָׁקוּף
- הדרכות
- להשתמש
- ערך
- לצפיה
- W3
- שעון
- ברוך הבא
- מה
- בתוך
- לְלֹא
- תיק עבודות
- עובד
- עובד
- ראוי
- YouTube