Skip to content

Скрытие маркеров вне зоны видимости

html
<yandex-map
    :height="height"
    :settings="{
        location: {
            center,
            zoom,
        },
        zoomRange: ZOOM_RANGE,
        theme,
        showScaleInCopyrights: true,
    }"
    :width="width"
>
    <yandex-map-default-scheme-layer/>
    <yandex-map-default-features-layer/>
    <yandex-map-controls :settings="{ position: 'right' }">
        <yandex-map-zoom-control/>
    </yandex-map-controls>
    <yandex-map-controls :settings="{ position: 'top left' }">
        <yandex-map-control-button>
            <label>
                hideOutsideViewport: true

                <input
                    v-model="mode"
                    name="mode"
                    type="radio"
                    :value="true"
                >
            </label>
            <br>
            <label>
                hideOutsideViewport: {extent: size}
                <input
                    v-model="mode"
                    name="mode"
                    type="radio"
                    :value="false"
                >
            </label>
        </yandex-map-control-button>
    </yandex-map-controls>
    <yandex-map-marker
        v-for="(p, i) in points"
        :key="i"
        :settings="{ coordinates: p.coordinates, hideOutsideViewport: mode === true ? true : false }"
    >
        <div
            class="marker"
            :style="p.style"
        />
    </yandex-map-marker>
</yandex-map>
ts
import {
    YandexMap,
    YandexMapControlButton,
    YandexMapControls,
    YandexMapDefaultFeaturesLayer,
    YandexMapDefaultSchemeLayer,
    YandexMapMarker,
    YandexMapZoomControl,
} from 'vue-yandex-maps';
import { ref } from 'vue';
import type { LngLat } from '@yandex/ymaps3-types';

const mode = ref(true);
const BOUNDS = [
    [35.25003512499998, 56.24506103566212],
    [39.99612887499998, 55.253693595469706],
];
const MAX_POINT_SIZE = 220;

const [lb, rt] = BOUNDS;
const DELTA = 6;

const EXT_BOUNDS = [
    [lb[0] - DELTA, lb[1] + DELTA],
    [rt[0] + DELTA, rt[1] - DELTA],
];

const ZOOM_RANGE = { min: 9, max: 10 };

const seed = (s: number) => () => {
    s = Math.sin(s) * 10000;
    return s - Math.floor(s);
};

const rnd = seed(10000); // () => Math.random()

const point = (bounds: number[][]) => [
    bounds[0][0] + ((bounds[1][0] - bounds[0][0]) * rnd()),
    bounds[1][1] + ((bounds[0][1] - bounds[1][1]) * rnd()),
];

const getRandomPoints = (count: number) => Array.from({ length: count }, (_, i) => {
    const size = 10 + (rnd() * MAX_POINT_SIZE);

    return {
        coordinates: point(EXT_BOUNDS) as LngLat,
        style: {
            '--point-size': `${ size }px`,
            '--point-bg-color': `hsl(${ i % 365 }deg 50% 50%)`,
        },
        size,
    };
});

const points = getRandomPoints(2000);
css
<style scoped>
.marker {
  width: var(--point-size, 10px);
  aspect-ratio: 1/1;
  border: 1px solid #0e86e6;
  background-color: var(--point-bg-color, #858585);
  border-radius: 50%;
  transform: translate(-50%, -50%);
}
</style>

Сделано с ♥ под лицензией MIT.