прямая манипуляция

я сделал маленький пример прямой манипуляции объектом с использованием мультитача, потому что не нашёл общий язык с hammer.js. Зато теперь я знаю, как это работает. В правильных реализациях те точки, за которые вы «ухватили» объект, остаются строго под вашими пальцами по мере движения. Например, если один палец остаётся неподвижен, а другой движется по кругу вокруг него, то объект будет вращаться вокруг «зажатой» точки.

трюк заключается в том, чтобы при перемещении пальцев в новые координаты вычислить такое преобразование объекта, которое перенесёт в эти координаты зажатые первыми точки. Можно попробовать задать такое преобразование при помощи операторов CSS transform translate, scale и rotate, но вычислять для них значения будет неудобно. Зато надёжно сработает метод с использованием матрицы, хотя и тут без вычислений не обойтись. Удивительно, что готовых формул в интернете мне найти не удалось, и пришлось самому вспоминать линейную алгебру, операции с матрицами, и решение систем линейных уравнений. Имея новые координаты S1 и S2, матрица для переноса точек I1 и I2 к этим координатам вычисляется так:

var a = ((S1.x - S2.x) * (I1.x - I2.x) + (S1.y - S2.y) * (I1.y - I2.y)) / 
  (Math.pow(I1.y - I2.y, 2) + Math.pow(I1.x - I2.x, 2));
var c = ((S1.y - S2.y) - a * (I1.y - I2.y)) / (I1.x - I2.x);
var tx = S1.x - a * I1.x + c * I1.y;
var ty = S1.y - c * I1.x - a * I1.y;

return new Matrix([
    [a, -c, tx],
    [c,  a, ty],
    [0,  0,  1]
]);

а дальше всё просто: при первых касаниях мы запоминаем точки объекта, за которые ухватились, и при последующих вычисляем по этому алгоритму матрицу и вставляем её в стиль объекта.

Артемий Трегубенко,
, ,

comments powered by Disqus