diff options
| author | Fuwn <[email protected]> | 2025-06-28 06:35:17 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2025-06-28 06:35:17 -0700 |
| commit | 3c6199d12d58c311632d22d3261da7892d7a8e63 (patch) | |
| tree | c2fbbbaf9c9e98a0955863bdfe3284d8637694f1 /Sora/Views/InteractiveImageView.swift | |
| parent | feat: Development commit (diff) | |
| download | sora-testing-3c6199d12d58c311632d22d3261da7892d7a8e63.tar.xz sora-testing-3c6199d12d58c311632d22d3261da7892d7a8e63.zip | |
feat: Development commit
Diffstat (limited to 'Sora/Views/InteractiveImageView.swift')
| -rw-r--r-- | Sora/Views/InteractiveImageView.swift | 108 |
1 files changed, 61 insertions, 47 deletions
diff --git a/Sora/Views/InteractiveImageView.swift b/Sora/Views/InteractiveImageView.swift index 052e9cd..dafe9b2 100644 --- a/Sora/Views/InteractiveImageView.swift +++ b/Sora/Views/InteractiveImageView.swift @@ -11,7 +11,8 @@ struct InteractiveImageView<MenuItems: View>: View { @State private var previousOffset: CGSize = .zero @State private var zoomAnchor: UnitPoint = .center - var body: some View { + @ViewBuilder + private func primaryImageContent(image: Image) -> some View { Group { image .resizable() @@ -21,60 +22,73 @@ struct InteractiveImageView<MenuItems: View>: View { .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 + } + + @ViewBuilder + private func imageContent(image: Image) -> some View { + if #available(iOS 26.0, *) { + primaryImageContent(image: image) + } else { + primaryImageContent(image: image) + .clipped() + } + } + + var body: some View { + imageContent(image: image) + .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 + } - currentScale = max(previousScale * gesture.magnification, 1) + currentScale = max(previousScale * gesture.magnification, 1) + } } - } - .onEnded { _ in - previousScale = currentScale - } - .simultaneously( - with: (currentScale > 1 ? DragGesture(minimumDistance: 0) : nil) - .onChanged { gesture in - withAnimation(.interactiveSpring()) { - var newOffset: CGSize = .zero - let offset = gesture.translation + .onEnded { _ in + previousScale = currentScale + } + .simultaneously( + with: (currentScale > 1 ? DragGesture(minimumDistance: 0) : nil) + .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) + currentOffset = clampOffset(offset: newOffset) + } } + .onEnded { _ in + previousOffset = currentOffset + } + ) + ) + .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 { |