80 lines
2.4 KiB
Swift
80 lines
2.4 KiB
Swift
//
|
|
// PhotoTumbnailView.swift
|
|
// Swipe That Pic
|
|
//
|
|
// Created by Amine Bou on 27/07/2024.
|
|
//
|
|
|
|
import Foundation
|
|
import Photos
|
|
import SwiftUI
|
|
|
|
struct BigPicture: View {
|
|
private var image: Image
|
|
|
|
@State var scale = 1.0
|
|
@State var lastScale = 0.0
|
|
@State var offset: CGSize = .zero
|
|
@State var lastOffset: CGSize = .zero
|
|
|
|
init(image: Image) {
|
|
self.image = image
|
|
}
|
|
|
|
var body: some View {
|
|
GeometryReader { proxy in
|
|
image
|
|
.resizable()
|
|
.scaledToFill()
|
|
.scaleEffect(scale)
|
|
.offset(offset)
|
|
.frame(width: proxy.size.width, height: proxy.size.height)
|
|
.gesture(
|
|
MagnificationGesture(minimumScaleDelta: 0)
|
|
.onChanged({ value in
|
|
withAnimation(.interactiveSpring()) {
|
|
scale = handleScaleChange(value)
|
|
}
|
|
})
|
|
.onEnded({ _ in
|
|
lastScale = scale
|
|
}).simultaneously(
|
|
with: DragGesture(minimumDistance: 0)
|
|
.onChanged({ value in
|
|
withAnimation(.interactiveSpring()) {
|
|
offset = handleOffsetChange(value.translation)
|
|
}
|
|
})
|
|
.onEnded({ _ in
|
|
lastOffset = offset
|
|
})
|
|
|
|
).simultaneously(with: TapGesture(count: 2).onEnded({ Void in
|
|
scale = 1.0
|
|
lastScale = 0.0
|
|
offset = .zero
|
|
lastOffset = .zero
|
|
}))
|
|
)
|
|
|
|
}
|
|
// We'll also make sure that the photo will
|
|
// be square
|
|
.aspectRatio(1, contentMode: .fit)
|
|
|
|
}
|
|
|
|
private func handleScaleChange(_ zoom: CGFloat) -> CGFloat {
|
|
lastScale + zoom - (lastScale == 0 ? 0 : 1)
|
|
}
|
|
|
|
private func handleOffsetChange(_ offset: CGSize) -> CGSize {
|
|
var newOffset: CGSize = .zero
|
|
|
|
newOffset.width = offset.width + lastOffset.width
|
|
newOffset.height = offset.height + lastOffset.height
|
|
|
|
return newOffset
|
|
}
|
|
}
|