diff options
| author | Fuwn <[email protected]> | 2025-02-27 01:02:40 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2025-02-27 01:02:40 -0800 |
| commit | ad7b39d62acbc899ad26d2319eea01a62642022d (patch) | |
| tree | 3dec0fa8d15167ce987c533946779cc3bc5fa010 | |
| parent | feat: Development commit (diff) | |
| download | sora-testing-ad7b39d62acbc899ad26d2319eea01a62642022d.tar.xz sora-testing-ad7b39d62acbc899ad26d2319eea01a62642022d.zip | |
feat: Development commit
| -rw-r--r-- | Sora/Views/InteractiveImageView.swift | 112 |
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 { |