在Leaflet中旋转标记

时间:2012-11-21 13:45:30

标签: javascript rotation icons marker leaflet

如何在传单中旋转标记?我会有很多标记,都有旋转角度。

我在Leaflet on GitHub尝试了来自 runanet / coomsie 的解决方案,但我的标记没有任何反应:

L.Marker.RotatedMarker= L.Marker.extend({    
    _reset: function() {
        var pos = this._map.latLngToLayerPoint(this._latlng).round();

        L.DomUtil.setPosition(this._icon, pos);
        if (this._shadow) {
            L.DomUtil.setPosition(this._shadow, pos);
        }

        if (this.options.iconAngle) {
            this._icon.style.WebkitTransform = this._icon.style.WebkitTransform + ' rotate(' + this.options.iconAngle + 'deg)';
            this._icon.style.MozTransform = 'rotate(' + this.options.iconAngle + 'deg)';
            this._icon.style.MsTransform = 'rotate(' + this.options.iconAngle + 'deg)';
            this._icon.style.OTransform = 'rotate(' + this.options.iconAngle + 'deg)';
        }

        this._icon.style.zIndex = pos.y;
    },

    setIconAngle: function (iconAngle) {

        if (this._map) {
            this._removeIcon();
        }

        this.options.iconAngle = iconAngle;

        if (this._map) {
            this._initIcon();
            this._reset();
        }
    }

});

var rotated = new L.Marker.RotatedMarker([63.42, 10.39]);
rotated.setIconAngle(90);
rotated.addTo(map);

还有其他想法或解决方案吗? (在Windows上使用Firefox 16进行测试。)

4 个答案:

答案 0 :(得分:8)

按原样运行代码,当您尝试在Firefox中旋转代码时,图标将消失(尝试在鼠标上旋转而不是在加载时旋转,在尝试旋转之前,您会看到图标出现),但是我我愿意打赌它会在webkit浏览器中工作(第一次)。原因是变换线:

this._icon.style.WebkitTransform = this._icon.style.WebkitTransform + ' rotate(' + this.options.iconAngle + 'deg)';
this._icon.style.MozTransform = 'rotate(' + this.options.iconAngle + 'deg)';

Firefox也使用CSS变换来定位图标,因此在旋转之前,Moztransform将具有例如“translate(956px,111px)”的值。代码现在的方式,它将用简单的“旋转(90度)”取代它,Firefox将不知道在哪里放置图标。

您希望Moztransform的值为“translate(956px,111px)rotate(90deg)”,因此如果您使用此代码,它将首次运行,就像在webkit中一样。

this._icon.style.MozTransform = this._icon.style.MozTransform  + ' rotate(' + this.options.iconAngle + 'deg)';

但是,它会在下一次旋转时中断,所以你真的需要一次性设置平移和旋转,如下所示:

this._icon.style.MozTransform = L.DomUtil.getTranslateString(pos) + ' rotate(' + this.options.iconAngle + 'deg)';

然后你可以摆脱L.DomUtil.setPosition(this._icon,pos);一开始。

答案 1 :(得分:2)

对我来说非常有效的是添加data-rotate =" [angle]"属性到每个标记。这允许您在必要时在每次刷新时调用以下JQuery语句:

    $('.your-marker-class').each(function () {            
        var deg = $(this).data('rotate') || 0;
        var rotate = 'rotate(' + $(this).data('rotate') + 'deg) scale(0.5,0.5)';
        $(this).css({
            '-webkit-transform': rotate,
            '-moz-transform': rotate,
            '-o-transform': rotate,
            '-ms-transform': rotate,
            'transform': rotate
        });
    });

工作速度非常快,有数百/数千个标记。在互联网上的某个地方发现了这个方法,但似乎也适合在这里分享。

答案 2 :(得分:2)

此解决方案是迄今为止最简单的解决方案:https://github.com/bbecquet/Leaflet.RotatedMarker

注意:它只修改现有标记,允许另外两个选项(rotationAngle和rotationOrigin)。

解决方案非常有效。根据GitHub页面,一个用法示例:

L.marker([48.8631169, 2.3708919], {
    rotationAngle: 45
}).addTo(map);

答案 3 :(得分:1)

如果您使用的是react-leaflet,我将基于这个想法(https://github.com/bbecquet/Leaflet.RotatedMarker)创建一个React组件,该组件扩展Marker并接受rotation和rotationOrigin作为道具。

// Libs
import L from 'leaflet'

// Components
import { ExtendableMarker } from 'react-leaflet-extendable'

// HOCS
import { withLeaflet } from 'react-leaflet'

const proto_setPos = L.Marker.prototype._setPos

const LeafletMarker = L.Marker.extend({
  _setPos(pos: [number, number]) {
    proto_setPos.call(this, pos)
    this._setRotation(this.options.rotation)
  },
  _setRotation(rotation: number | null | undefined) {
    if (typeof rotation === 'number') {
      this._icon.style[L.DomUtil.TRANSFORM + 'Origin'] = this.options.rotationOrigin || 'center'
      const transform = this._icon.style[L.DomUtil.TRANSFORM] + ` rotate(${rotation}deg)`
      this._icon.style[L.DomUtil.TRANSFORM] = transform
    }
  },
})

const createRotatedMarker = (pos: [number, number], options: any) => {
  return new LeafletMarker(pos, options)
}

class RotatedMarker extends ExtendableMarker {
  public createLeafletElement() {
    return createRotatedMarker(this.props.position, { ...this.props })
  }
}

export default withLeaflet(RotatedMarker)