Skip to content

Commit

Permalink
Merge pull request #55 from tatsuz0u/develop
Browse files Browse the repository at this point in the history
feat: Zooming images from touch point
  • Loading branch information
tatsuz0u authored Sep 10, 2021
2 parents 0384323 + 7612d05 commit 8255583
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
types: [closed]
env:
DEVELOPER_DIR: /Applications/Xcode_13.0.app
APP_VERSION: '1.0.6'
APP_VERSION: '1.1.0'
SCHEME_NAME: 'EhPanda'
BUILDS_PATH: '/tmp/action-builds'
ARCHIVE_PATH: '/tmp/action-builds/EhPanda.xcarchive'
Expand Down
2 changes: 2 additions & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ disabled_rules:

identifier_name:
excluded:
- x
- y
- id
- no

Expand Down
23 changes: 23 additions & 0 deletions EhPanda/App/EhPandaApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ private extension EhPandaApp {
configureWebImage()
configureDomainFronting()
}
addTouchHandler()
configureLogging()
fetchTagTranslator()
fetchIgneousIfNeeded()
Expand Down Expand Up @@ -87,6 +88,15 @@ private extension EhPandaApp {

// MARK: Configuration
private extension EhPandaApp {
func addTouchHandler() {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
let tapGesture = UITapGestureRecognizer(
target: self, action: nil
)
tapGesture.delegate = TouchHandler.shared
keyWindow?.addGestureRecognizer(tapGesture)
}
}
func configureLogging() {
var file = FileDestination()
var console = ConsoleDestination()
Expand Down Expand Up @@ -153,3 +163,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
supportedInterfaceOrientationsFor window: UIWindow?
) -> UIInterfaceOrientationMask { AppDelegate.orientationLock }
}

final class TouchHandler: NSObject, UIGestureRecognizerDelegate {
static let shared = TouchHandler()
var currentPoint: CGPoint?

func gestureRecognizer(
_ gestureRecognizer: UIGestureRecognizer,
shouldReceive touch: UITouch
) -> Bool {
currentPoint = touch.location(in: touch.window)
return false
}
}
1 change: 1 addition & 0 deletions EhPanda/App/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ extension Dictionary where Key == String, Value == String {
}
}

// Enables fullscreen swipe back gesture
extension UINavigationController: UIGestureRecognizerDelegate {
override open func viewDidLoad() {
super.viewDidLoad()
Expand Down
48 changes: 30 additions & 18 deletions EhPanda/View/Reading/ReadingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ struct ReadingView: View, StoreAccessor, PersistenceAccessor {
@State private var sliderValue: Float = 1
@State private var sheetState: ReadingViewSheetState?

@State private var scaleAnchor: UnitPoint = .center
@State private var scale: CGFloat = 1
@State private var baseScale: CGFloat = 1
@State private var offset: CGSize = .zero
Expand Down Expand Up @@ -193,12 +194,10 @@ struct ReadingView: View, StoreAccessor, PersistenceAccessor {
ZStack {
backgroundColor.ignoresSafeArea()
conditionalList
.scaleEffect(scale).offset(offset)
.transition(opacityTransition)
.gesture(tapGesture)
.gesture(dragGesture)
.gesture(magnifyGesture)
.ignoresSafeArea()
.scaleEffect(scale, anchor: scaleAnchor)
.offset(offset).transition(opacityTransition)
.gesture(tapGesture).gesture(dragGesture)
.gesture(magnifyGesture).ignoresSafeArea()
ControlPanel(
showsPanel: $showsPanel,
sliderValue: $sliderValue,
Expand Down Expand Up @@ -550,19 +549,17 @@ private extension ReadingView {
}
}
func onDoubleTap(_: TapGesture.Value) {
syncScaleAnchor()
set(newOffset: .zero)
set(newScale: scale == 1 ? setting.doubleTapScaleFactor : 1)
}

func onDragGestureChanged(value: DragGesture.Value) {
if scale > 1 {
let newX = value.translation.width + newOffset.width
let marginW = windowW * (scale - 1) / 2
let newOffsetW = min(max(newX, -marginW), marginW)

let newY = value.translation.height + newOffset.height
let marginH = windowH * (scale - 1) / 2
let newOffsetH = min(max(newY, -marginH), marginH)
let newOffsetW = fixWidth(x: newX)
let newOffsetH = fixHeight(y: newY)

set(newOffset: CGSize(width: newOffsetW, height: newOffsetH))
}
Expand All @@ -579,6 +576,7 @@ private extension ReadingView {
if value == 1 {
baseScale = scale
}
syncScaleAnchor()
set(newScale: value * baseScale)
}
func onMagnificationGestureEnded(value: MagnificationGesture.Value) {
Expand Down Expand Up @@ -609,17 +607,31 @@ private extension ReadingView {
}
fixOffset()
}
func fixOffset() {
let marginW = windowW * (scale - 1) / 2
let marginH = windowH * (scale - 1) / 2
let currentW = offset.width
let currentH = offset.height
func syncScaleAnchor() {
guard let point = TouchHandler.shared.currentPoint else { return }

let x = min(max(point.x / absWindowW, 0), 1)
let y = min(max(point.y / absWindowH, 0), 1)
scaleAnchor = UnitPoint(x: x, y: y)
}
func fixOffset() {
withAnimation {
offset.width = min(max(currentW, -marginW), marginW)
offset.height = min(max(currentH, -marginH), marginH)
offset.width = fixWidth(x: offset.width)
offset.height = fixHeight(y: offset.height)
}
}
func fixWidth(x: CGFloat) -> CGFloat {
let marginW = absWindowW * (scale - 1) / 2
let leadingMargin = scaleAnchor.x / 0.5 * marginW
let trailingMargin = (1 - scaleAnchor.x) / 0.5 * marginW
return min(max(x, -trailingMargin), leadingMargin)
}
func fixHeight(y: CGFloat) -> CGFloat {
let marginH = absWindowH * (scale - 1) / 2
let topMargin = scaleAnchor.y / 0.5 * marginH
let bottomMargin = (1 - scaleAnchor.y) / 0.5 * marginH
return min(max(y, -bottomMargin), topMargin)
}
}

// MARK: ImageContainer
Expand Down

0 comments on commit 8255583

Please sign in to comment.