برنامه نویسی

یک نقشه را با جزوه در یک پروژه بعدی ادغام کنید

در هفته های اخیر من روی پروژه ای کار کرده ام که نیاز به ادغام کارت تعاملی برای نمایش داده های جغرافیایی دارد. من قبلاً از کتابفروشی استفاده کرده بودم جزوه 🍃 در طول آموزش و من به طور طبیعی به این راه حل ساده و انعطاف پذیر روی آوردم.

چرا استفاده نمی شود react-leaflet ؟

اگرچه این کتابخانه محاصره شده است جزوه در مؤلفه های React ، او نیازهای من را در این پروژه برآورده نکرد. ناسازگاری نسخه ها (React ، Ts ، Next) و سادگی تنظیم مستقیم جزوه من را به این رویکرد مینیمالیستی سوق داد.


1. اولیه سازی نقشه 🗺

نصب کتابفروشی با دستور زیر:

yarn add leaflet

ایجاد یک جزء


  • ما مهم هستیم جزوه و قلاب های لازم
  • ما استفاده می کنیم useRef برای نسبت دادن مرجع به نقشه ما ، که به شما امکان می دهد نمونه های کارت را به درستی مدیریت کرده و از درگیری ها در مونتاژ/جداسازی جلوگیری کنید.
  • ما کارت را با آن پیکربندی می کنیم L.map() : گزینه هایی از قبیل سطح بزرگنمایی ، مختصات مرکز یا فعال سازی بزرگنمایی به پیمایش را مشخص کنید. برای دیدن گزینه های مختلف برای پیکربندی ، می توانید آنها را در اسناد در اینجا پیدا کنید.
  • ما یک کاشی شخصی با آن اضافه می کنیم L.tileLayer() بدون فراموش کردن اضافه کردن تخصیص اجباری برای احترام به حقوق نویسندگان.
  • سرانجام ، ما حذف نمونه های کارت را برای از بین بردن مؤلفه برای جلوگیری از برخورد ، مدیریت می کنیم.
"use client"
import { useEffect, useRef } from "react"
import L from "leaflet"

const mapRef = useRef<L.Map | null>(null)

useEffect(() => {
    if (mapRef.current) {
      mapRef.current.remove()
      mapRef.current = null
    }

    const map = L.map("map", {
      center: [48.8566, 2.3522], // coordonnées de Paris
      zoom: 10, 
      scrollWheelZoom: false,
    })

    L.tileLayer("https://tiles.stadiamaps.com/tiles/stamen_toner_lite/{z}/{x}/{y}{r}.png",
      {attribution: "©Stamen Design, ©OpenStreetMap contributors",}).addTo(map)

    mapRef.current = map

    return () => {
        if (mapRef.current) {
            mapRef.current.remove()
            mapRef.current = null
        }
    }

    }, [])

  return <div id="map" className="w-full h-full">div>
}

نقشه جزوه طراحی استامن


2. خطاهای مربوط به DOM را در Next.js مدیریت کنید

به عنوان جزوه برای کار کردن از DOM (سند مدل Object Model) در چندین سطح استفاده کنید (اولیه سازی نقشه ، نشانگرها و غیره) برای جلوگیری از خطاهای نوع ، غیرفعال کردن آن در سمت SSR (سرور) مهم است: ❌ ReferenceError: پنجره تعریف نشده استبشر

برای چه "use client" کافی نیست؟

خوب "use client" این مؤلفه را مجبور به انجام مشتری از طرف مشتری کند ، این تضمین نمی کند که همه وابستگی ها از این قانون پیروی کنند. به عنوان مثال ، واردات جهانی مانند import L from 'leaflet' به محض بارگیری پرونده ، حتی قبل از ساخت مؤلفه اجرا می شود. علاوه بر این ، تنظیمات یا وابستگی های خاصی ممکن است در بارگیری دخالت کند جزوه در سمت سرور ، که باعث اشتباه می شود.

