Создать матричную систему преобразования в React Native?

Я только что построил относительно сложный интерфейс редактирования изображений в React Native.

Опыт должен быть очень похож на Instagram, и имеет функции "зажим", "масштабирование", "панорамирование" и "поворот".

Преобразования сохраняются как данные, например:

transformation: {
  bottomBoundary: 1989,
  leftBoundary: 410,
  rightBoundary: 1634,
  topBoundary: 765,
  rotation: 0,
},

В то время как topBoundary и bottomBoundary являются смещениями от вершины изображения, а leftBoundary и rightBoundary являются смещениями слева от изображения.

При вращении, поскольку React Native использует центр объектов в качестве источника трансформации, изображения должны быть смещены при ориентации 90 ° или 270 °, так что они все еще "липкие" в верхнем/левом углу и могут быть смещены:

calculateRotationOffset.js

export default function (width, height) {
  const transform = [
    { rotate: '${this.rotation}deg' },
  ]

  /*
    RN rotates around centre point, so we need to
    manually offset the rotation to stick the image
    to the top left corner so that our offsets will
    work.
  */
  if (this.rotation === 90) {
    transform.push(
      { translateX: -((width - height) / 2) },
      { translateY: -((width - height) / 2) },
    )
  } else if (this.rotation === 270) {
    transform.push(
      { translateX: ((width - height) / 2) },
      { translateY: ((width - height) / 2) },
    )
  }
  return transform
}

Что-то о моей реализации ротации и масштабирования не работает вместе.

Вот полный пример закуски. ,

Чтобы воспроизвести ошибку:

  1. Поверните изображение один раз
  2. Pinch для увеличения или уменьшения масштаба
  3. Поверните изображение снова

Теперь изображение будет перевернуто и смещено неправильно.

Для воспроизведения ошибки существует не менее трех преобразований, поэтому я не смог отслеживать эту проблему.

Этот вопрос, безусловно, будет вознагражден в случае необходимости, и я также могу предложить денежное вознаграждение. Спасибо!

Обновление. После нескольких предложений кажется, что лучший способ решить эту проблему - преобразование матриц, а затем каким-то образом преобразовать эту матрицу обратно в стиль, который RN может отображать на экране. Матричные преобразования должны поддерживать панорамирование, поворот и масштабирование.

Ответ 1

Я бы заменил bottomBoundary и т.д. bottomBoundary разложенного преобразования (поворот, масштаб, перевод) и использовал мультитач в пользовательском интерфейсе. При перемещении одного пальца по изображению вы можете обновить компонент перевода матрицы и двумя пальцами трансформировать его так, чтобы изображение выглядело на пальцах. Если вы хотите ограничить вращение до 90 градусов, вы можете щелкнуть его, когда пользователь отпустит. Это позволяет свободно перемещаться и интуитивно перемещаться внутри изображения без необходимости использования кнопок поворота.

Хранение матрицы всегда в разложенной форме позволяет избежать ее разложения или нормализации, чтобы избежать накопления числовой погрешности (искажения и изменения соотношения сторон).

Создание нового класса DecomposedMatrix поможет структурировать код. Ключ состоит в том, чтобы обрабатывать его примерно так:

scaleBy(scale) {
    this.scale *= scale;
    this.x *= scale;
    this.y *= scale;
}