diff --git a/SignalMessaging/Views/ImageEditor/ImageEditorCropViewController.swift b/SignalMessaging/Views/ImageEditor/ImageEditorCropViewController.swift index 26653ddca..9fb07cf5e 100644 --- a/SignalMessaging/Views/ImageEditor/ImageEditorCropViewController.swift +++ b/SignalMessaging/Views/ImageEditor/ImageEditorCropViewController.swift @@ -516,16 +516,20 @@ class ImageEditorCropViewController: OWSViewController { owsFailDebug("Missing pinchTransform.") return } - guard let locationStart = gestureRecognizer.locationStart else { + guard let oldLocationView = gestureRecognizer.locationStart else { owsFailDebug("Missing locationStart.") return } - let locationNow = gestureRecognizer.location(in: self.clipView) - let locationUnitStart = self.locationUnit(forLocationInView: locationStart, transform: gestureStartTransform) - let locationUnitNow = self.locationUnit(forLocationInView: locationNow, transform: gestureStartTransform) - let locationUnitDelta = CGPointSubtract(locationUnitNow, locationUnitStart) - let newUnitTranslation = CGPointAdd(gestureStartTransform.unitTranslation, locationUnitDelta) + // The beauty of using an SRT (scale-rotate-translation) tranform ordering + // is that the translation is applied last, so it's trivial to convert + // translations from view coordinates to transform translation. + let viewBounds = clipView.bounds + let newLocationView = gestureRecognizer.location(in: self.clipView) + // Our (view bounds == canvas bounds) so no need to convert. + let translation = newLocationView.minus(oldLocationView) + let translationUnit = translation.toUnitCoordinates(viewSize: viewBounds.size, shouldClamp: false) + let newUnitTranslation = gestureStartTransform.unitTranslation.plus(translationUnit) updateTransform(ImageEditorTransform(outputSizePixels: gestureStartTransform.outputSizePixels, unitTranslation: newUnitTranslation, @@ -600,17 +604,19 @@ class ImageEditorCropViewController: OWSViewController { } @objc public func rotate90ButtonPressed() { - rotateButtonPressed(angleRadians: CGFloat.pi * 0.5) + rotateButtonPressed(angleRadians: CGFloat.pi * 0.5, rotateCanvas: true) } @objc public func rotate45ButtonPressed() { - rotateButtonPressed(angleRadians: CGFloat.pi * 0.25) + rotateButtonPressed(angleRadians: CGFloat.pi * 0.25, rotateCanvas: false) } - private func rotateButtonPressed(angleRadians: CGFloat) { - // Invert width and height. - let outputSizePixels = CGSize(width: transform.outputSizePixels.height, - height: transform.outputSizePixels.width) + private func rotateButtonPressed(angleRadians: CGFloat, rotateCanvas: Bool) { + let outputSizePixels = (rotateCanvas + // Invert width and height. + ? CGSize(width: transform.outputSizePixels.height, + height: transform.outputSizePixels.width) + : transform.outputSizePixels) let unitTranslation = transform.unitTranslation let rotationRadians = transform.rotationRadians + angleRadians let scaling = transform.scaling