I have an application I am developing that allows users to drop "Pins" on an SVG. These pins can be moved around the underlying SVG and the coordinates are saved in a database. The pins also have a "center of mass" of bottom center, I store the coordinates of the tip of the pin, not the 0,0 origin of the pin icon.
I am trying to implement a functionality, that will allow the pins to show larger when zoomed out of the underlying SVG, and scale smaller when zooming in (think google maps, if you look at a zoomed out map of all restaurants and then zoom in, the pins get smaller and more spread out).
I have this feature working on desktop web, see images below
However, on mobile, the same code causes the pins to exist in a different location, and when zooming I can see them scaling down to the top left point, and not the center bottom like the desktop client.
JS Code that is creating the scaling styles and logic:
if (instance) {
instance.dispose();
instance = panzoom($('#partialDiv')[0]);
var pins = Array.from(document.querySelectorAll('.draggable'));
instance.on('transform', function(pz) {
var transform = instance.getTransform();
pins.forEach(pin => {
if (transform.scale > 10 && transform.scale < 18) {
pin.setAttribute("transform", 'matrix('
15 / transform.scale ', 0, 0, '
15 / transform.scale ', '
pin.transform.baseVal[0].matrix.e ', ' pin.transform.baseVal[0].matrix.f ')');
var pinStyle = pin.style;
pin.setAttribute("transform-origin", "" pin.getBBox().width / 2 " " pin.getBBox().height "0px");
pinStyle.transformBox = 'fill-box';
pin.style['-webkit-transform-origin-x'] = '50%';
pin.style['-webkit-transform-origin-y'] = 'bottom';
pinStyle.transformBox = 'fill-box';
} else if (transform.scale > 18) {
pin.setAttribute("transform", 'matrix(0.8, 0, 0, 0.8, '
pin.transform.baseVal[0].matrix.e ', ' pin.transform.baseVal[0].matrix.f ')');
var pinStyle = pin.style;
pin.setAttribute("transform-origin", "" pin.getBBox().width / 2 " " pin.getBBox().height "0px");
pinStyle.transformBox = 'fill-box';
pin.style['-webkit-transform-origin-x'] = '50%';
pin.style['-webkit-transform-origin-y'] = 'bottom';
} else {
pin.setAttribute("transform", 'matrix(2, 0, 0, 2, '
pin.transform.baseVal[0].matrix.e ', ' pin.transform.baseVal[0].matrix.f ')');
var pinStyle = pin.style;
pin.setAttribute("transform-origin", "" pin.getBBox().width / 2 " " pin.getBBox().height "0px");
pinStyle.transformBox = 'fill-box';
pin.style['-webkit-transform-origin-x'] = '50%';
pin.style['-webkit-transform-origin-y'] = 'bottom';
}
});
});
}
Why would the pins be displayed at a different origin on Chrome Desktop vs. Chrome IOS? Same is true for other desktop browsers and Safari on mobile. I have tried variations of webkit styles but it does not seem to change this behavior. Any advice is much appreciated.
CodePudding user response:
After hours of troubleshooting I learned that there is a bug on IOS webkit 16.2 that does not allow transform-origin to work with a transform attribute. Only the transform being performed in CSS will work with a transform-origin style.
Useful resource for anyone having an issue similar to me: https://caniuse.com/mdn-svg_attributes_presentation_transform-origin