✅ راه حل برای حل این مشکل: واردات پویا

واردات پویا از بعد. js به شما امکان می دهد یک مؤلفه را فقط در سمت مشتری بارگیری کنید ، کاملاً غیرفعال کردن ارائه در سمت سرور (ssr: false)بشر این مانع می شود جزوه و ساخت و سازهای آن در جایی که DOM وجود ندارد اعدام شود.
stonchation مستندات رسمی برای مدیریت واردات پویا.

در یک جدید مؤلفه مشتری که ما تماس می گیریم ، ما به صورت پویا مؤلفه را وارد می کنیم

به شرح زیر:

"use client"
import dynamic from "next/dynamic"

const Map = dynamic(() => import("./Map").then((mod) => mod.Map), {
    ssr: false,
})

export const MapContainer = () => {
    return (
        <div className="md:flex-1 w-[30rem] h-[30rem] border-2 border-black mb-6">
            <Map />
        div>
    )
}

افزودن بارگذاری مشروط

حتی با { ssr: false }، اگر برخی از مشکلات ممکن است بوجود بیاید جزوه قبل از آماده شدن DOM بارگیری می شود. برای جلوگیری از هرگونه درگیری ، می توانیم تأییدیه را در مؤلفه اضافه کنیم نقشه، در آغاز useEffect که نقشه را آغاز می کند:

  useEffect(() => {
    if (typeof window === "undefined") {
       return
    }

  if (mapRef.current) {
      mapRef.current.remove()
      mapRef.current = null
    }

...

سبک های سمت مشتری را بارگیری کنید

مرحله آخر انتقال واردات CSS به طور مستقیم به پرونده است global.css (در شروع پرونده) برای مدیریت متمرکز:

@import "leaflet/dist/leaflet.css";

3. نشانگرها را اضافه کنید

یک نشانگر ساده اضافه کنید

const marker = L.marker([48.8566, 2.3522]).addTo(map);
marker.bindPopup("Welcome to Paris 🥖!");

به جز آن .. کنسول شما مطمئناً خطای 404 را برای رسیدن به پرونده های آن نشان می دهد جزوه نوع:

GET /marker-icon-2x.png 404 in 4113ms
GET /marker-shadow.png 404 in 4106ms

برگه نشانگر خطا

به طور پیش فرض ، جزوه سعی کنید تصاویر نشانگرهای خود (marker-icon.png ، marker-shadow.png و غیره) را از یک مسیر مربوط به بارگیری کنید node_modules، که اغلب با سازمان یک پروژه در محیطی مانند Next.js یا سایر چارچوب های مدرن مطابقت ندارد.

✅ راه حل LA:

  • ما پرونده ها را در راه کپی/می چسبانیم node_modules/leaflet/dist/images در یک پرونده جدید leaflet که در پرونده پیدا خواهیم کرد public:

جایی که جزوه نماد نشانگر را پیدا کنید

  • و ما مسیرهای جدید دسترسی به تصاویر را به وضوح تعریف می کنیم:

    L.Icon.Default.mergeOptions({
           iconRetinaUrl: "./leaflet/marker-icon-2x.png",
       iconUrl: "./fealflet/marker-icon.png",
       shadowUrl: "./leaflet/marker-shadow.png",
    })

جزوه نشانگر پیش فرض

اما راه حل مورد علاقه من همچنان سفارشی سازی است.

یک نشانگر شخصی اضافه کنید

  • ما ابتدا باید نمادهای پیش فرض را اضافه کنیم تا از تولید آنها جلوگیری شود و به پایان برسد خطاهای 404بشر
  • سپس تصویر خود را وارد می کنیم ، نماد شخصی سازی شده ای را که با آن پیکربندی می کنیم ایجاد می کنیم L.marker()بشر
  • سرانجام ، ما نشانگر شخصی خود را به نقشه خود اضافه می کنیم (در صورت تمایل با پاپ آپ):
   L.Icon.Default.mergeOptions({
           iconRetinaUrl: null,
       iconUrl: null,
       shadowUrl: null,
   })

    const customIcon = L.icon({
       iconUrl: "/map-pin2.png",
       iconSize: [30, 30],
       iconAnchor: [15, 30],
       popupAnchor: [0, -30],
    })

    const marker = L.marker([48.8566, 2.3522], { icon: customIcon}).addTo(map)
    marker.bindPopup("Welcome to Paris 🥖!")

نشانگر سفارشی روی جزوه

سپس می توانید Geoloc را فعال کنید ، نقطه کاربر یا هر داده تعاملی دیگری را که به نظر شما مربوط می شود اضافه کنید!


4. 🎨 سفارشی سازی نقشه

شخصی سازی یک کارت جزوه به شما امکان می دهد یک تجربه کاربر مطابق با پروژه خود ایجاد کنید. خواهیم دید: چگونه کاشی ها را تغییر دهیم ، دکمه های زوم را با طراحی خود سازگار کنید و پنجره های منحصر به فرد ایجاد کنید.

با کاشی بازی کنید

کاشی ها پایه بصری کارت شما هستند. یک کاشی چاه می تواند هویت بصری یک پروژه را تقویت کند.
آیا چیزی اصلی ، شیرین تر می خواهید؟ انتخاب برای tile آبرنگ مراحل!
برای یافتن کاشی های رایگان در اینجا دو منبع مفید وجود دارد:

نقشه را شکل دهید (دکمه های بزرگنمایی ، ظرف ..)

در پرونده 📁 global.css شما می توانید چیزهای زیادی را تجربه کرده و کارت را به هویت بصری پروژه خود نزدیک کنید.
در اینجا مثالی از کارهایی که می توانیم انجام دهیم آورده شده است:

/* styles généraux /*
.leaflet-container {
    border-radius: 50%;
    overflow: hidden;
    position: relative;
}

.leaflet-control-container {
    position: absolute;
    top: 11rem;
    left: 1rem;
}

/* styles des boutons liés au zoom /*
.leaflet-control-zoom {
    position: absolute;
    border: none !important;
    top: 10px;
    left: -10px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.leaflet-touch .leaflet-bar a {
    width: 40px;
    height: 40px;
    line-height: 40px;
    border: none !important;
    color: white !important;
    font-size: 22px !important;
    border-radius: 50% !important;
    background: rgba(0, 0, 0, 0.673);
    box-shadow: 0 5px 7px rgba(0, 0, 0, 0.3);
    width: 40px;
    height: 40px;
    cursor: pointer;
    transition: all 0.3s ease;
}

/* styles des boutons au survol de la souris /*
.leaflet-control-zoom-in:hover,
.leaflet-control-zoom-out:hover {
    background: #6f00ffb3 !important;
    color: white !important;
    border-color: #6f00ffb3 !important;
}

جزوه نقشه سفارشی زیبا با CSS

بد نیست ، درست است؟ توجه داشته باشید که من تخصیص پیش فرض را غیرفعال کردم (اضافه کنید attributionControl: false, به گزینه های اولیه سازی نقشه شما) و اینکه من شخصی اضافه کردم.

گفتی پاپ آپ؟

ریخته شده سفارشی SA:

  • ما به غیرفعال کردن سبک پیش فرض از طریق CSS فکر می کنیم
  • و سپس پنجره جدید را به نشانگر اضافه می کنیم
    const customPopup = ``

const marker = L.marker([48.875335693359375, 2.3433215618133545], {
            icon: customIcon,
        }).addTo(map)
        marker.bindPopup(customPopup, { closeButton: false })

پنجره سفارشی با جزوه


ولایت رفیق، شما می دانید که چگونه یک کارت تعاملی را با ادغام و سفارشی سازی کنید جزوه 😊

و اگر اینطور نیست ، از چه ابزارهای دیگری برای ایجاد کارت در برنامه های خود استفاده می کنید؟

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا