|
|
|
@ -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
|
|
|
|
|