Введение
Как всегда, я поделюсь с вами некоторыми интересными требованиями, возникающими в проекте, и представлю соответствующий процесс реализации.
вот изображение:
Короче говоря, конкретный сценарий приложения требует от нас добавления пользовательского наложения, как показано на рисунке на карте. Процесс реализации разделен на следующие два пункта, которые вам необходимо представить.
- Реализация водной ряби
- Реализация пользовательского оверлея
Реализация водной ряби
Реализация этого требования определенно неотделима от написания собственных оверлеев, поэтому сначала давайте обсудим реализацию анимации водной ряби.
Во-первых, мы видим, что обложка на картинке состоит из красного сердца и водной ряби, где закреплено красное сердце, тогда мы можем прямо написать:
<div class="radar"></div>
.radar {
width: 40px;
height: 40px;
border-radius: 50%;
background-color: red;
}
Из рисунка видно, что в общей сложности имеется три водные ряби, которые постепенно распространяются изнутри наружу. Если мы посмотрим только на водную рябь, на самом деле, принцип внешней диффузии заключается в постепенном увеличении ширины и высоты водной ряби до определенной степени с помощью анимации. Насколько велика конкретная диффузия? Читатели могут установить окончательную ширину и высота ряби воды в соответствии с их собственными потребностями. . Базовая структура и стиль водной ряби реализованы следующим образом:
<div class="radar">
<div class="ripple"></div>
<div class="ripple"></div>
<div class="ripple"></div>
</div>
.radar {
width: 40px;
height: 40px;
border-radius: 50%;
background-color: red;
position: relative;
.ripple {
width: 40px;
height: 40px;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
border: 1px solid red;
animation: ripple 2s linear infinite;
}
}
Причина, по которой узел dom водной ряби вложен в радарный узел, в основном состоит в том, чтобы сделать позиционирование «абсолютным отцом ребенка» для достижения эффекта центрирования и выравнивания водной ряби, что должно быть легко понять. Что касается начальной ширины и высоты водной ряби, то для облегчения расчета времени задержки анимации я установил ее равной ширине и высоте красного сердца.Если читателям интересно, вы можете попробовать установить ширину и высоту до любого значения от 0 до 40 пикселей, чтобы увидеть эффект (Анимация слепого предположения автора может быть немного ошибочной, и это может быть не ------> "ручная собачья голова")).
Что касается реализации анимации, то это очень просто.Нам нужно только постепенно увеличивать ширину и высоту водной ряби одновременно, но следует отметить, что водная рябь со временем исчезнет.Здесь мы используем непрозрачность: 0 взаимодействует с анимацией для достижения эффекта постепенного исчезновения.
@keyframes ripple {
to {
width: 150px;
height: 150px;
opacity: 0;
}
}
Код здесь, мы поняли водную рябь, но неужели чего-то не хватает? А как насчет трех рябей на воде?
Эту проблему также легко решить, нам нужно только установить соответствующую задержку анимации для водной ряби.
.radar :nth-child(1) {
animation-delay: 0.666s;
}
.radar :nth-child(2) {
animation-delay: 1.322s;
}
Таким образом, мы реализуем водную рябь.
Реализация пользовательского оверлея
На этот раз автор принимает требования Baidu Maps, так как же реализовать пользовательские наложения с помощью Baidu Maps?
Фактически, документ по разработке карты Baidu также очень прямо показывает нам готовый метод пользовательских наложений. Здесь автор немного переписывает метод написания с классом es6, причина та же, официальный кейс можно сослаться наДемонстрация карты Baidu
Пользовательские оверлеи реализуются в три этапа:
- Определите конструктор и наследуйте Overlay
- Инициализировать пользовательское наложение
- рисовать наложение
Определите конструктор и наследуйте Overlay
Согласно официальному веб-сайту: «Прежде всего вам необходимо определить конструктор пользовательского наложения. Вы можете передать некоторые свободные переменные через параметры конструктора. Установите свойство прототипа объекта пользовательского наложения на экземпляр наложения, чтобы наследовать базовый класс оверлея.».
Используя класс es6, мы можем быстро реализовать:
Пройденная точка является координатной позицией, которая используется для последующего расчета положения наложения на карте.
class RadarOverlay extends BMap.Overlay {
constructor(point) {
super();
this.point = point;
}
}
Инициализировать пользовательское наложение
Официальное заявление: «Реализуйте метод инициализации. Когда вызывается метод map.addOverlay, API вызывает этот метод. Когда метод map.addOverlay вызывается для добавления пользовательского наложения, API вызывает метод инициализации объект для инициализации наложения. , в процессе инициализации вам необходимо создать DOM-элементы, необходимые для наложения, и добавить их в соответствующий контейнер карты. Здесь мы выбираем добавить их в контейнер markerPane."
На самом деле смысл, вероятно, в том, что Baidu Map будет вызывать метод инициализации в пользовательском конструкторе оверлея при добавлении оверлея. Этот метод инициализации используется для инициализации оверлея. Он создаст требуемый DOM во время процесса инициализации, поэтому мы собираемся для реализации инициализации в нашем собственном конструкторе (здесь мы используем класс).
Метод официального сайта карты Baidu:
Затем мы определяем метод инициализации в классе в соответствии с требованиями официального сайта. Шаблон хранит элементы DOM, которые нам нужны для инициализации.Здесь узел dom будет иметь еще один родительский узел с className в качестве Radar-Box, чем ссылка выше для реализации водной ряби, потому что мы также можем увидеть официальный пример на официальном сайте. При создании элемента DOM к узлу DOM добавляется стиль position:absolute, но, поскольку положение нашего узла радара является относительным, нам нужно вложить еще один слой узлов DOM в самый внешний слой, чтобы убедиться, что весь DOM расположен относительно карты. Конечно, позиция родительского узла также является абсолютным позиционированием.
initialize(map) {
this._map = map;
const template = `<div class="radar-box">
<div class="radar">
<div class="ripple"></div>
<div class="ripple"></div>
<div class="ripple"></div>
</div>
</div>`;
// 创建文档碎片
const divFragment = document.createRange().createContextualFragment(template);
const div = divFragment.querySelectorAll('.radar-box')[0];
// 将div添加到覆盖物容器中
map.getPanes().markerPane.appendChild(div);
this._div = div;
return div;
}
Таким образом, мы успешно определили метод инициализации в классе.Что касается того, почему div должен быть добавлен в оверлейный контейнер, на официальном сайте также есть следующие инструкции:
Вероятно, это означает, что Baidu Map предоставила нам несколько способов отображения покрытия.Наши пользовательские покрытия на самом деле хранятся под одним из выбранных нами контейнеров для покрытия.Заинтересованные друзья могут узнать о каждом контейнере для мульчи. . .
рисовать наложение
Здесь автор продолжает делать некоторые предложения.Официальное заявление: "Пока что мы только добавили оверлей на карту, но мы не разместили его в правильном положении. Вам нужно установить положение оверлея в метод draw. Всякий раз, когда состояние карты изменяется (например, перемещение положения, изменение уровня), API вызывает метод рисования наложения для пересчета положения наложения. Метод map.pointToOverlayPixel может преобразовывать географические координаты во все положения наложения. Требуется координаты пикселей».
Проще говоря, например, после масштабирования карты метод draw в оверлее будет вызываться снова для пересчета положения оверлея.
Итак, вопрос в том, откуда берется метод рисования?
Таким образом, официальное значение заключается в том, что мы определяем метод рисования в конструкторе пользовательского наложения, в котором мы используем метод map.pointToOverlayPixel карты Baidu Map (используемый для преобразования географических координат в пиксельные координаты) для преобразования географических координат в наложения желаемого пикселя. координаты.
Затем нам просто нужно добавить метод рисования в класс: Среди них this.point — это координатная точка точки в нашем конструкторе, а 40 представляет начальную ширину и высоту всей нашей водной ряби.Читатель может фактически изменить 40 на форму, которой можно передать параметры, такие как this.size, что облегчит последующий код.Поддержка здесь не слишком сложна для интуитивного понимания читателями.
draw() {
// 根据地理坐标转换为像素坐标,并设置给容器
const position = this._map.pointToOverlayPixel(this.point);
this._div.style.left = `${position.x - 40 / 2}px`;
this._div.style.top = `${position.y - 40 / 2}px`;
}
На данный момент весь наш пользовательский класс покрытия реализован, и общая диаграмма кода приведена ниже (здесь 40 заменено на код this.size, который немного удобнее поддерживать):
class RadarOverlay extends BMap.Overlay {
constructor(point, size) {
super();
this.point = point;
this.size = size;
}
initialize(map) {
this._map = map;
const template = `<div class="radar-box">
<div class="radar">
<div class="ripple"></div>
<div class="ripple"></div>
<div class="ripple"></div>
</div>
</div>`;
const divFragment = document.createRange().createContextualFragment(template);
const div = divFragment.querySelectorAll('.radar-box')[0];
map.getPanes().markerPane.appendChild(div);
this._div = div;
return div;
}
draw() {
// 根据地理坐标转换为像素坐标,并设置给容器
const position = this._map.pointToOverlayPixel(this.point);
this._div.style.left = `${position.x - this.size / 2}px`;
this._div.style.top = `${position.y - this.size / 2}px`;
}
}
Использование пользовательских наложений
Теперь, когда у нас есть все реализованные пользовательские оверлеи, первое, что нужно сделать, это, конечно же, использовать их следующим образом:
initMap() {
const map = new BMap.Map(this.$refs.map);
map.centerAndZoom(new BMap.Point(116.404, 39.915), 15);
// 实例化我们要绘制自定义覆盖物的点坐标
const point = new BMap.Point(116.404, 39.915);
// 实例化自定义覆盖物,将坐标点和水波纹的尺寸传进构造函数中
const radar = new RadarOverlay(point, 40);
// 添加自定义覆盖物
map.addOverlay(radar);
}
Эффект показан на рисунке:
Эпилог
Что касается другого содержания создания пользовательских наложений, если вы хотите углубиться, вы можете обратиться к документации Baidu Maps, которая должна быть более подробной, чем автор (собачья голова). Если есть какие-либо проблемы с содержанием статьи, пожалуйста, оставьте сообщение и оставьте сообщение.Я надеюсь общаться с большими парнями из всех слоев общества.Если вам нравится статья автора, не забудьте дать мне это очень важно для меня.
Адрес источника: https://gitee.com/zhao_jiahao/baidu-map-custom-cover