Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Aspect Ratio setting to resize + crop media #107

Merged
merged 9 commits into from
Apr 12, 2021
Merged
72 changes: 54 additions & 18 deletions Classes/Editor/EditorView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega

weak var playerView: MediaPlayerView?

var exportSize: CGSize {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exports media to the same size we are displaying to the user.

let exportView = playerView ?? self
return CGSize(width: exportView.bounds.width * exportView.contentScaleFactor, height: exportView.bounds.height * exportView.contentScaleFactor)
}

private let mainActionMode: MainActionMode
private let confirmButton = UIButton()
private let closeButton = UIButton()
Expand Down Expand Up @@ -190,10 +195,10 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega
private lazy var drawingCanvasConstraints: FullViewConstraints = {
return FullViewConstraints(
view: drawingCanvas,
top: drawingCanvas.topAnchor.constraint(equalTo: topAnchor),
bottom: drawingCanvas.bottomAnchor.constraint(equalTo: bottomAnchor),
leading: drawingCanvas.leadingAnchor.constraint(equalTo: leadingAnchor),
trailing: drawingCanvas.trailingAnchor.constraint(equalTo: trailingAnchor)
top: drawingCanvas.topAnchor.constraint(equalTo: playerView?.topAnchor ?? topAnchor),
bottom: drawingCanvas.bottomAnchor.constraint(equalTo: playerView?.bottomAnchor ?? bottomAnchor),
leading: drawingCanvas.leadingAnchor.constraint(equalTo: playerView?.leadingAnchor ?? leadingAnchor),
trailing: drawingCanvas.trailingAnchor.constraint(equalTo: playerView?.trailingAnchor ?? trailingAnchor)
)
}()

Expand All @@ -202,10 +207,10 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega
private lazy var movableViewCanvasConstraints = {
return FullViewConstraints(
view: movableViewCanvas,
top: movableViewCanvas.topAnchor.constraint(equalTo: topAnchor),
bottom: movableViewCanvas.bottomAnchor.constraint(equalTo: bottomAnchor),
leading: movableViewCanvas.leadingAnchor.constraint(equalTo: leadingAnchor),
trailing: movableViewCanvas.trailingAnchor.constraint(equalTo: trailingAnchor)
top: movableViewCanvas.topAnchor.constraint(equalTo: playerView?.topAnchor ?? topAnchor),
bottom: movableViewCanvas.bottomAnchor.constraint(equalTo: playerView?.bottomAnchor ?? bottomAnchor),
leading: movableViewCanvas.leadingAnchor.constraint(equalTo: playerView?.leadingAnchor ?? leadingAnchor),
trailing: movableViewCanvas.trailingAnchor.constraint(equalTo: playerView?.trailingAnchor ?? trailingAnchor)
)
}()

Expand All @@ -225,6 +230,7 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega

weak var delegate: EditorViewDelegate?
private var mediaContentMode: UIView.ContentMode
private var aspectRatio: CGFloat?

@available(*, unavailable, message: "use init() instead")
required public init?(coder aDecoder: NSCoder) {
Expand All @@ -242,6 +248,7 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega
showQuickPostButton: Bool,
showBlogSwitcher: Bool,
confirmAtTop: Bool,
aspectRatio: CGFloat?,
quickBlogSelectorCoordinator: KanvasQuickBlogSelectorCoordinating?,
tagCollection: UIView?,
metalContext: MetalContext?,
Expand All @@ -258,6 +265,7 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega
self.showQuickPostButton = showQuickPostButton
self.showBlogSwitcher = showBlogSwitcher
self.confirmAtTop = confirmAtTop
self.aspectRatio = aspectRatio
self.quickBlogSelectorCoordinator = quickBlogSelectorCoordinator
self.tagCollection = tagCollection
self.metalContext = metalContext
Expand Down Expand Up @@ -330,7 +338,35 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega
private func setupPlayer() {
let playerView = MediaPlayerView(metalContext: metalContext, mediaContentMode: mediaContentMode)
playerView.delegate = self
playerView.add(into: self)

if let aspectRatio = aspectRatio {
playerView.layer.masksToBounds = true
playerView.layer.cornerRadius = 12
playerView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(playerView)

let bottomConstraint: NSLayoutConstraint
let topConstraint: NSLayoutConstraint
if Device.belongsToIPhoneXGroup {
bottomConstraint = playerView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor)
topConstraint = playerView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor)
} else {
bottomConstraint = playerView.bottomAnchor.constraint(equalTo: bottomAnchor)
topConstraint = playerView.topAnchor.constraint(equalTo: topAnchor)
}
NSLayoutConstraint.activate([
playerView.centerXAnchor.constraint(equalTo: centerXAnchor),
playerView.leadingAnchor.constraint(greaterThanOrEqualTo: leadingAnchor),
playerView.trailingAnchor.constraint(lessThanOrEqualTo: trailingAnchor),
playerView.widthAnchor.constraint(equalTo: playerView.heightAnchor, multiplier: aspectRatio, constant: 0),
topConstraint,
bottomConstraint,
playerView.bottomAnchor.constraint(lessThanOrEqualTo: bottomAnchor)
])
} else {
playerView.add(into: self)
}

self.playerView = playerView
}

Expand Down Expand Up @@ -523,7 +559,7 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega

let verticalPositioning: [NSLayoutConstraint]
if confirmAtTop {
verticalPositioning = [collectionContainer.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor)]
verticalPositioning = [collectionContainer.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor, constant: -KanvasEditorDesign.shared.editorViewButtonBottomMargin)]
} else {
verticalPositioning = [collectionContainer.centerYAnchor.constraint(equalTo: confirmOrPostButton().centerYAnchor)]
}
Expand Down Expand Up @@ -563,10 +599,10 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega

