Клуб API Карт

Анимация пользовательского слоя

Пост в архиве.

Сделал пользовательский layout через IDomTile.

В renderAt  формируется канвас, который передается на карту.

Проблема в том, что в анимации при зумировании канвасы не тянутся. прыгают из стороны в сторону.

 

пробовал сделать так:

 

  

 

var canvas = controller._model.renderTile.call(controller._model, this.coord, this.zoom);

                this.content = document.createElement('ymaps');

                this.content.style.backgroundSize = '100%';

                this.content.style.position = 'absolute';

                this.content.style.backgroundImage = "url(" + canvas.toDataURL("image/png") + ")";

                this.content.style.height = canvas.style.height;

                this.content.style.width = canvas.style.width;

                if (typeof this.content.style.webkitUserSelect !== 'undefined') {

                    this.content.style.webkitUserSelect = 'none';

                    this.content.style.webkitTransformOrigin = '0px 0px';

                }

                context.appendChild(this.content);

 

 

 

 

 

все равно скачет. помогите, плиз.

http://maps.1cs.su/?mode=4

 

5 комментариев
Sergey Konstantinov
28 января 2016, 04:32

Что Вы пытаетесь сделать и как? Расскажите подробнее.

а как вы вычисляете координаты сдвига canvas при зумировании?

на самом деле там все сложно. 

во первых вешаю на pane, в котором у меня лежит канвас 2 слушателя:

pane = new ymaps.pane.movable.StepwisePane( map, {className:'ymaps-nolan-canvases', zIndex:200});

        pane.events.add('actionend', function () {

           self._draw.call(self);

        });

        pane.events.add('zoomchange', function () {

           self._draw.call(self);

        });

а вот код расчета размеров и положения канваса

this._draw = function () {

        var z = pane.getZoom();

        if (z == map.getZoom()) {

            var c1 = pane.fromClientPixels(bounds[0]),

                c2 = pane.fromClientPixels(bounds[1]),

                k = controller.model.pow2(Math.round(z)),

                globalBounds = [

                    {x:(c1[0] / k), y:(c1[1] / k)},

                    {x:(c2[0] / k), y:(c2[1] / k)}

                ];

            if (oldGlobalBounds == null || !(oldGlobalBounds[0].x == globalBounds[0].x && oldGlobalBounds[0].y == globalBounds[0].y

                && oldGlobalBounds[1].x == globalBounds[1].x && oldGlobalBounds[1].y == globalBounds[1].y)) {

                this._restore();

                model.renderMapCanvas(layout, globalBounds, z);

            }

            oldGlobalBounds = globalBounds;

            zoom = z;

        } else {

            var currentTick = map.action.getCurrentState(),

                currentCenter = currentTick.globalPixelCenter,

                offset = { x: (bounds[1][0] - bounds[0][0]) / 2, y: (bounds[1][1] - bounds[0][1]) / 2},

                k = model.pow2(currentTick.zoom),

                globalBounds = [

                    {x: (currentCenter[0] - offset.x) / k, y: (currentCenter[1] - offset.y) / k},

                    {x: (currentCenter[0] + offset.x) / k, y: (currentCenter[1] + offset.y) / k} ];

                model.renderMapCanvas(layout, globalBounds, currentTick.zoom, true);

        }

 

    };

Я вашу рализацию дёрнул себе) Интересная штука. Но в fullcanvas yandex контроллере(остальное не смотрел) у вас, почему то, не просчитываются координаты смещения карты относительно центра при скролзуме. Маркеры прыгали, допилил этот момент. Если интересно вот мой метод:

            _draw: function() {

                var zoom = this.pane.getZoom(),

                    bounds = this.pane.getViewport(),

                    currentTick = map.action.getCurrentState(),

             currentZoom = currentTick.zoom,

                    top = bounds[0][1],

                    left = bounds[0][0],

                    width = (typeof FlashCanvas == 'undefined') ? bounds[1][0] - bounds[0][0] : 2000,

                    height = (typeof FlashCanvas == 'undefined') ? bounds[1][1] - bounds[0][1] : 2000;

 

                if (Math.round(zoom) == zoom) {

                    

                    var c1 = this.pane.fromClientPixels(bounds[0]),

                        c2 = this.pane.fromClientPixels(bounds[1]),

                        k = this.controller.model.pow2(Math.round(zoom)),

                        globalBounds = [{x: (c1[0] / k), y: (c1[1] / k)}, {x: (c2[0] / k), y: (c2[1] / k)}];

                    this.zoom = zoom;

                    this.layout.width = width;

                    this.layout.height =  height;

                    this.controller.model.renderMapCanvas(this.layout, globalBounds, zoom);

                    

                } else {

var d, dx, dy;

if(zoom > this.zoom){

               d = 1 + zoom-this.zoom;

               dx = this.deltaX*currentTick.tickProgress;

               dy = this.deltaY*currentTick.tickProgress;

               } else {

               d = 1/(1 - zoom + this.zoom);

               dx = - (this.deltaX*currentTick.tickProgress*2);

               dy = - (this.deltaY*currentTick.tickProgress*2);

               }

               

               left = (left - dx) * d;

               top = (top - dy) * d;

               width = width * d;

               height = height * d;

               //console.log(dx, this.deltaX);         

                }

                $(this.layout).css( { left: left  + 'px', top: top + 'px',

                    width : width  + 'px', height:  height +'px'});

            } 



this.deltaX this.deltaY присваиваются при скроле:

 map.events.add('wheel', function(evt) {

this.deltaX = (evt.get('domEvent').get('pageX') - this.cntr[0])/2;

this.deltaY = (evt.get('domEvent').get('pageY') - this.cntr[1])/2;

});

жестко... на самом деле все намного проще.