Comments 7
const distanceNew = Math.hypot(
firstFinger.x - secondFinger.x,
firstFinger.y - secondFinger.y);
// 'distance' variable is previous distance between fingers
const scaleDelta = (distanceNew - distance) * 0.01;
const nextScale = scale + scaleDelta; // 'scale' is previous scale
Что это вообще за формулы? В них есть хоть какой-то математический смысл, или они подбирались пока результат не стал хоть немного напоминать то что нужно?
Вот правильная формула, дающая наиболее интуитивное управление масштабом:
const distanceNew = Math.hypot(
firstFinger.x - secondFinger.x,
firstFinger.y - secondFinger.y);
// 'distance' variable is previous distance between fingers
const nextScale = scale / distance * distanceNew;
Кстати, держите функцию которая сразу считает масштабирование, перемещение и поворот по двум пальцам:
/**
* @param {Point} p1 старая позиция первого пальца
* @param {Point} p2 старая позиция второго пальца
* @param {Point} q1 новая позиция первого пальца
* @param {Point} q2 новая позиция второго пальца
*/
function getMatrix(p1, p2, q1, q2) {
const // межпальцевые вектора
px = p1.x - p2.x, py = p1.y - p2.y,
qx = q1.x - q2.x, qy = q1.2 - q2.y;
const // коэффициенты масштаба и поворота
a = (px * qx + py * qy) / (px * px + py * py),
b = (qx * py - px * qy) / (px * px + py * py);
const // коэффициенты перемещения
e = q1.x - a * p1.x - b * p1.y,
f = q1.y + b * p1.x - a * p1.y;
return new DOMMatrix([a, b, -b, a, e, f]);
}
Этот код возвращает матрицу перехода от старого масштаба к новому, чтобы её применить надо взять текущую матрицу преобразования и домножить на вычисленную.
Но чтобы такой способ работал — надо все преобразования делать только матрицами, никаких svgPositionSet, только ensureTransform.
qy = q1.2 + q2.y ?
может быть так:
qy = q1.y + q2.y ?
Спасибо!
Решал похожую задачу, необходимо было сделать просматривалку планов здания. В итоге уперся в размер svg, они могли быть 50-100мб, возникали тормоза.
Как решение написал сервис на SharpJS, резал картинку на тайлы, для просмотра использовал любые карты - leaflet/mapbox/etc.
JavaScript: Zoom как в картах для SVG/HTML