addSubview(textMenuContainer)
NSLayoutConstraint.activate([
textMenuContainer.leadingAnchor.constraint(equalTo: leadingAnchor),
textMenuContainer.trailingAnchor.constraint(equalTo: trailingAnchor),
textMenuContainer.topAnchor.constraint(equalTo: topAnchor),
textMenuContainer.bottomAnchor.constraint(equalTo: bottomAnchor)
textMenuContainer.leadingAnchor.constraint(equalTo: playerView?.leadingAnchor ?? leadingAnchor),
textMenuContainer.trailingAnchor.constraint(equalTo: playerView?.trailingAnchor ?? trailingAnchor),
textMenuContainer.topAnchor.constraint(equalTo: playerView?.topAnchor ?? topAnchor),
textMenuContainer.bottomAnchor.constraint(equalTo: playerView?.bottomAnchor ?? bottomAnchor)
])
}

Expand All @@ -578,10 +614,10 @@ final class EditorView: UIView, MovableViewCanvasDelegate, MediaPlayerViewDelega
addSubview(drawingMenuContainer)
drawingMenuContainer.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
drawingMenuContainer.leadingAnchor.constraint(equalTo: leadingAnchor),
drawingMenuContainer.trailingAnchor.constraint(equalTo: trailingAnchor),
drawingMenuContainer.topAnchor.constraint(equalTo: topAnchor),
drawingMenuContainer.bottomAnchor.constraint(equalTo: bottomAnchor)
drawingMenuContainer.leadingAnchor.constraint(equalTo: playerView?.leadingAnchor ?? leadingAnchor),
drawingMenuContainer.trailingAnchor.constraint(equalTo: playerView?.trailingAnchor ?? trailingAnchor),
drawingMenuContainer.topAnchor.constraint(equalTo: playerView?.topAnchor ?? topAnchor),
drawingMenuContainer.bottomAnchor.constraint(equalTo: playerView?.bottomAnchor ?? bottomAnchor)
])
}

Expand Down
4 changes: 3 additions & 1 deletion Classes/Editor/EditorViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ public final class EditorViewController: UIViewController, MediaPlayerController
showQuickPostButton: settings.showQuickPostButtonInEditor,
showBlogSwitcher: settings.showBlogSwitcherInEditor,
confirmAtTop: settings.features.editorConfirmAtTop,
aspectRatio: settings.aspectRatio,
quickBlogSelectorCoordinator: quickBlogSelectorCoordinator,
tagCollection: tagCollection,
metalContext: metalContext,
Expand Down Expand Up @@ -812,7 +813,8 @@ public final class EditorViewController: UIViewController, MediaPlayerController
}

private var exportSize: CGSize? {
return settings.features.scaleMediaToFill ? CGSize(width: editorView.frame.width * editorView.contentScaleFactor, height: editorView.frame.height * editorView.contentScaleFactor) : nil
let exportSize = editorView.exportSize
return settings.features.scaleMediaToFill ? exportSize : nil
}

private func createFinalGIF(segments: [CameraSegment], mediaInfo: MediaInfo, archive: Data, exportAction: KanvasExportAction) {
Expand Down
7 changes: 6 additions & 1 deletion Classes/Editor/Text/EditorTextController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,12 @@ final class EditorTextController: UIViewController, EditorTextViewDelegate, Colo
@objc func keyboardWillShow(notification: NSNotification) {
if let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue {
let keyboardRectangle = keyboardFrame.cgRectValue
textView.moveToolsUp(distance: keyboardRectangle.height)

let bottom = CGPoint(x: view.frame.minX, y: view.frame.maxY)
let difference = keyboardRectangle.maxY - view.convert(bottom, to: nil).y

let heightDiff = keyboardRectangle.height - difference
textView.moveToolsUp(distance: heightDiff)
}
}

Expand Down
3 changes: 3 additions & 0 deletions Classes/Settings/CameraSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,9 @@ public struct CameraFeatures {
/// The Font Selector button uses the currently selected font for its label
public var fontSelectorUsesFont: Bool = DefaultCameraSettings.fontFamilyUsesFont

/// The aspect ratio to pin the Editor View to
public var aspectRatio: CGFloat? = nil

override public init() { }

}
Expand Down
2 changes: 1 addition & 1 deletion Kanvas.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |spec|
spec.name = "Kanvas"
spec.version = "1.2.5"
spec.version = "1.2.6"
spec.summary = "A custom camera built for iOS."
spec.homepage = "https://github.com/tumblr/kanvas-ios"
spec.license = "MPLv2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ final class EditorViewTests: FBSnapshotTestCase {
showQuickPostButton: false,
showBlogSwitcher: false,
confirmAtTop: false,
aspectRatio: nil,
quickBlogSelectorCoordinator: nil,
tagCollection: nil,
metalContext: nil,
Expand Down
4 changes: 2 additions & 2 deletions KanvasExample/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ PODS:
- FBSnapshotTestCase/Core (2.1.4)
- FBSnapshotTestCase/SwiftSupport (2.1.4):
- FBSnapshotTestCase/Core
- Kanvas (1.2.3)
- Kanvas (1.2.6)

DEPENDENCIES:
- FBSnapshotTestCase (= 2.1.4)
Expand All @@ -20,7 +20,7 @@ EXTERNAL SOURCES:

SPEC CHECKSUMS:
FBSnapshotTestCase: 094f9f314decbabe373b87cc339bea235a63e07a
Kanvas: 97860c54ea07119c533a80d951ee8c1b39d8f386
Kanvas: 828033a062a8df8bd73e6efd1a09ac438ead4b41

PODFILE CHECKSUM: 14b28dd726149c0d01dba9154d5bb095d9ba6a18

Expand Down