Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Double rotation is applied to markers if this package is used along with RotatedMarker #117

Open
EpicUsername12 opened this issue Jul 25, 2024 · 0 comments

Comments

@EpicUsername12
Copy link

Explanation

The rotation is applied twice if you're using leaflet-polylinedecorator and leaflet-rotatedmarker.

In the marker HTML that is then generated by Leaflet, we can see the following:

<img ... style="... transform: translate3d(226px, -107px, 0px) rotateZ(179.118deg) rotateZ(179.118deg); ... ">

The rotateZ() is present 2 times.

This is because the package is already reusing the same Marker.include(...) as leaflet-rotatedmarker:

(function() {
// save these original methods before they are overwritten
var proto_initIcon = L.Marker.prototype._initIcon;
var proto_setPos = L.Marker.prototype._setPos;
var oldIE = (L.DomUtil.TRANSFORM === 'msTransform');
L.Marker.addInitHook(function () {
var iconOptions = this.options.icon && this.options.icon.options;
var iconAnchor = iconOptions && this.options.icon.options.iconAnchor;
if (iconAnchor) {
iconAnchor = (iconAnchor[0] + 'px ' + iconAnchor[1] + 'px');
}
this.options.rotationOrigin = this.options.rotationOrigin || iconAnchor || 'center bottom' ;
this.options.rotationAngle = this.options.rotationAngle || 0;
// Ensure marker keeps rotated during dragging
this.on('drag', function(e) { e.target._applyRotation(); });
});
L.Marker.include({
_initIcon: function() {
proto_initIcon.call(this);
},
_setPos: function (pos) {
proto_setPos.call(this, pos);
this._applyRotation();
},
_applyRotation: function () {
if(this.options.rotationAngle) {
this._icon.style[L.DomUtil.TRANSFORM+'Origin'] = this.options.rotationOrigin;
if(oldIE) {
// for IE 9, use the 2D rotation
this._icon.style[L.DomUtil.TRANSFORM] = 'rotate(' + this.options.rotationAngle + 'deg)';
} else {
// for modern browsers, prefer the 3D accelerated version
this._icon.style[L.DomUtil.TRANSFORM] += ' rotateZ(' + this.options.rotationAngle + 'deg)';
}
}
},
setRotationAngle: function(angle) {
this.options.rotationAngle = angle;
this.update();
return this;
},
setRotationOrigin: function(origin) {
this.options.rotationOrigin = origin;
this.update();
return this;
}
});
})();

As you can see in the above code, it's the same code as: https://github.com/bbecquet/Leaflet.RotatedMarker/blob/master/leaflet.rotatedMarker.js

If you are using both packages, it means that the standard leaflet Marker will be replaced by an extension (A) that applies rotation. (by leaflet-rotatedmarker)

And this new extension (A) will be once again extended (B, by leaflet-polylinedecorator) to apply the same rotation.

Now the Marker "class" of leaflet points to B.

And as we can see in the code, the _setPos function always call the "super" function before applying the rotation.

The call chain will be: B -> A -> original Marker

But B and A both applies the rotation, causing the bug.

Another issue is that leaflet-rotatedmarker is also a depedency for this package which makes it so in most settings, you cannot avoid this bug even if you want to rotate markers with PolylineDecorator alone.

Workaround(s)

  • The simplest fix is to divide the rotation angle by 2 and comment why you did so
  • Create your own rotated marker extension, that do not replace the real Marker
  • Manually change the code to handle such cases, but then it creates code that is very hard to maintain
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant