1. לפני שמתחילים
במדריך הזה נסביר איך מוסיפים סמנים תלת-ממדיים לאפליקציה ומגדירים להם סגנון. בנוסף, תלמדו איך להוסיף אנימציה לאפליקציה על ידי טיסה למיקומים ספציפיים ומסביב להם.
המדריך הזה מבוסס על המושגים שנדונו בcodelab הראשון. אם עדיין לא עשיתם זאת, כדאי להשלים את הקודלאב הזה כדי לקבל את הידע הבסיסי הנדרש ליצירת האפליקציה הזו.
מה עליכם לעשות
האפליקציה הזו מספקת סקירה כללית על המשרדים העיקריים של Google באירופה. המשתמשים יכולים לבחור משרד, להיכנס אליו ולעוף מסביב כדי לבדוק אותו, ואז להתרחק כדי לחזור לתצוגה הכללית. התכונות האלה, שנפוצות באפליקציות נסיעות וחקר, מספקות למשתמשים חוויה מעמיקה יותר.
בסדנת הקוד הזו תלמדו ליצור אפליקציית אינטרנט תלת-ממדית שמבצעת את הפעולות הבאות:
- טעינת Maps JavaScript API באופן דינמי.
- הוספת סמנים תלת-ממדיים למפה.
- הוספת סגנונות לסמנים באמצעות קובצי SVG.
- מאפשרת לכם לעוף אל הסמנים ולעוף סביבם.
- הפונקציה מסנכרנת את המיקומים מהקוד למערך.
מה תלמדו
- איך עובדים הסמנים.
- איך להגדיר סגנון לסימונים.
- איך אנימציה פועלת עם הפונקציות המובנות.
- מיקומי מצלמה לצילום לעומת מיקומי נקודות לצילום, כדי לקבל מסגרת טובה יותר.
- טיפים שימושיים לצילום פרמטרים של המצלמה כדי לקבל מסגרת טובה יותר לפריטים.
דרישות מוקדמות
כדי להשלים את Codelab הזה, עליכם להכיר את הנושאים הבאים. אם אתם כבר מכירים את הפלטפורמה של מפות Google, אתם יכולים לדלג אל Codelab.
מוצרים נדרשים בפלטפורמה של מפות Google
ב-Codelab הזה נשתמש במוצרים הבאים של פלטפורמת מפות Google:
- Maps JavaScript API
דרישות נוספות ל-Codelab הזה
כדי להשלים את הקודלאב הזה, תצטרכו את החשבונות, השירותים והכלים הבאים:
- חשבון Google Cloud שבו החיוב מופעל.
- מפתח API של הפלטפורמה של מפות Google עם ממשק API של JavaScript במפות Google מופעל.
- ידע בסיסי ב-JavaScript, ב-HTML וב-CSS.
- עורך טקסט או סביבת פיתוח משולבת (IDE) לבחירתכם, כדי לשמור ולערוך קובץ לצפייה.
- דפדפן אינטרנט כדי להציג את הקובץ תוך כדי עבודה.
2. להגדרה
הגדרת הפלטפורמה של מפות Google
אם עדיין אין לכם חשבון ב-Google Cloud Platform ופרויקט שבו החיוב מופעל, תוכלו להיעזר במדריך תחילת העבודה עם פלטפורמת מפות Google כדי ליצור חשבון לחיוב ופרויקט.
- ב-Cloud Console, לוחצים על התפריט הנפתח של הפרויקט ובוחרים את הפרויקט שבו רוצים להשתמש ב-codelab הזה.
- מפעילים את ממשקי ה-API וערכות ה-SDK של הפלטפורמה של מפות Google הנדרשים לסדנת הקוד הזו ב-Google Cloud Marketplace. כדי לעשות זאת, פועלים לפי השלבים שמפורטים בסרטון הזה או במסמך הזה.
- יוצרים מפתח API בדף Credentials במסוף Cloud. אפשר לפעול לפי השלבים שמפורטים בסרטון הזה או במסמך הזה. כל הבקשות לפלטפורמה של מפות Google מחייבות מפתח API.
3. גלובוס פשוט
כדי להתחיל לפתח את האפליקציה, חובה להגדיר את ההגדרות הבסיסיות. התוצאה תהיה תצוגה של כדור הארץ כ'גוש כחול' בצורתו הבסיסית ביותר, כפי שמוצג בתמונה:
הוספת הקוד לדף ההתחלה
כדי להוסיף את הגלובוס לאתר, צריך להוסיף את הקוד הבא לדף. הפעולה הזו תוסיף קטע לטעינה של Maps Javascript API ופונקציית init שיוצרת את רכיב המפה התלת-ממדית בדף שבו תוסיפו את הקוד של הסמנים.
חשוב להוסיף לדף מפתח משלכם (שיצרתם בקטע 'הגדרה'), אחרת לא תוכלו לאתחל את רכיב התלת-ממד.
<!DOCTYPE html>
<html>
<head>
<title>Step 1 - Simple Globe</title>
<style>
body {
height: 100vh;
margin: 0;
}
</style>
</head>
<body>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "<INSERT API KEY>",
v: "alpha",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map3D = null;
async function init() {
const { Map3DElement, MapMode } = await google.maps.importLibrary("maps3d");
map3D = new Map3DElement({
mode: MapMode.HYBRID,
});
document.body.append(map3D);
}
init();
</script>
</body>
</html>
עכשיו אפשר להתחיל לכוון את המיקום הרצוי. בשלב הבא נסביר איך עושים את זה.
4. תצוגת הפריים הראשון
אחרי שיצרתם מפה בתצוגת כדור הארץ, השלב הבא בתהליך ההטמעה הוא להגדיר את מיקום ההתחלה הנכון. כך המשתמשים יכולים לקבל סקירה כללית מיידית של המקום שבו הם עובדים.
הדוגמה הזו מתמקדת במשרדים של Google באירופה, אבל אפשר להחיל את הגישה הזו על כל מיקום בעולם – ממדינה שלמה ועד לבלוק אחד בעיר. המהירות והגמישות של המוצר מאפשרות לכם להתאים את האפליקציה מגלובלית למקומית עם שינויים מינימליים בקוד.
מתחילים עם הפריים הראשוני כדי שהמפה בתלת-ממד תיראה כך:
מכוונים את המצלמה לאירופה
כדי שהתצוגה תהיה כמו שמוצגת, צריך להגדיר את המסך בצורה נכונה, כאילו ממקמים מצלמה בחלל ומצלמים מלמעלה את המיקום.
כדי לעשות זאת, אפשר להשתמש במספר פרמטרים בחלונית הבקרה של המפה כדי להגדיר את פרטי המצלמה. באיור אפשר לראות איך הפרמטרים פועלים זה עם זה בעולם 'האמיתי'. באופן ספציפי, יש את נקודת המרכז שממנה המצלמה מצלמת, ואת המרחק מנקודת המבט שלכם (הטווח). צריך גם להגדיר את הטייה של נקודת המבט של המצלמה (אחרת תראו את כדור הארץ מלמעלה).
ההגדרה האחרונה, כיוון, קובעת את כיוון המצלמה. הוא נמדד כסטייה מצפון. הערכים האלה חלים על רכיב המפה התלת-ממדית כאובייקט כדי להגדיר את התצוגה הראשונית. אפשר לראות את זה בקוד עם ה-constructor המעודכן של רכיב תלת-ממדי.
map3D = new Map3DElement({
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
mode: MapMode.HYBRID
});
צילום הפרמטרים של המצלמה
כדי ליצור מסגרת לתצוגה במפה תלת-ממדית, צריך למקם את המצלמה במדויק, ויכול להיות שיהיה קשה לעשות זאת באמצעות קוד בלבד. כדי לפשט את התהליך, אפשר להשתמש בהאק השימושי הזה: מוסיפים לדף פונקציה שמתעדת את הפרמטרים של המצלמה כשמקליקים על התצוגה הנדרשת. הפרמטרים יוצגו במסוף, מוכנים להעתקה להגדרות המצלמה של האובייקט.
הקוד שבו תרצו להשתמש בהמשך מופיע בדוגמה של הדף הזה, אבל הוא לא מופיע בדוגמה של הדפים הבאים כי הוא לא נדרש ל-codelab. עם זאת, כדאי לזכור אותו אם רוצים ליצור הדגמות immersive יותר באמצעות מיקום מצלמה טוב יותר.
map3D.addEventListener('gmp-click', (event) => {
console.log("camera: { center: { lat: " + map3D.center.lat + ", lng : " + map3D.center.lng + ", altitude: " + map3D.center.altitude + " }, range: " + map3D.range + ", tilt: " + map3D.tilt + " ,heading: " + map3D.heading + ", }");
console.log("{ lat: " + event.position.lat + ", lng : " + event.position.lng + ", altitude: " + event.position.altitude + " }");
// Stop the camera animation when the map is clicked.
map3D.stopCameraAnimation();
});
שימו לב לשימוש בפונקציה stopCameraAnimation
. אם הדף מתקרב או מסתובב, כדאי שתוכלו להפסיק את האנימציה כדי שתוכלו לצלם את המיקום במסך באותו רגע. קטע הקוד הזה מאפשר לעשות זאת. פרטים נוספים זמינים במסמכי התיעוד של stopCameraAnimation
.
פלט לדוגמה מהקליק, כפי שהוא מוצג במסוף.
camera: { center: { lat: 51.39870122020001, lng : -0.08573187165829443, altitude: 51.66845062662254 }, range: 716.4743880553578, tilt: 50.5766672986501 ,heading: -1.048260134782318, }
step2.html:40 { lat: 51.398158351120536, lng : -0.08561139388593597, altitude: 51.860469133677626 }
אפשר להשתמש בטקסט מהמצלמה כקלט JSON במגוון אובייקטים במפות 3D. הפלט השני הוא מיקום הנקודה בפועל שבה בוצע הלחיצה, וגם הוא שימושי ליצירת נקודות או כל דבר אחר לצורך מיקום של סמנים.
עכשיו, כשהמסגרת של הדף מוגדרת כמו שצריך, אפשר להוסיף סמנים. בשלב הבא מוסבר איך עושים את זה.
פתרון ברמת הקטע
בשלב הזה, הדף המלא מוצג כפתרון לאימות ההטמעה. (אם מעתיקים, חשוב להשתמש במפתח ה-API שלכם).
<!DOCTYPE html>
<html>
<head>
<title>Step 2 - Europe View</title>
<style>
body {
height: 100vh;
margin: 0;
}
</style>
</head>
<body>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "<INSERT API KEY>",
v: "alpha",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map3D = null;
async function init() {
const { Map3DElement, MapMode } = await google.maps.importLibrary("maps3d");
map3D = new Map3DElement({
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
mode: MapMode.HYBRID,
});
map3D.addEventListener('gmp-click', (event) => {
console.log("camera: { center: { lat: " + map3D.center.lat + ", lng : " + map3D.center.lng + ", altitude: " + map3D.center.altitude + " }, range: " + map3D.range + ", tilt: " + map3D.tilt + " ,heading: " + map3D.heading + ", }");
console.log("{ lat: " + event.position.lat + ", lng : " + event.position.lng + ", altitude: " + event.position.altitude + " }");
map3D.stopCameraAnimation();
});
document.body.append(map3D);
}
init();
</script>
</body>
</html>
5. סימון פשוט
בקטע הזה נסביר איך להוסיף את הסמן הראשון. קודם כל, נספק לכם פרטים כלליים על סמנים.
מפות תלת-ממדיות תומכות ביצירה של שתי כיתות שונות של סמנים: הכיתה Marker3DElement והכיתה Marker3DInteractiveElement. הבחירה בין שתי הכיתות האלה נקבעת לפי הרצון שלכם לאפשר לחיצות על הסמנים או לא. מלבד זאת, הם זהים במהותם, כך שתחילה תיצרו Marker3DElement ואז תבצעו "שדרוג" שלו ל-Marker3DInteractiveElement בשלבים הבאים.
הפתרון המלא לשלב הזה מופיע כאן:
הוספת גובה לסימונים
הדבר הראשון שחשוב לדעת הוא שהסמנים הם תלת-ממדיים, כמו כל שאר הפריטים במפה התלת-ממדית. כלומר, למיקום יכול להיות גובה (אַלְטוּטוּד), והגובה הזה יכול לייצג מיקום ביחס לגובה פני הים, לקרקע, לרשת או להיצמד לקרקע ולהתעלם מהמיקום ביחס לגובה. פרטים נוספים זמינים בקטע Altitude constants במסמכי העזרה של AltitudeMode.
אפשר גם להגדיר אם הסמן יהיה בולט או לא באמצעות הערך extruded. ההגדרה הזו קובעת אם יופיע קו קטן מהסמן לקרקע כדי להציג את המיקום בפועל ביחס לגובה. ההגדרה הזו שימושית לבחירת נקודות על הקרקע. דוגמה לכך היא המיקום של Google בבריטניה. שני הפריטים מוגדרים כמודלים תלת-ממדיים, והמיקום שלהם מוגדר לגובה מוחלט. הראשון ב-75 מטר והשני ב-125 מטר.
גובה 75 מטר. | גובה 125 מטר. |
הסתרה או הצגה של סמנים עם חסימות ותקלות
יכול להיות שהדבר לא חשוב בהדגמה שלנו, כי המיקומים רחוקים זה מזה, אבל אם יש סמנים שעשויים לחפוף זה לזה או להסתתר מאחורי בניינים, אפשר לקבוע מה יקרה להם באמצעות הערכים collisionBehavior או drawsWhenOccluded.
להתנהגות של התנגשויות יש את האפשרויות הבאות:
REQUIRED
: (ברירת המחדל) תמיד להציג את הסמן, ללא קשר להתנגשות.OPTIONAL_AND_HIDES_LOWER_PRIORITY
הצגת הסמן רק אם הוא לא חופף לסמנים אחרים. אם שני סמנים מהסוג הזה חופפים, מוצג הסמן עם הערך הגבוה יותר שלzIndex
. אם יש להם את אותוzIndex
, יוצג התמונה שנמצאת במיקום הנמוך יותר במסך האנכי.REQUIRED_AND_HIDES_OPTIONAL
תמיד להציג את הסמן ללא קשר להתנגשות, ולהסתיר סמנים או תוויותOPTIONAL_AND_HIDES_LOWER_PRIORITY
שיחפו על הסמן.
ההבדלים באופן הצגת הסמנים על סמך התנהגות ההתנגשות שמוגדרת מוצגים בתמונות. כל הסמנים מוצגים כשמגדירים את הערך REQUIRED
, אבל אם משתמשים ב-REQUIRED_AND_HIDES_OPTIONAL
, במקרה הזה יוצגו הסמנים שנמצאים נמוך יותר במסך (אפשר לשנות את הערך של zIndex כדי לגרום לסמנים אחרים להופיע מעליהם, אם רוצים).
חובה | REQUIRED_AND_HIDES_OPTIONAL |
לגבי חסימה, אפשר לבחור אם הסימונים יוצגו מאחורי בניינים או לא. זה מוצג בתמונה הבאה. כשהערך של drawsWhenOccluded
מוגדר כ-true, הסימונים מוצגים מעט כהים יותר כשהם נמצאים מאחורי בניינים. כשהערך מוגדר כ-false, הסימונים מוסתרים כשהם נמצאים מאחורי בניין. פרטים נוספים זמינים בטבלה הבאה:
|
|
כפי שצוין, סמנים שמוסווים על ידי התנגשות יוצגו כהים אם מותר לצייר סמנים מוסתרים. בתמונה אפשר לראות שחלק מהסמנים מוסתרים על ידי המבנים וחלק מוסתרים על ידי סמנים אחרים.
לפרטים נוספים, אפשר לעיין בדוגמה collision-behavior במפה דו-ממדית.
ניקוי לוח הציור
עכשיו הגיע הזמן ליצור את הסמן הראשון. כדי לוודא שהמשתמש מתמקד בסמנים, אפשר להשבית את תוויות ברירת המחדל במפה התלת-ממדית.
מגדירים את הערך mode
של רכיב המפה התלת-ממדית כ-SATELLITE
.
מידע נוסף זמין במאמר מצב.
map3D = new Map3DElement({
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
mode: MapMode.SATELLITE
});
התוצאה היא המפה התלת-ממדית הבאה:
הוספת הסמן הראשון
עכשיו, כשהקנבס נקי, אפשר להוסיף את הסמן הראשון. הפרמטרים העיקריים כוללים מיקום ותווית.
כדי להוסיף סמן, מגדירים את המיקום שלו. אפשר גם לכלול תווית שתופיע מעל הסמן ורכיבים אחרים כפי שמתואר במסמכי העזרה של Marker3DElement.
כדי להוסיף את הסמן שלנו, מוסיפים את הקוד הבא אחרי השורה שמסתירה את תוויות ברירת המחדל, כפי שמוצג:
const marker = new Marker3DElement({
position: { lat: 51.5332, lng: -0.1260, altitude: 75 },
label: 'Google UK',
altitudeMode: 'ABSOLUTE',
extruded: true,
});
map3D.append(marker);
אחרי שיוצרים את הסמן, מוסיפים אותו למפה התלת-ממדית באמצעות שיטת ה-append. חשוב לזכור שהסמנים מאוחסנים כמערך של רכיבי צאצאים במפה התלת-ממדית. כדי לשנות סמן, צריך לגשת אליו דרך המערך הזה.
מוודאים שה-Marker3DElement
נטען מ-Maps JavaScript API על ידי הוספה שלו לרשימת הספריות בזמן טעינת ה-API.
const { Map3DElement, MapMode, Marker3DElement } = await google.maps.importLibrary("maps3d");
עכשיו, כשהדף נטען, כל אירופה תהיה גלויה עם סמן מעל המשרד בלונדון. כפי שמוצג באנימציה, אפשר להתקרב באופן ידני כדי לראות את הסמן מעל המיקום שנוצר.
עכשיו, אחרי שהעליתם את הסמן הראשון, השלב הבא הוא לשפר את המראה שלו.
פתרון ברמת הקטע
בשלב הזה, הדף המלא מוצג כפתרון לאימות ההטמעה. (אם מעתיקים, חשוב להשתמש במפתח ה-API שלכם).
<!DOCTYPE html>
<html>
<head>
<title>Step 3 - Simple Marker</title>
<style>
body {
height: 100vh;
margin: 0;
}
</style>
</head>
<body>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "<INSERT API KEY>",
v: "alpha",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map3D = null;
async function init() {
const { Map3DElement, MapMode, Marker3DElement } = await google.maps.importLibrary("maps3d");
map3D = new Map3DElement({
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
mode: MapMode.SATELLITE,
});
const marker = new Marker3DElement({
position: { lat: 51.5332, lng: -0.1260, altitude: 75 },
label: 'Google UK',
altitudeMode: 'ABSOLUTE',
extruded: true,
});
map3D.append(marker);
document.body.append(map3D);
}
init();
</script>
</body>
</html>
6. סמן SVG
בשלב הזה נוסיף דגל לסמן כדי לייצג את המדינה שבה הוא נמצא, וכך נבליט אותו. נראה איך עושים את זה, ולשם כך צריך להכיר את PinElement.
בסוף תקבלו את המראה החדש, כפי שמוצג:
התאמה אישית בסיסית באמצעות PinElement
אחד מהרכיבים המשותפים בין הסמנים ב-JavaScript API, בין אם מדובר במפות דו-ממדיות או תלת-ממדיות, הוא PinElement. כשאתם מוסיפים Marker3DElement ל-Map3DElement , אתם מוסיפים PinElement ל-Marker3DElement כצאצא לרכיב הזה.
ה-PinElement מכיל את היכולת, ברמה בסיסית, לשנות את הסמן הרגיל כדי להגדיר את צבע המסגרת, צבע הנקודה הפנימית (או הגליף) וצבע הרקע שלו. אפשר לראות אותם בתמונה שבה מוצג סמן 2D.
אפשר גם להגדיר את גודל הסמן דרך הרכיב על ידי הגדרת ערך הסולם שלו (ערך גדול מ-1 גדול מהרגיל, וערך קטן מ-1 קטן יותר ביחס).
אפשר גם להחליף את ה-Glyph בתמונה או בקובץ SVG כדי ליצור מראה מותאם אישית יותר, ועדיין לשמור על המראה הרגיל של סיכות המפה של PinElement.
מעבר ל-PinElements
בשלב הזה תעדכנו את PinElement
הרגיל בדגל svg ובצבעים שונים, אבל חשוב לדעת שאפשר גם לשנות לגמרי את המראה של סמן כך שהוא לא ייראה אפילו כמו סיכה במפה. בתוך הסמן אפשר גם להוסיף גרפיקה חדשה באמצעות תבניות, כמו HTMLImageElement ו-SVGElement. פרטים נוספים על כך מופיעים במסמך Marker3DElement-Slots.
כדי לראות מה אפשר לעשות, כדאי לעיין בדוגמאות הבאות, שבהן מוצגות דוגמאות לעיצוב סמנים באמצעות מספר שיטות שונות.
סמנים עם התאמה אישית בסיסית באמצעות PinElement, ראו דוגמאות. | סמנים עם התאמה אישית מורכבת באמצעות תבנית באמצעות SVG ותמונות, ראו דוגמאות. |
מוסיפים את PinElement
כדי לשנות את המראה של הסמן, קודם כול צריך לוודא שספריית PinElement נוספה לדף. כדי לעשות זאת, מוסיפים את שורת הקוד הבאה אחרי ייבוא הספרייה maps3d
:
const { Map3DElement, MapMode, Marker3DElement } = await google.maps.importLibrary("maps3d");
const { PinElement } = await google.maps.importLibrary('marker');
עכשיו, אחרי שהרכיב נטען, אפשר להפנות אל PinElement וליצור אותו. בודקים את הקוד, מוסיפים אותו בין המקום שבו נוצר הסמן לבין המקום שבו הוא מצורף למפה התלת-ממדית.
const marker = new Marker3DElement({
position: { lat: 51.5332, lng: -0.1260, altitude: 75 },
label: 'Google UK',
altitudeMode: 'ABSOLUTE',
extruded: true,
});
const base = document.location.href.substr(0, document.location.href.lastIndexOf("/"));
const markerPin = new PinElement({
"background": 'white',
"glyph": new URL(base + '/images/gb.svg'),
"scale": 1.0,
});
marker.append(markerPin);
map3D.append(marker);
מכיוון שאתם לא רק מעלים סיכה בסיסית, יש כמה דברים שצריך לעשות מעבר להגדרת PinElement, עם צבע הרקע והסולם המשויכים.
קודם צריך ליצור הפניה לתמונה בפורמט SVG של סמל הדגל, במקרה הזה דגל בריטניה. אפשר לקבל אותם מאוסף כמו זה בכתובת https://flagicons.lipis.dev/.
אחרי שתקבלו את הסמל, תוכלו להציב אותו במקום שהאתר יוכל לאתר. במקרה כזה, תוכלו להגדיר את מיקום התמונה בקוד או להשתמש במיקום האתר הנוכחי כקטע ההתחלה של הספרייה, כפי שמוצג כאן באמצעות משתנה הבסיס. לאחר מכן אפשר לקשר את זה למיקום בשרת לסמל המתאים, במקרה הזה '/images/gb.svg'.
הפעולה הזו יוצרת PinElement שנראה כמו זה שמוצג:
אחרי שממקמים את הדגל במיקום הנכון ומזינים את הקוד במיקום הנכון, אמורה להופיע מפה תלת-ממדית שנראית כך:
עכשיו סיימנו לעצב את הסמן, ואפשר גם לשנות אותו כך שיהיה אפשר ללחוץ עליו כדי להוסיף אינטראקטיביות. נבצע זאת בשלב הבא.
פתרון ברמת הקטע
בשלב הזה, הדף המלא מוצג כפתרון לאימות ההטמעה. (אם מעתיקים, חשוב להשתמש במפתח ה-API שלכם).
בנוסף, חשוב לזכור שצריך לקבל את קובץ ה-SVG (או קובץ PNG, לבחירתך) של הדגל ולשמור אותו בספרייה שאפשר למצוא דרך הדף (כאן הוא נשמר בתיקיית התמונות).
<!DOCTYPE html>
<html>
<head>
<title>Step 4 - SVG Marker</title>
<style>
body {
height: 100vh;
margin: 0;
}
</style>
</head>
<body>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "<INSERT API KEY>",
v: "alpha",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map3D = null;
async function init() {
const { Map3DElement, MapMode, Marker3DElement } = await google.maps.importLibrary("maps3d");
const { PinElement } = await google.maps.importLibrary('marker');
map3D = new Map3DElement({
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
mode: MapMode.SATELLITE,
});
const marker = new Marker3DElement({
position: { lat: 51.5332, lng: -0.1260, altitude: 75 },
label: 'Google UK',
altitudeMode: 'ABSOLUTE',
extruded: true,
});
const base = document.location.href.substr(0, document.location.href.lastIndexOf("/"));
const markerPin = new PinElement({
"background": 'white',
"glyph": new URL(base + '/images/gb.svg'),
"scale": 1.0,
});
marker.append(markerPin);
map3D.append(marker);
document.body.append(map3D);
}
init();
</script>
</body>
</html>
7. סמן אינטראקטיבי
בשלב האחרון נוספה סיכה לדף, אבל מלבד המראה היפה שלה, היא לא עושה הרבה, ועדיין צריך לבצע אינטראקציה עם המפה בתלת-ממד באותו אופן. השלב הבא הוא להוסיף את היכולת לבצע פעולה כלשהי עם הסמן כשלוחצים עליו, כדי לאפשר לסמן להגיב לאינטראקציה של המשתמש.
כדי להוסיף את התכונה הזו, צריך לבצע טרנספורמציה של Marker3DElement ל-Marker3DInteractiveElement. בסוף תקבלו דף שנראה דומה, אבל כשלוחצים על הסמן יופיע התראה. זה בערך איך זה נראה:
קודם צריך לשנות את סוג הסמן
כדי להוסיף אינטראקטיביות לסמן, צריך לוודא שהוא משתמש בכיתה הנכונה. Marker3DInteractiveElement הוא הרכיב הנדרש, אבל מכיוון שהוא תוסף ל-Marker3DElement, לא צריך לעשות שום דבר מלבד לטעון את הכיתה החדשה ולשנות את שם הכיתה ב-constructor.
const { Map3DElement, MapMode, Marker3DInteractiveElement } = await google.maps.importLibrary("maps3d");
const { PinElement } = await google.maps.importLibrary('marker');
map3D = new Map3DElement({
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
mode: MapMode.SATELLITE,
});
const marker = new Marker3DInteractiveElement({
position: { lat: 51.5332, lng: -0.1260, altitude: 75 },
label: 'Google UK',
altitudeMode: 'ABSOLUTE',
extruded: true,
});
בשלב השני מוסיפים את האירוע מסוג קליק לסמן
בשלב הבא מוסיפים אירוע לחיצה לסמן כדי לטפל באינטראקציה של המשתמש ולהגיב. בקטע הקוד אפשר לראות שאירוע הקליק נוסף לסמן. במקרה כזה, מתבצעת הפעלה של התראה וקופץ הטקסט שמוצגת בו התווית מהסימון, שנוצר מהיעד של האירוע שהופעל ומאפשר לנו לגשת למאפיין התווית. מוסיפים את הקוד הבא לאפליקציה מיד אחרי יצירת הסמן.
marker.addEventListener('gmp-click', (event) => {
alert('You clicked on : ' + event.target.label);
event.stopPropagation();
});
הערה: אירוע stopPropagation משמש כדי לוודא שכל רכיבי ההקשה האחרים בסטאק יופעלו באובייקטים הבסיסיים, כמו לוח הציור הראשי של המפה התלת-ממדית.
עכשיו, כשמריצים את האפליקציה, אמורה להופיע התוצאה הבאה:
עכשיו, כשיש אפשרות לבצע פעולה כלשהי כשלוחצים על הסמן, אפשר להוסיף אנימציה לדף בשלב הבא.
פתרון ברמת הקטע
בשלב הזה, הדף המלא מוצג כפתרון לאימות ההטמעה. (אם מעתיקים, חשוב להשתמש במפתח ה-API שלכם).
<!DOCTYPE html>
<html>
<head>
<title>Step 5 - Interactive Marker</title>
<style>
body {
height: 100vh;
margin: 0;
}
</style>
</head>
<body>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "<INSERT API KEY>",
v: "alpha",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map3D = null;
async function init() {
const { Map3DElement, MapMode, Marker3DInteractiveElement } = await google.maps.importLibrary("maps3d");
const { PinElement } = await google.maps.importLibrary('marker');
map3D = new Map3DElement({
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
mode: MapMode.SATELLITE,
});
const marker = new Marker3DInteractiveElement({
position: { lat: 51.5332, lng: -0.1260, altitude: 75 },
label: 'Google UK',
altitudeMode: 'ABSOLUTE',
extruded: true,
});
marker.addEventListener('gmp-click', (event) => {
alert('You clicked on : ' + event.target.label);
event.stopPropagation();
});
const base = document.location.href.substr(0, document.location.href.lastIndexOf("/"));
const markerPin = new PinElement({
"background": 'white',
"glyph": new URL(base + '/images/gb.svg'),
"scale": 1.0,
});
marker.append(markerPin);
map3D.append(marker);
document.body.append(map3D);
}
init();
</script>
</body>
</html>
8. מעבר בטיסה אל
בשלב הזה תשתמשו באפשרות ללחוץ על הסמן כדי להוסיף אנימציה לטיסה למיקום שלו. אפשר לראות את התכונה הזו בפעולה כאן.
אנימציה באמצעות flyCameraTo
כדי להוסיף את התכונה הזו לדף, משתמשים בשיטה flyCameraTo של מפות תלת-ממד, שבה המצלמה מבצעת אנימציה בין מיקום המצלמה שבו אתם נמצאים לבין מיקום המצלמה שרוצים להציג, מבצעת אינטרפולציה בין השניים ומבצעת אנימציה של הטיסה במפה התלת-ממדית.
כשמשתמשים בפקודה flyCameraTo, צריך לציין את FlyToAnimationOptions שיש לה שני מאפיינים: endCamera, שהוא המיקום שאליו המצלמה צריכה להצביע בסוף האנימציה, ו-durationMillis , שהוא משך הזמן במילישניות שיידרש לביצוע המעבר.
בדוגמה, מכוונים את המצלמה למבנה שמהווה את מיקום הסמן, עם הטיה של 65 מעלות, טווח של 500 מטרים ומצב צפון עם כיוון של 0 מעלות. מגדירים את תזמון האנימציה ל-12,500 אלפיות השנייה (12.5 שניות).
מחליפים את אירוע ההתראה הנוכחי בדף בקטע הקוד flyCameraTo:
marker.addEventListener('gmp-click', (event) => {
map3D.flyCameraTo({
endCamera: {
center: marker.position,
tilt: 65,
range: 500,
heading: 0,
},
durationMillis: 12500,
});
event.stopPropagation();
});
זהו, עכשיו אמורה להיות לך אפשרות לרענן את הדף, ללחוץ על הסמן ולעוף אל Google UK, כפי שמוצג באנימציה:
בשלב הזה הוספתם סמן שניתן ללחוץ עליו, שמזיז את המצלמה למיקום הסמן. בשלב הבא תוסיפו את היכולת להזיז את המצלמה סביב הנקודה כך שתקיף את המיקום.
פתרון ברמת הקטע
בשלב הזה, הדף המלא מוצג כפתרון לאימות ההטמעה. (אם מעתיקים, חשוב להשתמש במפתח ה-API שלכם).
<!DOCTYPE html>
<html>
<head>
<title>Step 6 - Zoom To</title>
<style>
body {
height: 100vh;
margin: 0;
}
</style>
</head>
<body>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "<INSERT API KEY>",
v: "alpha",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map3D = null;
async function init() {
const { Map3DElement, MapMode, Marker3DInteractiveElement } = await google.maps.importLibrary("maps3d");
const { PinElement } = await google.maps.importLibrary('marker');
map3D = new Map3DElement({
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
mode: MapMode.SATELLITE,
});
const marker = new Marker3DInteractiveElement({
position: { lat: 51.5332, lng: -0.1260, altitude: 75 },
label: 'Google UK',
altitudeMode: 'ABSOLUTE',
extruded: true,
});
marker.addEventListener('gmp-click', (event) => {
map3D.flyCameraTo({
endCamera: {
center: marker.position,
tilt: 65,
range: 500,
heading: 0,
},
durationMillis: 12500,
});
event.stopPropagation();
});
const base = document.location.href.substr(0, document.location.href.lastIndexOf("/"));
const markerPin = new PinElement({
"background": 'white',
"glyph": new URL(base + '/images/gb.svg'),
"scale": 1.0,
});
marker.append(markerPin);
map3D.append(marker);
document.body.append(map3D);
}
init();
</script>
</body>
</html>
9. טיסה מסביב
הרכיב האחרון באנימציה שלנו הוא שימוש בשיטה flyCameraAround כדי ליצור אנימציה של מסלול סביב הבניין. בסוף תקבלו אנימציה שתמריא אל הבניין ואז תתעופף סביבו כמו שמוצג באנימציה. זהו סרטון קצר מדי כדי להיחשב כדוגמה אמיתית, אבל הוא שימושי כדי להראות איך הפעולה פועלת, בלי להיות ארוך מדי. אפשר להתנסות עם התזמונים עד שמוצאים ערך שמתאים לכם.
בואו לטוס מסביב!
השיטה flyCameraAround דומה לפונקציה flyCameraTo בכך שהיא מקבלת מספר אפשרויות כקלט, שמאפשרות לקבוע את המיקום שבו המצלמה תנוע במסלול, את פרמטרי המצלמה ואת משך הזמן במילי-שניות שיידרש להקפה. לבסוף, אפשר גם לציין את מספר הסיבובים שיכולים להתרחש בזמן שצוין. אפשר לראות את כל האפשרויות כאן, בקטע FlyAroundAnimationOptions.
אבל רגע!
באנימציה אפשר לראות את האנימציה שטסה למיקום ואז טסה סביבו, תוך קישור האנימציות. כדי לעשות זאת, משתמשים באירוע gmp-animationend של מפות 3D כדי לוודא שהאנימציה הנוכחית הסתיימה לפני שמפעילים את האנימציה הבאה. האנימציה הזו אמורה להתרחש רק פעם אחת לפני שהיא נעצרת.
בודקים את הקוד ומוסיפים אותו אחרי הקוד שנוסף בקטע הקודם.
marker.addEventListener('gmp-click', (event) => {
map3D.flyCameraTo({
endCamera: {
center: marker.position,
tilt: 65,
range: 500,
heading: 0,
},
durationMillis: 5000,
});
map3D.addEventListener('gmp-animationend', () => {
map3D.flyCameraAround({
camera: {
center: marker.position,
tilt: 65,
range: 500,
heading: 0,
},
durationMillis: 5000,
rounds: 1
});
}, { once: true });
event.stopPropagation();
});
הוספת היכולת להקשיב לאירוע gmp-animationend מאפשרת להפעיל את האירוע flyCameraAround. הגדרת נקודת ההתחלה כאותה נקודה שבה השתמשתם במצלמה הסופית של שיטת המעבר 'הזזת המצלמה' מאפשרת מעבר חלק (כדי לא לגרום לתנועות חדות למיקום חדש). שוב, הערך של durationMillis מוגדר כדי לקבוע את משך הזמן של האנימציה. במקרה כזה, השיטה מקבלת גם אפשרות אחרת, rounds
, והיא מוגדרת כ-1.
פירוש הדבר הוא שהמצלמה תסתובב סביב הנקודה פעם אחת ב-5 שניות. אתם יכולים להתנסות בערכים האלה כדי למצוא את המספר שמתאים לכם.
בשלב הזה האנימציה תסתיים, אבל לא רוצים שהאירוע gmp-animationend יופעל שוב עם קטע הקוד הזה, כי זה יוביל לכך שהמסלול יתבצע ללא הגבלת זמן. כדי למנוע זאת, אפשר להגדיר את ההגדרה once של המאזין כ-true. המשמעות היא שהאירוע יוסר אחרי שהוא יסתיים, וכך יתאפשר למנוע את הלולאה האינסופית.
אחרי שמוסיפים את הקוד הזה, אפשר להריץ את הפתרון ולראות שהאנימציה עכשיו טסה סביב הסמן בסוף, כפי שמוצג באנימציה:
בשלב הזה, הוספת סימן שאפשר ללחוץ עליו. לאחר מכן, המצלמה תתעופף למיקום של הסימן ותסתובב סביבו. בשלב הבא נתחיל להוסיף נקודות נוספות ולאפשר לנו לעבור ביניהן.
פתרון ברמת הקטע
בשלב הזה, הדף המלא מוצג כפתרון לאימות ההטמעה. (אם מעתיקים, חשוב להשתמש במפתח ה-API שלכם).
<!DOCTYPE html>
<html>
<head>
<title>Step 7 - Zoom Around</title>
<style>
body {
height: 100vh;
margin: 0;
}
</style>
</head>
<body>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "<INSERT API KEY>",
v: "alpha",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map3D = null;
const europeCamera = {
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
};
async function init() {
const { Map3DElement, MapMode, Marker3DInteractiveElement } = await google.maps.importLibrary("maps3d");
const { PinElement } = await google.maps.importLibrary('marker');
map3D = new Map3DElement({
...europeCamera,
mode: MapMode.SATELLITE,
});
const marker = new Marker3DInteractiveElement({
position: { lat: 51.5332, lng: -0.1260, altitude: 75 },
label: 'Google UK',
altitudeMode: 'ABSOLUTE',
extruded: true,
});
marker.addEventListener('gmp-click', (event) => {
map3D.flyCameraTo({
endCamera: {
center: marker.position,
tilt: 65,
range: 500,
heading: 0,
},
durationMillis: 5000,
});
map3D.addEventListener('gmp-animationend', () => {
map3D.flyCameraAround({
camera: {
center: marker.position,
tilt: 65,
range: 500,
heading: 0,
},
durationMillis: 5000,
rounds: 1
});
}, { once: true });
event.stopPropagation();
});
const base = document.location.href.substr(0, document.location.href.lastIndexOf("/"));
const markerPin = new PinElement({
"background": 'white',
"glyph": new URL(base + '/images/gb.svg'),
"scale": 1.0,
});
marker.append(markerPin);
map3D.append(marker);
document.body.append(map3D);
}
init();
</script>
</body>
</html>
10. פריז!
לונדון היא עיר נהדרת, אבל היא נראית קצת בודדה בדף, אז נתחיל להוסיף כמה מיקומים חדשים, ונתחיל בפריז. כדי לעשות זאת, אפשר להשתמש במערך כדי לאחסן את כל הפרטים הספציפיים למיקום, ולאחר מכן להשתמש בו כקלט לפונקציות ולמשתנים שמגדירים את הפרמטרים של הצגת הסמנים, וגם את המעבר למיקומי המצלמה ומסביב להם. כפי שצוין, יכול להיות שהמיקום הזה יהיה שונה ממיקום נקודת הסמן, למשל כדי לקבל תמונה טובה יותר של בניין.
מערך מיקומים
כדי שלא תצטרכו להטמיע בקוד את כל הפרטים של מיקום מסוים, כמו מצלמת צפייה, נקודת סמן ואפשרויות תצוגה, תוכלו להשתמש במערך קטן של אובייקטי JSON כדי לאחסן את הנתונים האלה. לאחר מכן אפשר להחיל את זה כשהסמנים נוצרים ומשמשים באפליקציה. הדוגמה הזו מופיעה בקטע הקוד, שבו נוצר משתנה בשם officeLocations
כדי לאחסן את המערך.
מוסיפים את הקוד הבא ממש לפני פונקציית init. חשוב גם לשים לב שמשתנה הבסיס הועבר מחוץ לפונקציית init כדי שניתן יהיה להחיל אותו על כל מיקומי המשרדים.
const base = document.location.href.substr(0, document.location.href.lastIndexOf("/"));
const europeCamera = {
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
};
const officeLocations = [
{
"name": "Google France",
"camera": {
"center": { lat: 48.877276, lng: 2.329978, altitude: 48 },
"range": 178,
"tilt": 57.48,
"heading": -17,
},
"point": { lat: 48.8775183, lng: 2.3299791, altitude: 60 },
"pin": {
"background": 'white',
"glyph": new URL(base + '/images/fr.svg'),
"scale": 1.0,
},
},
{
"name": "Google UK",
"camera": {
"center": { lat: 51.5332, lng: -0.1260, altitude: 38.8 },
"range": 500,
"tilt": 56.21672368296945,
"heading": -31.15763027564165,
},
"point": { lat: 51.5332, lng: -0.1260, altitude: 75 },
"pin": {
"background": 'white',
"glyph": new URL(base + '/images/gb.svg'),
"scale": 1.0,
},
}]
const base = document.location.href.substr(0, document.location.href.lastIndexOf("/"));
לכל מיקום משרד יש את המאפיינים הבאים:
- name : שם המיקום.
- camera : התצוגה הראשונית שבה אפשר לראות את המיקום שאליו רוצים לעבור ולעוף מסביב.
- point : המיקום שבו רוצים למקם את הסמן.
- pin : הפרטים של צבע הסיכה של הסמן ומאפייני הגליף
זווית אחרת
ניתן לראות כאן שבבריטניה מרכז המצלמה ונקודת הסמן זהים (מלבד הגובה), ואילו בצרפת המצלמה והנקודה שונים. הסיבה לכך היא שבמיקום בצרפת, הסמן צריך להיות במיקום שונה מהתצוגה הראשונית של המצלמה, כדי לספק תצוגה טובה יותר של כל הבניין כשמצלמים אותו ומקיפים אותו, בהשוואה לתצוגה שתתקבל אם משתמשים בנקודת הסמן.
חזרה לדף 'אירופה'
אחת מהפונקציות של הוספת נקודות היא הדרישה לאפשרות לעבור ביניהן. אפשר להשתמש בתפריט נפתח כדי לאפשר בחירה, אבל בדוגמה הזו המצלמה תרחף חזרה לתצוגה האירופית בכל פעם כדי לאפשר למשתמש לבחור מיקום אחר.
כדי לעשות זאת, צריך לשמור את התצוגה הראשונית במשתנה שאפשר להשתמש בו כדי לאפס את המצלמה לתצוגה המלאה של אירופה. בדוגמה הזו מוסיפים משתנה חדש בשם europeCamera
כדי לאחסן את הערך לשימוש מאוחר יותר.
עדכון פונקציית init
העריכה הראשונה שצריך לבצע היא להשתמש באובייקט europeCamera
כקלט ביצירת Map3DElement
.
העריכה השנייה שצריך לבצע היא להוסיף לולאה לקטע יצירת הסמן כדי לעדכן אותו עם הפרמטרים שמאוחסנים במשתנים. אפשר לראות אותם בקוד המוצג:
- office.point : מיקום הסמן.
- office.name : שם המשרד שמשמש לתווית של הסמן.
- office.camera : המיקום הראשוני של המצלמה.
- office.pin : האפשרויות של PinElement להבדלים בתצוגה
בנוסף, אל תשכחו לקבל קובץ SVG או תמונה של הדגל הצרפתי.
async function init() {
const { Map3DElement, MapMode, Marker3DInteractiveElement } = await google.maps.importLibrary("maps3d");
const { PinElement } = await google.maps.importLibrary('marker');
map3D = new Map3DElement({
...europeCamera,
mode: MapMode.SATELLITE,
});
officeLocations.forEach(office => {
const marker = new Marker3DInteractiveElement({
position: office.point,
label: office.name,
altitudeMode: 'ABSOLUTE',
extruded: true,
});
marker.addEventListener('gmp-click', (event) => {
map3D.flyCameraTo({
endCamera: office.camera,
durationMillis: 5000,
});
map3D.addEventListener('gmp-animationend', () => {
map3D.flyCameraAround({
camera: office.camera,
durationMillis: 5000,
rounds: 1
});
map3D.addEventListener('gmp-animationend', () => {
map3D.flyCameraTo({
endCamera: europeCamera,
durationMillis: 5000,
});
}, { once: true });
}, { once: true });
event.stopPropagation();
});
const markerPin = new PinElement(office.pin);
marker.append(markerPin);
map3D.append(marker);
});
document.body.append(map3D);
}
שימו לב שפונקציה שנייה מסוג gmp-animationend מתווספת אחרי האנימציה flyCameraAround
כדי לטפל בהחזרה של המצלמה לתצוגה האירופית, באמצעות המשתנה europeCamera
שנשמר. כפי שמוצג באנימציה:
בשלב הזה, האפליקציה הורחבה כך שתכלול שני מיקומים ואפשרות לעבור ביניהם באמצעות אנימציה ומערך מיקומים. בשלב הבא, שאר מיקומי המשרדים יתווספו למערך.
פתרון ברמת הקטע
בשלב הזה, הדף המלא מוצג כפתרון לאימות ההטמעה. (אם מעתיקים, חשוב להשתמש במפתח ה-API שלכם).
בנוסף, חשוב לזכור שצריך לקבל את קובץ ה-SVG (או קובצי ה-PNG, לבחירתך) של הדגל ולשמור אותו בספרייה שאפשר למצוא דרך הדף (כאן הוא מאוחסן בתיקיית התמונות).
<!DOCTYPE html>
<html>
<head>
<title>Step 8 - Paris!</title>
<style>
body {
height: 100vh;
margin: 0;
}
</style>
</head>
<body>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "<INSERT API KEY>",
v: "alpha",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map3D = null;
const base = document.location.href.substr(0, document.location.href.lastIndexOf("/"));
const europeCamera = {
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
};
const officeLocations = [
{
"name": "Google France",
"camera": {
"center": { lat: 48.877276, lng: 2.329978, altitude: 48 },
"range": 178,
"tilt": 57.48,
"heading": -17,
},
"point": { lat: 48.8775183, lng: 2.3299791, altitude: 60 },
"pin": {
"background": 'white',
"glyph": new URL(base + '/images/fr.svg'),
"scale": 1.0,
},
},
{
"name": "Google UK",
"camera": {
"center": { lat: 51.5332, lng: -0.1260, altitude: 38.8 },
"range": 500,
"tilt": 56.21672368296945,
"heading": -31.15763027564165,
},
"point": { lat: 51.5332, lng: -0.1260, altitude: 75 },
"pin": {
"background": 'white',
"glyph": new URL(base + '/images/gb.svg'),
"scale": 1.0,
},
}]
async function init() {
const { Map3DElement, MapMode, Marker3DInteractiveElement } = await google.maps.importLibrary("maps3d");
const { PinElement } = await google.maps.importLibrary('marker');
map3D = new Map3DElement({
...europeCamera,
mode: MapMode.SATELLITE,
});
officeLocations.forEach(office => {
const marker = new Marker3DInteractiveElement({
position: office.point,
label: office.name,
altitudeMode: 'ABSOLUTE',
extruded: true,
});
marker.addEventListener('gmp-click', (event) => {
map3D.flyCameraTo({
endCamera: office.camera,
durationMillis: 5000,
});
map3D.addEventListener('gmp-animationend', () => {
map3D.flyCameraAround({
camera: office.camera,
durationMillis: 5000,
rounds: 1
});
map3D.addEventListener('gmp-animationend', () => {
map3D.flyCameraTo({
endCamera: europeCamera,
durationMillis: 5000,
});
}, { once: true });
}, { once: true });
event.stopPropagation();
});
const markerPin = new PinElement(office.pin);
marker.append(markerPin);
map3D.append(marker);
});
document.body.append(map3D);
}
init();
</script>
</body>
</html>
11. עוד מקומות
האפליקציה כוללת עכשיו את כל התכונות הנדרשות, אבל המפה בתלת-ממד עדיין נראית קצת ריקה, לכן עכשיו נוסיף עוד כמה מיקומים כדי להוסיף לה קצת צבע. באמצעות מערך, קל להמשיך לאכלס מיקומים חדשים עם סמנים ייחודיים משלהם. השלב האחרון הוא להמשיך להוסיף סמנים עד שמתקבלת התצוגה הבאה.
הוספת עוד סמנים
ל-Google יש מספר משרדים במדינות רבות באירופה, אז נוסיף כמה מהם למפה. צריך רק לעדכן את המערך. המקור של הקוד הזה יכול להיות שירות אינטרנט או קובץ סטטי כלשהו. במקרה שלנו, מטעמי פשטות, הוא יישמר באותו דף.
אפשר להוסיף כמה סמנים שרוצים, והם ייאספו על ידי הדף ולאחר מכן יתווספו באופן אוטומטי לתצוגה. חשוב לזכור לקבל את הדגלים הנכונים ולשמור אותם בספריית התמונות (או בכל מקום אחר שנוח לכם).
const officeLocations = [
{
name: "Google France",
camera: {
center: { lat: 48.877276, lng: 2.329978, altitude: 48 },
range: 178,
tilt: 57.48,
heading: -17,
},
point: { lat: 48.8775183, lng: 2.3299791, altitude: 60 },
pin: {
background: 'white',
glyph: new URL(base + '/images/fr.svg'),
scale: 1.0,
},
},
{
name: "Google UK",
camera: {
center: { lat: 51.5332, lng: -0.1260, altitude: 38.8 },
range: 500,
tilt: 56.21672368296945,
heading: -31.15763027564165,
},
point: { lat: 51.5332, lng: -0.1260, altitude: 75 },
pin: {
background: 'white',
glyph: new URL(base + '/images/gb.svg'),
scale: 1.0,
},
},
{
name: "Google Belgium",
camera: {
center: { lat: 50.83930408436509, lng: 4.38052394507952, altitude: 64.38932203802196},
range: 466.62899893119175,
tilt: 43.61569474716178,
heading: 51.805907046332074,
},
point: { lat: 50.8392653, lng: 4.3808751, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/be.svg'),
scale: 1.0,
},
},
{
name: "Google Czechia",
camera: {
center: {
lat: 50.07004093853976,
lng: 14.402871475443956,
altitude: 223.39574818495532
},
range: 522.0365799222782,
tilt: 62.39511972890614,
heading: -39.150149539328304,
},
point: { lat: 50.0703122, lng: 14.402668199999999, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/cz.svg'),
scale: 1.0,
},
},
{
name: "Google Denmark",
details: "2, Sankt Petri Passage 5, 1165 København",
camera: {
center: {
lat: 55.680359539635866,
lng: 12.570460204526002,
altitude: 30.447654757346044
},
range: 334.8786935049066,
tilt: 55.38819319004654,
heading: 149.63867461295067,
},
point: { lat: 55.6804504, lng: 12.570279099999999, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/dk.svg'),
scale: 1.0,
},
},
,
{
name: "Google Greece",
camera: {
center: {
lat: 38.038634694028055,
lng: 23.802924946201266,
altitude: 196.45884670344995
},
range: 343.57226336076565,
tilt: 54.97375927639567,
heading: -33.26775344055724,
},
point: { lat: 38.038619, lng: 23.8031622, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/gr.svg'),
scale: 1.0,
},
},
{
name: "Google Germany",
camera: {
center: {
lat: 53.55397683312404,
lng: 9.986350507286808,
altitude: 44.83610870143956
},
range: 375.3474077822466,
tilt: 71.35078443829818,
heading: -160.76930098951416,
},
point: { lat: 53.5540227, lng: 9.9863, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/de.svg'),
scale: 1.0,
},
},
{
name: "Google Ireland",
camera: {
center: { lat: 53.339816899999995, lng: -6.2362644, altitude: 38.777415761228006 },
range: 500,
tilt: 56.21672368296945,
heading: -31.15763027564165,
},
point: { lat: 53.339816899999995, lng: -6.2362644, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/ie.svg'),
scale: 1.0,
},
},
{
name: "Google Italy",
camera: {
center: {
lat: 45.486361346538224,
lng: 9.18995496294455,
altitude: 138.55834058400072
},
range: 694.9398023590038,
tilt: 57.822470255679114,
heading: 84.10194883488619,
},
point: { lat: 45.4863064, lng: 9.1894762, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/it.svg'),
scale: 1.0,
},
},
{
name: "Google Lithuania",
camera: {
center: {
lat: 54.698040606567965,
lng: 25.30965338542576,
altitude: 111.80276944294413
},
range: 412.5808304977545,
tilt: 43.50793332082195,
heading: -29.181098269421028,
},
point: { lat: 54.6981204, lng: 25.3098617, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/at.svg'),
scale: 1.0,
},
},
{
name: "Google Netherlands",
camera: {
center: {
lat: 52.33773837150874,
lng: 4.871754560171063,
altitude: 53.68063996154723
},
range: 473.1982259177312,
tilt: 56.216523350388634,
heading: 71.78252318033718,
},
point: { lat: 52.337801, lng: 4.872065999999999, altitude: 100 },
pin: {
background: 'white',
glyph: new URL(base + '/images/nl.svg'),
scale: 1.0,
},
},
{
name: "Google Norway",
camera: {
center: { lat: 59.90991209999999, lng: 10.726020799999999, altitude: 38.777415761228006 },
range: 500,
tilt: 56.21672368296945,
heading: -31.15763027564165,
},
point: { lat: 59.90991209999999, lng: 10.726020799999999, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/no.svg'),
scale: 1.0,
},
},
{
name: "Google Poland",
camera: {
center: { lat: 52.22844380000001, lng: 20.9851819, altitude: 38.777415761228006 },
range: 500,
tilt: 56.21672368296945,
heading: -31.15763027564165,
},
point: { lat: 52.22844380000001, lng: 20.9851819, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/pl.svg'),
scale: 1.0,
},
},
{
name: "Google Portugal",
camera: {
center: {
lat: 38.7240122810727,
lng: -9.150628263172639,
altitude: 55.299662291551044
},
range: 337.7474313328639,
tilt: 56.79772652682846,
heading: 176.0722118222208,
},
point: { lat: 38.723915999999996, lng: -9.150629, altitude: 35 },
pin: {
background: 'white',
glyph: new URL(base + '/images/pt.svg'),
scale: 1.0,
},
},
{
name: "Google Romania",
camera: {
center: {
lat: 44.43076650172983,
lng: 26.109700164718586,
altitude: 125.57895810814505
},
range: 364.25249956711923,
tilt: 38.517539223834326,
heading: -38.81294924429363,
},
point: { lat: 44.4309897, lng: 26.1095719, altitude: 75 },
pin: {
background: 'white',
glyph: new URL(base + '/images/ro.svg'),
scale: 1.0,
},
},
{
name: "Google Spain",
camera: {
center: {
lat: 40.450078762608875,
lng: -3.6930085080020856,
altitude: 753.6446342341894
},
range: 845.7279793010093,
tilt: 46.752510050599746,
heading: 4.718779524265234,
},
point: { lat: 40.450294199999995, lng: -3.6927915, altitude: 175 },
pin: {
background: 'white',
glyph: new URL(base + '/images/es.svg'),
scale: 1.0,
},
},
{
name: "Google Sweden",
camera: {
center: {
lat: 59.33313751316038,
lng: 18.054618219238293,
altitude: 16.728213706832868
},
range: 377.5210725830039,
tilt: 63.59478230626709,
heading: 98.53138488367703,
},
point: { lat: 59.3332093, lng: 18.0536386, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/se.svg'),
scale: 1.0,
},
},
{
name: "Google Switzerland",
camera: {
center: {
lat: 47.365411056285275,
lng: 8.525063594405356,
altitude: 419.2348376754488
},
range: 166.74918737631742,
tilt: 59.31431457129067,
heading: -32.620415961949206,
},
point: { lat: 47.365452, lng: 8.5249253, altitude: 100 },
pin: {
background: 'white',
glyph: new URL(base + '/images/ch.svg'),
scale: 1.0,
},
}
]
לאחר מכן אמור להופיע דף מלא כמו בתמונה, שמאפשר למשתמש ללחוץ על כל מיקום ולעוף אליו ולידו, ואז לחזור אחורה.
סיימתם את הקודלאב. בקטע הבא נסכם את הדברים ונציע לכם דברים חדשים לנסות.
פתרון ברמת הקטע
בשלב הזה, הדף המלא מוצג כפתרון לאימות ההטמעה. (אם מעתיקים, חשוב להשתמש במפתח ה-API שלכם).
בנוסף, חשוב לזכור שצריך לקבל את קובץ ה-SVG (או קובצי ה-PNG, לבחירתך) של הדגל ולשמור אותו בספרייה שאפשר למצוא דרך הדף (כאן הוא מאוחסן בתיקיית התמונות).
<!DOCTYPE html>
<html>
<head>
<title>Step 9 - More Places!</title>
<style>
body {
height: 100vh;
margin: 0;
}
</style>
</head>
<body>
<script>
(g => { var h, a, k, p = "The Google Maps JavaScript API", c = "google", l = "importLibrary", q = "__ib__", m = document, b = window; b = b[c] || (b[c] = {}); var d = b.maps || (b.maps = {}), r = new Set, e = new URLSearchParams, u = () => h || (h = new Promise(async (f, n) => { await (a = m.createElement("script")); e.set("libraries", [...r] + ""); for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]); e.set("callback", c + ".maps." + q); a.src = `https://maps.${c}apis.com/maps/api/js?` + e; d[q] = f; a.onerror = () => h = n(Error(p + " could not load.")); a.nonce = m.querySelector("script[nonce]")?.nonce || ""; m.head.append(a) })); d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n)) })({
key: "<INSERT API KEY>",
v: "alpha",
// Use the 'v' parameter to indicate the version to use (weekly, beta, alpha, etc.).
// Add other bootstrap parameters as needed, using camel case.
});
</script>
<script>
let map3D = null;
const base = document.location.href.substr(0, document.location.href.lastIndexOf("/"));
const europeCamera = {
center: { lat: 46.717, lng: 7.075, altitude: 2175.130 },
range: 5814650,
tilt: 33,
heading: 4.36,
};
const officeLocations = [
{
name: "Google France",
details: "8 Rue de Londres, 75009 Paris, France",
camera: {
center: { lat: 48.877276, lng: 2.329978, altitude: 48 },
range: 178,
tilt: 57.48,
heading: -17,
},
point: { lat: 48.8775183, lng: 2.3299791, altitude: 60 },
pin: {
background: 'white',
glyph: new URL(base + '/images/fr.svg'),
scale: 1.0,
},
},
{
name: "Google UK",
details: "6 Pancras Square, London N1C 4AG, UK",
camera: {
center: { lat: 51.5332, lng: -0.1260, altitude: 38.8 },
range: 500,
tilt: 56.21672368296945,
heading: -31.15763027564165,
},
point: { lat: 51.5332, lng: -0.1260, altitude: 75 },
pin: {
background: 'white',
glyph: new URL(base + '/images/gb.svg'),
scale: 1.0,
},
},
{
name: "Google Belgium",
details: "Chau. d'Etterbeek 180, 1040 Brussel",
camera: {
center: { lat: 50.83930408436509, lng: 4.38052394507952, altitude: 64.38932203802196},
range: 466.62899893119175,
tilt: 43.61569474716178,
heading: 51.805907046332074,
},
point: { lat: 50.8392653, lng: 4.3808751, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/be.svg'),
scale: 1.0,
},
},
{
name: "Google Czechia",
details: "Stroupežnického 3191/17, 150 00 Praha 5-Smíchov",
camera: {
center: {
lat: 50.07004093853976,
lng: 14.402871475443956,
altitude: 223.39574818495532
},
range: 522.0365799222782,
tilt: 62.39511972890614,
heading: -39.150149539328304,
},
point: { lat: 50.0703122, lng: 14.402668199999999, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/cz.svg'),
scale: 1.0,
},
},
{
name: "Google Denmark",
details: "2, Sankt Petri Passage 5, 1165 København",
camera: {
center: {
lat: 55.680359539635866,
lng: 12.570460204526002,
altitude: 30.447654757346044
},
range: 334.8786935049066,
tilt: 55.38819319004654,
heading: 149.63867461295067,
},
point: { lat: 55.6804504, lng: 12.570279099999999, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/dk.svg'),
scale: 1.0,
},
},
,
{
name: "Google Greece",
details: "Fragkokklisias 6, Athina 151 25",
camera: {
center: {
lat: 38.038634694028055,
lng: 23.802924946201266,
altitude: 196.45884670344995
},
range: 343.57226336076565,
tilt: 54.97375927639567,
heading: -33.26775344055724,
},
point: { lat: 38.038619, lng: 23.8031622, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/gr.svg'),
scale: 1.0,
},
},
{
name: "Google Germany",
details: "ABC-Straße 19, 20354 Hamburg",
camera: {
center: {
lat: 53.55397683312404,
lng: 9.986350507286808,
altitude: 44.83610870143956
},
range: 375.3474077822466,
tilt: 71.35078443829818,
heading: -160.76930098951416,
},
point: { lat: 53.5540227, lng: 9.9863, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/de.svg'),
scale: 1.0,
},
},
{
name: "Google Ireland",
details: "Gordon House, 4 Barrow St, Grand Canal Dock, Dublin 4, D04 V4X7",
camera: {
center: { lat: 53.339816899999995, lng: -6.2362644, altitude: 38.777415761228006 },
range: 500,
tilt: 56.21672368296945,
heading: -31.15763027564165,
},
point: { lat: 53.339816899999995, lng: -6.2362644, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/ie.svg'),
scale: 1.0,
},
},
{
name: "Google Italy",
details: "Isola Building C, Via Federico Confalonieri, 4, 20124 Milano",
camera: {
center: {
lat: 45.486361346538224,
lng: 9.18995496294455,
altitude: 138.55834058400072
},
range: 694.9398023590038,
tilt: 57.822470255679114,
heading: 84.10194883488619,
},
point: { lat: 45.4863064, lng: 9.1894762, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/it.svg'),
scale: 1.0,
},
},
{
name: "Google Lithuania",
details: "Vilnius Tech Park, Antakalnis st. 17, 2nd building, LT-10312, Vilnius",
camera: {
center: {
lat: 54.698040606567965,
lng: 25.30965338542576,
altitude: 111.80276944294413
},
range: 412.5808304977545,
tilt: 43.50793332082195,
heading: -29.181098269421028,
},
point: { lat: 54.6981204, lng: 25.3098617, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/at.svg'),
scale: 1.0,
},
},
{
name: "Google Netherlands",
details: "Claude Debussylaan 34, 1082 MD Amsterdam",
camera: {
center: {
lat: 52.33773837150874,
lng: 4.871754560171063,
altitude: 53.68063996154723
},
range: 473.1982259177312,
tilt: 56.216523350388634,
heading: 71.78252318033718,
},
point: { lat: 52.337801, lng: 4.872065999999999, altitude: 100 },
pin: {
background: 'white',
glyph: new URL(base + '/images/nl.svg'),
scale: 1.0,
},
},
{
name: "Google Norway",
details: "Bryggegata 6, 0250 Oslo",
camera: {
center: { lat: 59.90991209999999, lng: 10.726020799999999, altitude: 38.777415761228006 },
range: 500,
tilt: 56.21672368296945,
heading: -31.15763027564165,
},
point: { lat: 59.90991209999999, lng: 10.726020799999999, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/no.svg'),
scale: 1.0,
},
},
{
name: "Google Poland",
details: "Rondo Daszynskiego 2, 00-843 Warsaw",
camera: {
center: { lat: 52.22844380000001, lng: 20.9851819, altitude: 38.777415761228006 },
range: 500,
tilt: 56.21672368296945,
heading: -31.15763027564165,
},
point: { lat: 52.22844380000001, lng: 20.9851819, altitude: 25 },
pin: {
background: 'white',
glyph: new URL(base + '/images/pl.svg'),
scale: 1.0,
},
},
{
name: "Google Portugal",
details: "R. Duque de Palmela 37 Piso 4, 1250-097 Lisboa",
camera: {
center: {
lat: 38.7240122810727,
lng: -9.150628263172639,
altitude: 55.299662291551044
},
range: 337.7474313328639,
tilt: 56.79772652682846,
heading: 176.0722118222208,
},
point: { lat: 38.723915999999996, lng: -9.150629, altitude: 35 },
pin: {
background: 'white',
glyph: new URL(base + '/images/pt.svg'),
scale: 1.0,
},
},
{
name: "Google Romania",
details: "Bulevardul Corneliu Coposu 6-8, București 030167",
camera: {
center: {
lat: 44.43076650172983,
lng: 26.109700164718586,
altitude: 125.57895810814505
},
range: 364.25249956711923,
tilt: 38.517539223834326,
heading: -38.81294924429363,
},
point: { lat: 44.4309897, lng: 26.1095719, altitude: 75 },
pin: {
background: 'white',
glyph: new URL(base + '/images/ro.svg'),
scale: 1.0,
},
},
{
name: "Google Spain",
details: "Torre Picasso, Pl. Pablo Ruiz Picasso, 1, Tetuán, 28020 Madrid",
camera: {
center: {
lat: 40.450078762608875,
lng: -3.6930085080020856,
altitude: 753.6446342341894
},
range: 845.7279793010093,
tilt: 46.752510050599746,
heading: 4.718779524265234,
},
point: { lat: 40.450294199999995, lng: -3.6927915, altitude: 175 },
pin: {
background: 'white',
glyph: new URL(base + '/images/es.svg'),
scale: 1.0,
},
},
{
name: "Google Sweden",
details: "Kungsbron 2, 111 22 Stockholm",
camera: {
center: {
lat: 59.33313751316038,
lng: 18.054618219238293,
altitude: 16.728213706832868
},
range: 377.5210725830039,
tilt: 63.59478230626709,
heading: 98.53138488367703,
},
point: { lat: 59.3332093, lng: 18.0536386, altitude: 50 },
pin: {
background: 'white',
glyph: new URL(base + '/images/se.svg'),
scale: 1.0,
},
},
{
name: "Google Switzerland",
details: "Brandschenkestrasse 110, 8002 Zürich",
camera: {
center: {
lat: 47.365411056285275,
lng: 8.525063594405356,
altitude: 419.2348376754488
},
range: 166.74918737631742,
tilt: 59.31431457129067,
heading: -32.620415961949206,
},
point: { lat: 47.365452, lng: 8.5249253, altitude: 100 },
pin: {
background: 'white',
glyph: new URL(base + '/images/ch.svg'),
scale: 1.0,
},
}
]
async function init() {
const { Map3DElement, MapMode, Marker3DInteractiveElement } = await google.maps.importLibrary("maps3d");
const { PinElement } = await google.maps.importLibrary('marker');
map3D = new Map3DElement({
...europeCamera,
mode: MapMode.SATELLITE,
});
officeLocations.forEach(office => {
const marker = new Marker3DInteractiveElement({
position: office.point,
label: office.name,
altitudeMode: 'RELATIVE_TO_GROUND',
extruded: true,
});
marker.addEventListener('gmp-click', (event) => {
map3D.flyCameraTo({
endCamera: office.camera,
durationMillis: 2000,
});
map3D.addEventListener('gmp-animationend', () => {
map3D.flyCameraAround({
camera: office.camera,
durationMillis: 2000,
rounds: 1
});
map3D.addEventListener('gmp-animationend', () => {
map3D.flyCameraTo({
endCamera: europeCamera,
durationMillis: 2000,
});
}, { once: true });
}, { once: true });
event.stopPropagation();
});
const markerPin = new PinElement(office.pin);
marker.append(markerPin);
map3D.append(marker);
});
document.body.append(map3D);
}
init();
</script>
</body>
</html>
12. השלבים הבאים
בקודלאב הזה למדתם את העקרונות הבסיסיים של מה שאפשר לעשות עם תצוגת 3D ב-Maps JavaScript API. בשלב הבא, נסו להוסיף למפה כמה מהתכונות הבאות:
- מוסיפים רשימה נפתחת כדי לאפשר בחירת משרד.
- אפשר להשתמש באפשרויות הנוספות לעיצוב של הסמנים כדי להוסיף קצת עניין.
- כדאי לבדוק את הספריות הנוספות שזמינות ל-Maps JavaScript API ומאפשרות תכונות נוספות, כמו ספריית Places שמאפשרת להציג את הדירוג של כל משרד באמצעות מזהה המקום שלו.
כדי לקבל מידע נוסף על דרכים לעבודה עם הפלטפורמה של מפות Google ועם תצוגה תלת-ממדית באינטרנט, אפשר לעיין בקישורים הבאים: