Я только что создал относительно сложный пользовательский интерфейс для редактирования изображений в React Native.
Предполагается, что интерфейс будет очень похож на Instagram и имеет функции масштабирования, панорамирования и поворота.
Преобразования хранятся в виде данных, например:
transformation: {
bottomBoundary: 1989,
leftBoundary: 410,
rightBoundary: 1634,
topBoundary: 765,
rotation: 0,
},
Где topBoundary и bottomBoundary - это смещения от верха изображения, а leftBoundary и rightBoundary - оба смещения от левого края изображения.
При повороте, поскольку React Native использует центр объектов в качестве источника преобразования, изображения необходимо смещать, когда они находятся в ориентации 90 ° или 270 °, чтобы они по-прежнему «прилипали» к верхнему / левому углу и могли быть смещены:
CalculRotationOffset.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
}
Что-то в моей реализации поворота и масштабирования не работает вместе.
Чтобы воспроизвести ошибку:
Изображение теперь будет перевернуто и смещено неправильно.
Здесь последовательно происходят как минимум три преобразования, чтобы воспроизвести ошибку, поэтому мне не удалось отследить проблему.
Этот вопрос обязательно будет одобрен, если это необходимо, и я могу также предложить денежное вознаграждение. Спасибо!
Обновлять: После нескольких предложений кажется, что лучший способ решить эту проблему - использовать преобразования матриц, а затем каким-то образом преобразовать эту матрицу обратно в стиль, который RN может отображать на экране. Матричные преобразования должны поддерживать панорамирование, поворот и масштабирование.
@NicoSchertler Я полагаю, что это был бы вариант, но причина, по которой я делаю это таким образом, заключается в том, чтобы как можно проще отскакивать преобразованные изображения от основного изображения с учетом данных преобразования. В частности, используя Cloudinary API. Если у вас есть идея полностью переписанного решения, напишите мне в личку.
Эти виды преобразований зависят от порядка, поэтому проверьте свой код, если вы используете тот же порядок преобразований, что и предполагалось (при редактировании), но, как указал Нико, использование кумулятивной единой унифицированной матрицы 3x3 намного проще и нечестно, чем это. для получения дополнительной информации взгляните на это: Понимание матриц однородного преобразования 4x4 они 3D, поэтому у вас не будет осей Z и координаты Z (матрица 3x3), отбрасываемой (Xz,Yz,Zx,Zy,Zz и один из нулей в столбце Z?)
@Spektre Да, я уже несколько раз видел это, но не понимаю, как это проще.
вместо обработки открытого упорядоченного списка команд преобразования, которые влияют друг на друга, вы применяете или запоминаете только одну матрицу 3x3, несмотря ни на что. нет условий if, что бы то ни было
@Spektre Да, с этой стороны все ясно. Как преобразовать эту матрицу в стиль, понятный RN? Бесплатной карты нет, логика должна быть написана в какой-то момент ...
@IsaacHinman результирующий сдвиг вращения и масштаб могут быть извлечены непосредственно из матрицы, извлекая 2 вектора оси и начало координат ... размер каждого вектора оси дает вам масштаб, вращение в 2D - это простое использование atan2 по оси X, а начало координат - это перевод ...
@Spektre Вы заинтересованы в создании демонстрационного решения для вознаграждения?
@IsaacHinman Я не использую код в среде, которую вы помечаете, поэтому не совсем, но этот Разобрать 2D матрицу преобразования может помочь
@Spektre Если вы доступны для найма, пожалуйста, напишите мне в личку.
@IsaacHinman, мое рабочее время программирования на следующие 10-15 лет уже забронировано. Я кодирую простые вещи здесь как начало или отвлечение перед тем, как приступить к «тяжелым» вещам.
@Spektre Понятно. Спасибо за ваше время, я перечитаю ваши предыдущие комментарии и попытаюсь понять.
Вы проводили модульные тесты отдельных преобразований, а затем комбинации преобразований? Я уверен, что такая библиотека уже должна быть. Пробовали работать от github.com/kiddkai/react-native-gestures?
Мне удалось создать ваше приложение и запустить его. Вы добились прогресса? У вас есть репо?
@Soleil Что именно ты спрашиваешь? Я хочу реорганизовать приложение (как показано в закуске Expo), чтобы использовать более простую систему преобразования матриц. Нет, прогресса и репо нет.
@IsaacHinman Мне не удалось воспроизвести вашу ошибку, все в порядке. Тем не менее, вы теряете сковороду после первого зажима, и она больше не возвращается. Нет проблем, когда мы вращаемся.
Невозможно воспроизвести ошибку, но вам нужен this.pinching = false в handleResponderEnd, иначе вы больше не сможете панорамировать после защемления.
@j_d просто стоит отметить, что React Native уже поддерживает matrix в качестве типа преобразования, поэтому нет необходимости конвертировать обратно - github.com/facebook/react-native/blob/…



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я бы заменил bottomBoundary и т. д. На разложенную матрицу преобразования (поворот, масштаб, перевод) и использовал бы мультитач в пользовательском интерфейсе. Проведя одним пальцем по изображению, вы можете обновить компонент трансляции матрицы, а двумя пальцами трансформировать его так, чтобы изображение прилипало к пальцам. Если вы хотите ограничить вращение шагом в 90 градусов, вы можете привязать его, когда пользователь отпустит. Это позволяет вам свободно и интуитивно перемещаться по изображению, не требуя кнопок текущего поворота.
Хранение матрицы всегда в разложенной форме позволяет избежать ее разложения или нормализации, чтобы избежать накопления числовой неточности (перекоса и изменения соотношения сторон).
Создание нового класса DecomposedMatrix поможет структурировать код. Ключ в том, чтобы преобразовать его примерно так:
scaleBy(scale) {
this.scale *= scale;
this.x *= scale;
this.y *= scale;
}
Это слишком общий вариант, чтобы быть ответом, и он просто повторяет то, что уже было сказано в комментариях к исходному сообщению.
@IsaacHinman полностью меняет пользовательский интерфейс, внутреннюю логику и меняет представление о том, следует ли использовать матрицу преобразования, которая требует преобразования в формат React Native. Таким образом, он не переформулирует ситуацию, а использует совершенно новый подход. Я собирался также добавить образец кода, но передумал ...
@jjrv Тогда, возможно, я прочитал ответ до того, как вы его закончили. Одевают!
Это похоже на обычную проблему, которая возникает, когда вы представляете преобразование с отдельными частями преобразования, которые не следует разделять. Есть ли у вас возможность напрямую установить матрицу и комбинировать разные матрицы? Кстати, я не знаю фреймворка React. Скорее всего, это значительно упростит задачу. Например, смещения также должны вращаться при повороте изображения. Это будет сделано неявно с помощью единственной матрицы и соответствующих операторов.