Сегодня сделаем секцию Map нашего лендинга. Вставим интерактивную карту Яндекса через iframe.
Полезные ссылки:
Часть 1. Подготовка и настройка проекта
Часть 2. Настройка конфигурации и установка необходимых библиотек
Часть 3. Создание CSS-переменных и верстка блока Header
Часть 4. Верстка секции Hero, создание компонента Button
Часть 5. Верстка секции About
Часть 6. Верстка секции Gallery
Часть 7. Верстка секции WhyUs
Часть 8. Верстка секции Catalogue
Часть 9. Верстка секции Map
Часть 10. Верстка секции Footer
Часть 11. Создание якорных ссылок, рефакторинг
Часть 12. Создание мобильного меню
Часть 13. Анимация секций при скролле
Часть 14. Установка метаданных
Часть 15. Настройка Favicon.ico
Часть 16. Настройка счетчика Яндекс Метрики
Часть 17. Публикуем проект на хостинге
Яндекс карты
Для вставки карт на сайт я обычно использую сервис Яндекса — конструктор карт, он доступен по ссылке
Все очень просто:
1. Создаём карту и наносим необходимые метки и маршруты.
2. Копируем сгенерированный код iframe для вставки на сайт.
Создание компонента Map.jsx
В папке sections создадим файл компонента Map.jsx.
Содержимое файла Map.jsx
import { useEffect, useState } from 'react';
export default function Map() {
const [mapIsActive, setMapIsActive] = useState(false);
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
if (!mounted) return null;
return (
<section className='flex w-full text-on-primary bg-primary'>
<div className='flex flex-col gap-10 items-center w-full px-5 mx-auto max-w-screen-xl py-12 lg:py-32'>
<div className='flex w-full flex-col gap-10 lg:items-center lg:flex-row lg:justify-between lg:max-w-5xl'>
<h2 className='text-2xl lg:text-5xl font-black'>Как нас найти</h2>
<button
onClick={() => setMapIsActive((prevState) => !prevState)}
className={`w-max uppercase font-light rounded-lg hover:brightness-110 border border-on-primary px-5 py-4 transition-all duration-200 ease-in-out ${
mapIsActive ? 'bg-secondary' : 'bg-primary'
}`}
>
{mapIsActive ? 'Деактивировать карту' : 'Активировать карту'}
</button>
</div>
<div className='flex w-full max-w-5xl min-h-[440px] relative'>
<div className='flex w-full lg:absolute inset-0'>
<div className={`${mapIsActive ? '' : 'inset-0 '} absolute bg-transparent z-10`}></div>
<iframe
src='https://yandex.ru/map-widget/v1/?um=constructor%3A6b1f8fbb9bf255844f029b89d95fa5bf5c98e6d7f5991c1de8d2f36e385c5975&source=constructor'
width='100%'
height='100%'
className={`${mapIsActive ? '' : 'saturate-0'}`}
></iframe>
</div>
</div>
</div>
</section>
);
}
Сразу скажу про часть кода с mounted:
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
if (!mounted) return null;
Это необходимо для того, чтобы интерактив был доступен только после полной загрузки компонента, можно обойтись и без этого, но мне так привычнее.
Проблема интерактивных карт
Проблема всех интерактивных карт в том, что при скролле или прокрутке на телефоне или в браузере активируется режим масштабирования карты, вы наверняка с этим сталкивались, когда застревали на какой-либо секции с такой картой.
Я предлагаю решить эту проблему в корне, просто добавив невидимый слой поверх карты, который мы будем вручную включать и отключать по клику на соответствующую кнопку.
Я использую состояние mapIsActive для управления доступностью карты, нажимая кнопку «Активировать карту», мы уменьшаем размер блока с абсолютным позиционированием и делаем доступным блок с картой, визуально это отображается как на самой кнопке, которая теперь называется «Деактивировать карту», а сама карта становится цветной.
Таким простым способом я пользуюсь уже достаточно давно.
Не забудьте в самом iframe проставить ширину и высоту на 100%.
Яндекс Карты используют cookies в своей работе, а это значит, что нам необходимо поставить плашку с предупреждением пользователя об этом, в дальнейших уроках я вернусь к этой теме и покажу, как это сделать.
Рефакторинг page.jsx
Для начала добавим в начало кода строчку ( 'use client'; ), указывающую на то, что этот компонент и все его дочерние компоненты являются клиентскими, в Map.jsx мы будем использовать хуки UseState и UseEffect, а они работают только на клиенте.
Также импортируем и добавим в наш шаблон созданный компонент Map.jsx.
Содержимое файла page.jsx
'use client';
import About from './components/sections/About';
import Catalogue from './components/sections/Catalogue';
import Gallery from './components/sections/Gallery';
import Hero from './components/sections/Hero';
import Map from './components/sections/Map';
import WhyUs from './components/sections/WhyUs';
export default function Home() {
return (
<main>
<Hero />
<About />
<Gallery />
<WhyUs />
<Catalogue />
<Map />
</main>
);
}
В dev-режиме, мы получим вот такой блок нашего сайта:
На сегодня всё!
В следующей статье мы сверстаем последнюю секцию нашего лендинга — Footer.
Код данного урока доступен в репозитории GitHub по ссылке.
Не забудь подписаться на канал, а также заходи на мой блог blog.in9var.ru, а также можешь посетить мой основной сайт — in9var.ru.