mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
98 lines
3.3 KiB
Swift
98 lines
3.3 KiB
Swift
/*
|
|
* Atoll (DynamicIsland)
|
|
* Copyright (C) 2024-2026 Atoll Contributors
|
|
*
|
|
* Originally from boring.notch project
|
|
* Modified and adapted for Atoll (DynamicIsland)
|
|
* See NOTICE for details.
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import SwiftUI
|
|
|
|
struct MinimalFaceFeatures: View {
|
|
@State private var isBlinking = false
|
|
@State var height:CGFloat = 20;
|
|
@State var width:CGFloat = 30;
|
|
|
|
var body: some View {
|
|
VStack(spacing: 4) { // Adjusted spacing to fit within 30x30
|
|
// Eyes
|
|
HStack(spacing: 4) { // Adjusted spacing to fit within 30x30
|
|
Eye(isBlinking: $isBlinking)
|
|
Eye(isBlinking: $isBlinking)
|
|
}
|
|
|
|
// Nose and mouth combined
|
|
VStack(spacing: 2) { // Adjusted spacing to fit within 30x30
|
|
// Nose
|
|
RoundedRectangle(cornerRadius: 2)
|
|
.fill(Color.white)
|
|
.frame(width: 3, height: 4)
|
|
|
|
// Mouth (happy)
|
|
GeometryReader { geometry in
|
|
Path { path in
|
|
let width = geometry.size.width
|
|
let height = geometry.size.height
|
|
path.move(to: CGPoint(x: 0, y: height / 2))
|
|
path.addQuadCurve(to: CGPoint(x: width, y: height / 2), control: CGPoint(x: width / 2, y: height))
|
|
}
|
|
.stroke(Color.white, lineWidth: 2)
|
|
}
|
|
.frame(width: 14, height: 10)
|
|
}
|
|
}
|
|
.frame(width: self.width, height: self.height) // Maximum size of face
|
|
.onAppear {
|
|
startBlinking()
|
|
}
|
|
}
|
|
|
|
func startBlinking() {
|
|
Timer.scheduledTimer(withTimeInterval: 3, repeats: true) { _ in
|
|
withAnimation(.spring(duration: 0.2)) {
|
|
isBlinking = true
|
|
}
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
|
withAnimation(.spring(duration: 0.2)) {
|
|
isBlinking = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct Eye: View {
|
|
@Binding var isBlinking: Bool
|
|
|
|
var body: some View {
|
|
RoundedRectangle(cornerRadius: 10)
|
|
.fill(Color.white)
|
|
.frame(width: 4, height: isBlinking ? 1 : 4)
|
|
.frame(maxWidth: 15, maxHeight: 15) // Adjusted max size
|
|
.animation(.easeInOut(duration: 0.1), value: isBlinking)
|
|
}
|
|
}
|
|
|
|
struct MinimalFaceFeatures_Previews: PreviewProvider {
|
|
static var previews: some View {
|
|
ZStack {
|
|
Color.black
|
|
MinimalFaceFeatures()
|
|
}
|
|
.previewLayout(.fixed(width: 60, height: 60)) // Adjusted preview size for better visibility
|
|
}
|
|
}
|