import SwiftUI import SFSafeSymbols struct CameraView: View { static let cameraImagePadding: CGFloat = 300 private static let circleSize: CGFloat = 180 private var circleSize: CGFloat { CameraView.circleSize } static var circleCropFactor: CGFloat { let fullWidth = UIScreen.main.bounds.width + 2 * cameraImagePadding return circleSize / fullWidth } private let circleStrength: CGFloat = 3 private let circleColor: Color = .green private let captureButtonSize: CGFloat = 110 private let captureButtonHeight: CGFloat = 40 private let captureButtonWidth: CGFloat = 50 private let cancelButtonSize: CGFloat = 75 private let cancelIconSize: CGFloat = 25 @Binding var isPresented: Bool @Binding var image: UIImage? @Binding var capId: Int? @StateObject private var model = ContentViewModel() @EnvironmentObject var database: Database var body: some View { ZStack { FrameView(image: model.frame) .edgesIgnoringSafeArea(.all) .padding(-CameraView.cameraImagePadding) ErrorView(error: model.error) VStack { Spacer() HStack { Spacer() Button(action: dismiss) { Image(systemSymbol: .xmark) .resizable() .frame(width: cancelIconSize, height: cancelIconSize) .padding((cancelButtonSize-cancelIconSize)/2) .background(.thinMaterial) .cornerRadius(cancelButtonSize/2) }.padding() } } VStack { Spacer() HStack { Spacer() Button(action: capture) { Image(systemSymbol: .camera) .resizable() .frame(width: captureButtonWidth, height: captureButtonHeight) .padding(.horizontal, (captureButtonSize - captureButtonWidth)/2) .padding(.vertical, (captureButtonSize - captureButtonHeight)/2) .background(.thinMaterial) .cornerRadius(captureButtonSize / 2) }.padding() Spacer() } } VStack { Spacer() HStack { Spacer() Text("") .frame(width: circleSize, height: circleSize, alignment: .center) .overlay(RoundedRectangle(cornerRadius: circleSize/2) .stroke(lineWidth: circleStrength) .foregroundColor(circleColor)) .background(Color(white: 1, opacity: 0.01)) .onAppear(perform: didTapCircle) Spacer() } Spacer() }.ignoresSafeArea() } .onAppear() { model.startCapture() } .onDisappear { model.endCapture() }.onChange(of: model.image) { image in if let capId = capId, let image = image { database.save(image, for: capId) } else { database.image = image } dismiss() } } private func dismiss() { isPresented = false self.capId = nil } private func capture() { model.captureImage() } private func didTapCircle() { model.continuouslyFocusOnMiddle() } } struct CameraView_Previews: PreviewProvider { static var previews: some View { CameraView(isPresented: .constant(true), image: .constant(nil), capId: .constant(nil)) } }