Контрол Шторка и другие возможности canvas

В качестве рендерера по умолчанию OpenLayers 3 использует canvas. Это дает нам массу возможностей. Например, сохранение карты в файл png. Или замечательный метод clip, который ограничивает область отрисовки — именно этой функции будет посвящен данный пост.


Вертикальная шторка

osm Первым делом рассмотрим контрол Шторка (Swipe), который используют многие ГИС-системы. Вот пример для ArcGIS, демонстрирующий работу шторки (также на странице есть пример работы контрола Spyglass — Подзорная труба или Увеличительное стекло — который мы тоже рассмотрим). Контрол полезен, когда нужно сравнить два слоя. «Натягивая» один слой на другой можно проверить координатное совпадение двух слоев, не применяя прозрачности. Или сравнить снимок одного и того же местоположения за разные периоды времени.

Создадим простейшую карту с двумя слоями:


    var map = new ol.Map({
      target: 'map'
    });

    var osmLayer = new ol.layer.Tile({
      source: new ol.source.OSM()
    });
    map.addLayer(osmLayer);

    var arcgisImagery = new ol.layer.Tile({
        source: new ol.source.TileArcGISRest({
            url: 'http://server.arcgisonline.com/arcgis/rest/services/ESRI_Imagery_World_2D/MapServer'
        })
    });
    map.addLayer(arcgisImagery);
    
    var view = new ol.View({
      center: [ 4188426.7147939987, 7508764.236877314 ],
      zoom: 12
    });
    map.setView(view);

arcgisImagery — слой, который будет выступать в качестве подопытного. Для того, чтобы изменить область отрисовки, мы воспользуемся событием precompose, которое срабатывает непосредственно перед выводом изображения слоя на canvas.


    // текущее положение мыши - относительно него будут рассчитываться все эффекты
    var currentMousePosition = [0, 0];
    
    map.on('pointermove', function (evt) {
        // запоминаем положение мыши при движении курсора над картой
        currentMousePosition = evt.pixel;
        // необходимо вызывать принудительную отрисовку карты, иначе эффекты не будут обновляться
        map.render();
    });
    
    // обработка события перед отрисовкой слоя
    arcgisImagery.on('precompose', function(event) {
        var ctx = event.context;

        // ограничиваем область по вертикали от левого края до указателя мыши
        ctx.save();
        ctx.beginPath();
        ctx.rect(0, 0, currentMousePosition[0], ctx.canvas.height);
        ctx.clip();
    });

    // сразу после отрисовки слоя возвращаем область отрисовки в начальную форму
    arcgisImagery.on('postcompose', function(event) {
        var ctx = event.context;
        ctx.restore();
    });


Горизонтальная шторка

osm Горизонтальная шторка отличается от вертикальной только одной строчкой кода — теперь ширина остается фиксированной, а высота зависит от указателя мыши (отличающаяся строка подсвечена красным):


    arcgisImagery.on('precompose', function(event) {
        var ctx = event.context;

        ctx.save();
        ctx.beginPath();
        ctx.rect(0, 0, ctx.canvas.width, currentMousePosition[1]);
        ctx.clip();
    });


Квадратное увеличительное стекло

osm Название, конечно, не лучшее, но уж какое есть. Подобного контрола я не встречал, но из-за простоты реализации решил включить в список для разнообразия. Принцип работы тот же, что у Spyglass, но вместо окружности используется квадрат — получается своего рода окно в другой слой:


    arcgisImagery.on('precompose', function(event) {
        var ctx = event.context;

        var x = currentMousePosition[0];
        var y = currentMousePosition[1];

        // отображаем квадрат 100х100 с центром в текущих координатах мыши        
        ctx.save();
        ctx.beginPath();
        ctx.rect(x - 100, y - 100, 200, 200);
        ctx.clip();
    });


Увеличительное стекло

osm Контрол Spyglass в его классическом понимании. Это еще один инструмент наряду со шторкой для сравнения двух слоев. Является предпочтительным контролом, когда нужно «подсмотреть» сравнительно небольшие области — в этом случае разбиение всего слоя на две части будет не таким удобным.


    arcgisImagery.on('precompose', function(event) {
        var ctx = event.context;

        var x = currentMousePosition[0];
        var y = currentMousePosition[1];
        
        ctx.save();
        ctx.beginPath();
        // область просмотра - окружность с радиусом 100
        ctx.arc(x, y, 100, 0, 2 * Math.PI);
        // устанавливаем белую границу
        ctx.lineWidth = 6;
        ctx.strokeStyle = 'rgba(255,255,255,0.75)';
        ctx.stroke();
        ctx.clip();
    });


Звезда

osm Напоследок я оставил практически бесполезный, но весьма интересный функционал — вывод слоя в форме звезды. Причем звезда будет не жестко задана, а зависеть от параметров — количества углов, внешнего и внутреннего радиуса (что позволяет управлять длиной «шипов»). Функция для рисования звезды называется drawStar и принимает следующие параметры:

  • ctx — контекст элемента canvas
  • cx — центр в пикселях по x (координата курсора)
  • cy — центр в пикселях по y (координата курсора)
  • spikes — количество шипов
  • outerRadius — внешний радиус, пиксели
  • innerRadius — внутренний радиус, пиксели


    function drawStar(ctx, cx, cy, spikes, outerRadius, innerRadius) {
        var rot = Math.PI / 2 * 3;
        var x = cx;
        var y = cy;
        var step = Math.PI / spikes;

        ctx.beginPath();
        ctx.moveTo(cx, cy - outerRadius)
        for (var i = 0; i < spikes; i++){
            x = cx + Math.cos(rot) * outerRadius;
            y = cy + Math.sin(rot) * outerRadius;
            ctx.lineTo(x, y)
            rot += step

            x = cx + Math.cos(rot) * innerRadius;
            y = cy + Math.sin(rot) * innerRadius;
            ctx.lineTo(x, y);
            rot += step;
        }
        ctx.lineTo(cx, cy - outerRadius);
        ctx.closePath();
        ctx.clip();
    }

    arcgisImagery.on('precompose', function(event) {
        var ctx = event.context;

        var x = currentMousePosition[0];
        var y = currentMousePosition[1];
        
        ctx.save();
        drawStar(ctx, x, y, 7, 40, 70);
    });



И, конечно же, живой пример:




Ссылки:

Контрол Шторка и другие возможности canvas
Метки:    

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *