Pull to refresh

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 ?

Разумеется, только всё-таки минус:


const // межпальцевые вектора
        px = p1.x - p2.x, py = p1.y - p2.y, 
        qx = q1.x - q2.x, qy = q1.y - q2.y;

Если что, код я проверял, но я его проверял на C#, а не на Javascript. Вот при переносе с одного языка на другой опечатка и вылезла...

Не очень хорошая идея называть переменную fixedPoint — в контексте информатики сразу лезет посторонний смысл. Тем более, что есть специальный устоявшийся термин — origin.

Спасибо!

Решал похожую задачу, необходимо было сделать просматривалку планов здания. В итоге уперся в размер svg, они могли быть 50-100мб, возникали тормоза.

Как решение написал сервис на SharpJS, резал картинку на тайлы, для просмотра использовал любые карты - leaflet/mapbox/etc.

Sign up to leave a comment.

Articles