Создаем лендинг сайт с нуля: интерактивная яндекс карта #9
Сегодня сделаем секцию Map нашего лендинга. Вставим интерактивную карту Яндекса через iframe.
Полезные ссылки:
- Шаблон лендинга, который мы будем делать, доступен в Figma по ссылке.
- Код данного урока доступен в репозитории GitHub по ссылке.
- Подписывайтесь на мой Дзен канал
Яндекс карты
Для вставки карт на сайт я обычно использую сервис Яндекса — конструктор карт, он доступен по ссылке
Все очень просто:
-
Создаём карту и наносим необходимые метки и маршруты.
-
Копируем сгенерированный код 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 по ссылке.
На этом всё, добавляйте сайт в избранное, чтобы не пропустить новых статей, а также подписывайтесь на мой Дзен-канал – dzen.ru/in9var