如何旋转传单中的标记?我会有很多标记,都有旋转角度。
我已经在 GitHub 上的 Leaflet 上尝试了来自 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 进行测试。)
这个解决方案是迄今为止最简单的:https://github.com/bbecquet/Leaflet.RotatedMarker
注意:它仅修改现有标记,允许多两个选项(rotationAngle 和rotationOrigin)。
该解决方案效果非常好。根据 GitHub 页面,有一个使用示例:
L.marker([48.8631169, 2.3708919], {
rotationAngle: 45
}).addTo(map);
按原样运行代码,当您尝试在 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)”。按照现在的代码方式,它将简单地替换为“旋转(90deg)”,并且 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);一开始。
对我来说非常有效的是为每个标记添加 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
});
});
工作速度非常快,可以处理数百/数千个标记。在互联网上的其他帖子中找到了此方法,但似乎也可以在这里分享。
如果您使用react-leaflet,我基于这个想法(https://github.com/bbecquet/Leaflet.RotatedMarker)创建了一个扩展Marker并接受rotation和rotationOrigin作为prop的React组件。
// 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)
对于 React-Leaflet v3+ 集成,您可以使用以下代码来定义自定义旋转标记(在 JSX 中,使用钩子):
import L from 'leaflet';
import { useMap } from 'react-leaflet';
import React from 'react';
const LeafletMarker = L.Marker.extend({
_setPos(pos) {
L.Marker.prototype._setPos.call(this, pos); // Ensure calling the original method
this._setRotation(this.options.rotation);
},
_setRotation(rotation) {
if (typeof rotation === 'number' && this._icon) { // Check if _icon is available
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 = (position, options) => {
return new LeafletMarker(position, options);
};
const RotatedMarker = (props) => {
const map = useMap();
React.useEffect(() => {
const marker = createRotatedMarker(props.position, { ...props });
marker.addTo(map);
return () => {
map.removeLayer(marker);
};
}, [map, props.position, props.rotation, props.rotationOrigin]); // Add dependencies here
return null; // Since we're manually handling the marker, this component doesn't render anything itself
};
export default RotatedMarker;
基于与 bbecquet 的 RotatedMarker 相同的逻辑构建