152 lines
4.9 KiB
Swift
152 lines
4.9 KiB
Swift
import SwiftUI
|
|
import Bedrock
|
|
|
|
struct ScreenshotCameraPlaceholder: View {
|
|
@Binding var showSettings: Bool
|
|
let ringWidth: CGFloat
|
|
let ringColor: Color
|
|
let ringOpacity: Double
|
|
|
|
init(
|
|
showSettings: Binding<Bool> = .constant(false),
|
|
ringWidth: CGFloat = 70,
|
|
ringColor: Color = .white,
|
|
ringOpacity: Double = 0.7
|
|
) {
|
|
self._showSettings = showSettings
|
|
self.ringWidth = ringWidth
|
|
self.ringColor = ringColor
|
|
self.ringOpacity = ringOpacity
|
|
}
|
|
|
|
private var backgroundImage: UIImage? {
|
|
guard let imageURL = Bundle.main.url(forResource: "image", withExtension: "png") else {
|
|
return nil
|
|
}
|
|
return UIImage(contentsOfFile: imageURL.path)
|
|
}
|
|
|
|
@ViewBuilder
|
|
private func cameraImageLayer(size: CGSize) -> some View {
|
|
if let backgroundImage {
|
|
Image(uiImage: backgroundImage)
|
|
.resizable()
|
|
.scaledToFill()
|
|
.frame(width: size.width, height: size.height, alignment: .center)
|
|
.clipped()
|
|
} else {
|
|
Color.black
|
|
.frame(width: size.width, height: size.height)
|
|
}
|
|
}
|
|
|
|
var body: some View {
|
|
GeometryReader { geometry in
|
|
let size = geometry.size
|
|
ZStack {
|
|
cameraImageLayer(size: size)
|
|
|
|
ringColor
|
|
.opacity(ringOpacity)
|
|
.ignoresSafeArea()
|
|
|
|
cameraImageLayer(size: size)
|
|
.mask {
|
|
RoundedRectangle(cornerRadius: Design.CornerRadius.large)
|
|
.padding(ringWidth)
|
|
}
|
|
|
|
PlaceholderGridOverlay(ringWidth: ringWidth)
|
|
.allowsHitTesting(false)
|
|
|
|
VStack(spacing: 0) {
|
|
HStack {
|
|
Spacer()
|
|
PlaceholderTopButton(
|
|
systemImage: "gearshape.fill",
|
|
accessibilityLabel: "Settings",
|
|
action: { showSettings = true }
|
|
)
|
|
}
|
|
.padding(.top, ringWidth + Design.Spacing.medium)
|
|
.padding(.trailing, Design.Spacing.medium)
|
|
|
|
Spacer()
|
|
|
|
VStack(spacing: Design.Spacing.medium) {
|
|
ZoomControlView(
|
|
zoomFactor: 1.0,
|
|
isCenterStageActive: false
|
|
)
|
|
CaptureButton(action: { })
|
|
.padding(.bottom, Design.Spacing.large)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.ignoresSafeArea()
|
|
.accessibilityIdentifier("screenshot-camera-placeholder")
|
|
.overlay(alignment: .topLeading) {
|
|
Color.clear
|
|
.frame(width: 1, height: 1)
|
|
.accessibilityIdentifier("screenshot-camera-placeholder")
|
|
}
|
|
}
|
|
}
|
|
|
|
private struct PlaceholderTopButton: View {
|
|
let systemImage: String
|
|
let accessibilityLabel: String
|
|
let action: () -> Void
|
|
|
|
var body: some View {
|
|
Button(action: action) {
|
|
Image(systemName: systemImage)
|
|
.font(.title3)
|
|
.foregroundStyle(.white)
|
|
.frame(width: 44, height: 44)
|
|
.background(Color.black.opacity(Design.Opacity.medium), in: Circle())
|
|
.overlay {
|
|
Circle()
|
|
.strokeBorder(Color.white.opacity(Design.Opacity.subtle), lineWidth: Design.LineWidth.thin)
|
|
}
|
|
.shadow(radius: Design.Shadow.radiusSmall)
|
|
}
|
|
.accessibilityLabel(accessibilityLabel)
|
|
}
|
|
}
|
|
|
|
private struct PlaceholderGridOverlay: View {
|
|
let ringWidth: CGFloat
|
|
|
|
var body: some View {
|
|
GeometryReader { geometry in
|
|
let insetRect = CGRect(
|
|
x: ringWidth,
|
|
y: ringWidth,
|
|
width: geometry.size.width - (ringWidth * 2),
|
|
height: geometry.size.height - (ringWidth * 2)
|
|
)
|
|
|
|
Path { path in
|
|
for index in 1...2 {
|
|
let x = insetRect.minX + (insetRect.width * CGFloat(index) / 3)
|
|
path.move(to: CGPoint(x: x, y: insetRect.minY))
|
|
path.addLine(to: CGPoint(x: x, y: insetRect.maxY))
|
|
}
|
|
|
|
for index in 1...2 {
|
|
let y = insetRect.minY + (insetRect.height * CGFloat(index) / 3)
|
|
path.move(to: CGPoint(x: insetRect.minX, y: y))
|
|
path.addLine(to: CGPoint(x: insetRect.maxX, y: y))
|
|
}
|
|
}
|
|
.stroke(Color.white.opacity(Design.Opacity.subtle), lineWidth: Design.LineWidth.thin)
|
|
}
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
ScreenshotCameraPlaceholder(ringWidth: 70.0, ringColor: .white, ringOpacity: 0.7)
|
|
}
|