summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-02-27 01:02:40 -0800
committerFuwn <[email protected]>2025-02-27 01:02:40 -0800
commitad7b39d62acbc899ad26d2319eea01a62642022d (patch)
tree3dec0fa8d15167ce987c533946779cc3bc5fa010
parentfeat: Development commit (diff)
downloadsora-testing-ad7b39d62acbc899ad26d2319eea01a62642022d.tar.xz
sora-testing-ad7b39d62acbc899ad26d2319eea01a62642022d.zip
feat: Development commit
-rw-r--r--Sora/Views/InteractiveImageView.swift112
1 files changed, 57 insertions, 55 deletions
diff --git a/Sora/Views/InteractiveImageView.swift b/Sora/Views/InteractiveImageView.swift
index dfee98f..e7ddea2 100644
--- a/Sora/Views/InteractiveImageView.swift
+++ b/Sora/Views/InteractiveImageView.swift
@@ -1,8 +1,8 @@
import SwiftUI
-struct InteractiveImageView<ContextMenuContent: View>: View {
+struct InteractiveImageView<MenuItems: View>: View {
let image: Image
- let contextMenu: ContextMenuContent
+ let contextMenu: MenuItems
@State private var screenWidth = 0.0
@State private var screenHeight = 0.0
@State private var currentScale = 1.0
@@ -12,67 +12,69 @@ struct InteractiveImageView<ContextMenuContent: View>: View {
@State private var zoomAnchor: UnitPoint = .center
var body: some View {
- image
- .resizable()
- .scaledToFit()
- .scaleEffect(currentScale, anchor: zoomAnchor)
- .offset(currentOffset)
- .contextMenu { contextMenu }
- .frame(maxWidth: .infinity, maxHeight: .infinity)
- .clipped()
- .background(
- GeometryReader { geometry in
- Color.clear
- .onAppear {
- screenWidth = geometry.size.width
- screenHeight = geometry.size.height
+ Group {
+ image
+ .resizable()
+ .scaledToFit()
+ .contextMenu { if currentScale == 1 { contextMenu } }
+ }
+ .scaleEffect(currentScale, anchor: zoomAnchor)
+ .offset(currentOffset)
+ .frame(maxWidth: .infinity, maxHeight: .infinity)
+ .clipped()
+ .background(
+ GeometryReader { geometry in
+ Color.clear
+ .onAppear {
+ screenWidth = geometry.size.width
+ screenHeight = geometry.size.height
+ }
+ }
+ )
+ .gesture(
+ MagnifyGesture()
+ .onChanged { gesture in
+ withAnimation(.interactiveSpring()) {
+ if previousScale == 1 {
+ zoomAnchor = gesture.startAnchor
}
- }
- )
- .gesture(
- MagnifyGesture()
- .onChanged { gesture in
- withAnimation(.interactiveSpring()) {
- if previousScale == 1 {
- zoomAnchor = gesture.startAnchor
- }
- currentScale = max(previousScale * gesture.magnification, 1)
- }
- }
- .onEnded { _ in
- previousScale = currentScale
+ currentScale = max(previousScale * gesture.magnification, 1)
}
- .simultaneously(
- with: DragGesture(minimumDistance: 0)
- .onChanged { gesture in
- withAnimation(.interactiveSpring()) {
- var newOffset: CGSize = .zero
- let offset = gesture.translation
+ }
+ .onEnded { _ in
+ previousScale = currentScale
+ }
+ .simultaneously(
+ with: DragGesture(minimumDistance: 0)
+ .onChanged { gesture in
+ withAnimation(.interactiveSpring()) {
+ var newOffset: CGSize = .zero
+ let offset = gesture.translation
- newOffset.width = offset.width + previousOffset.width
- newOffset.height = offset.height + previousOffset.height
+ newOffset.width = offset.width + previousOffset.width
+ newOffset.height = offset.height + previousOffset.height
- currentOffset = clampOffset(offset: newOffset)
- }
- }
- .onEnded { _ in
- previousOffset = currentOffset
+ currentOffset = clampOffset(offset: newOffset)
}
- )
- )
- .highPriorityGesture(
- TapGesture(count: 2)
- .onEnded {
- withAnimation {
- currentScale = currentScale == 1 ? 2 : 1
- previousScale = currentScale
- currentOffset = .zero
- previousOffset = .zero
- zoomAnchor = .center
}
+ .onEnded { _ in
+ previousOffset = currentOffset
+ }
+ )
+ )
+ .highPriorityGesture(
+ TapGesture(count: 2)
+ .onEnded {
+ withAnimation {
+ currentScale = currentScale == 1 ? 2 : 1
+ previousScale = currentScale
+ currentOffset = .zero
+ previousOffset = .zero
+ zoomAnchor = .center
}
- )
+ }
+ )
}
private func clampOffset(offset: CGSize = .zero) -> CGSize {