| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- import SwiftUI
- // MARK: - PulsingRecordButton
- /// A minimalist, line-drawn record button suitable for a business productivity app.
- /// Completely avoids heavy neon glows, replacing them with thin outlines, a clean scale animation,
- /// and an outline mic icon.
- struct PulsingRecordButton: View {
- /// Closure triggered on tap.
- let action: () -> Void
- /// Controls the subtle pulse animation.
- @State private var isAnimating: Bool = false
- var body: some View {
- ZStack {
- // Precise outer thin outline (pulses slightly)
- Circle()
- .stroke(Color.primary.opacity(0.1), lineWidth: 1)
- .frame(width: 120, height: 120)
- .scaleEffect(isAnimating ? 1.08 : 0.98)
- .animation(
- .easeInOut(duration: 2.0).repeatForever(autoreverses: true),
- value: isAnimating
- )
-
- // Middle thin outline (expanding and fading pulse)
- Circle()
- .stroke(Color.primary.opacity(0.08), lineWidth: 1)
- .frame(width: 100, height: 100)
- .scaleEffect(isAnimating ? 1.25 : 1.0)
- .opacity(isAnimating ? 0.0 : 0.8)
- .animation(
- .easeOut(duration: 2.5).repeatForever(autoreverses: false),
- value: isAnimating
- )
- // Inner button body - pure line circle with translucent background
- Circle()
- .fill(Color.primary.opacity(0.03))
- .frame(width: 90, height: 90)
- .overlay(
- Circle()
- .stroke(Color.primary.opacity(0.2), lineWidth: 1)
- )
-
- // Inner core indicator - simple line microphone icon
- Image(systemName: "mic")
- .font(.system(size: 24, weight: .light))
- .foregroundColor(.primary)
- .scaleEffect(isAnimating ? 1.02 : 0.98)
- .animation(
- .easeInOut(duration: 2.0).repeatForever(autoreverses: true),
- value: isAnimating
- )
- }
- .frame(width: 120, height: 120)
- .contentShape(Circle())
- .onTapGesture {
- HapticManager.trigger(.recordStart)
- action()
- }
- .onAppear {
- isAnimating = true
- }
- }
- }
- // MARK: - Preview
- #Preview {
- ZStack {
- Color.spaceBlack.ignoresSafeArea()
- PulsingRecordButton {
- print("Record tapped")
- }
- }
- }
|