Я создал панорамируемое и масштабируемое img с помощью d3.js (нашел шаблон и настроил его под свои нужды). Хорошо работает на настольном компьютере, однако на мобильном устройстве (браузер Android на Samsung S4) панорамирование и масштабирование не ограничиваются изображением внутри svg, но поведение браузера по умолчанию также действует: полная страница перемещается по экрану и в увеличенном виде. Я попытался применить изменения, рекомендуемые здесь: Поведение D3 панорамирования / масштабирования не работает на мобильном Safari (прямоугольник), но безуспешно. Код в действии:
http://webentwicklung.ulrichbangert.de/panzoomimg.html
Код:
var widthSvg = 400, // width of viewport
heightSvg = 300, // heigt of viewport
widthImg = 1300, // width of image
heightImg = 910, // height of image
srcImg = "images/2019-04-15_Iris_barbata nana_White_Gem_(1920).jpg";
// then, create your svg element and a <g> container
// for all of the transformed content
var svg = d3.select("body").append("svg")
.attr("width", widthSvg)
.attr("height", heightSvg)
// .style("background-color", randomColor),
g = svg.append("g");
g.append("image")
.attr("width", widthImg + "px")
.attr("height", heightImg + "px")
.attr("x", "0px")
.attr("y", "0px")
.attr("xlink:href", srcImg)
.style("pointer-events", "none");
var rect = svg.append("rect")
.attr("width", widthSvg + "px")
.attr("height", heightSvg + "px")
.style("fill", "none")
.style("pointer-events", "all");
// then, create the zoom behvavior
var zoom = d3.behavior.zoom()
.scaleExtent([0.1, 1])
.on("zoom", function () {
// the "zoom" event populates d3.event with an object that has
// a "translate" property (a 2-element Array in the form [x, y])
// and a numeric "scale" property
var e = d3.event,
// now, constrain the x and y components of the translation by the
// dimensions of the viewport
tx = Math.min(0, Math.max(widthSvg - widthImg * e.scale, e.translate[0])),
ty = Math.min(0, Math.max(heightSvg - heightImg * e.scale, e.translate[1]));
// then, update the zoom behavior's internal translation, so that
// it knows how to properly manipulate it on the next movement
zoom.translate([tx, ty]);
// and finally, update the <g> element's transform attribute with the
// correct translation and scale (in reverse order)
g.attr("transform", [
"translate(" + [tx, ty] + ")",
"scale(" + e.scale + ")"
].join(" "));
});
// then, call the zoom behavior on the svg element, which will add
// all of the necessary mouse and touch event handlers.
// remember that if you call this on the <g> element, the even handlers
// will only trigger when the mouse or touch cursor intersects with the
// <g> elements' children!
rect.call(zoom);