Skip to content

Instantly share code, notes, and snippets.

@DarrenHurst
Created March 23, 2023 01:02
Show Gist options
  • Save DarrenHurst/853d911f206bc164fd509c988ebae47a to your computer and use it in GitHub Desktop.
Save DarrenHurst/853d911f206bc164fd509c988ebae47a to your computer and use it in GitHub Desktop.
@ViewBuilder different circle profile like images. Use: Build an avatar. switch to builder patter for components.
import Foundation
import SwiftUI
import PhotosUI
@available(iOS 16.0, *)
struct Photos: View {
var body: some View {
VStack{
VStack {
FunView(viewType: .koala)
FunView(viewType: .cat)
FunView(viewType: .dog)
FunView(viewType: .teddybear)
}.shadow(radius: 5)
}
}
}
@available(iOS 16.0, *)
enum ProfileImgType {
case cat, koala, teddybear, dog
@ViewBuilder
public mutating func avatarType(_ self: FunView) -> some View {
switch self.viewType {
case .cat:
self.funProfile(.white, .red, 0.5)
case .koala:
self.funProfile(.gray, .yellow, 0.1)
case .teddybear:
self.funProfile(.orange, .brown, 0.2)
case .dog:
self.funProfile(.brown, .brown, 0.1)
}
}
}
@available(iOS 13.0, *)
struct Triangle: Shape {
func path(in rect: CGRect) -> Path {
var path :Path = Path()
path.move(to: CGPoint(x:0,y:0))
path.addLine(to: CGPoint(x:15, y:25))
path.addLine(to: CGPoint(x:30, y:0))
path.addLine(to: CGPoint(x:0, y:0))
return path
}
}
@available(iOS 13.0, *)
struct Line: Shape {
func path(in rect: CGRect) -> Path {
var path: Path = Path()
path.move(to: CGPoint(x:0,y:0))
path.addLine(to: CGPoint(x:3, y:18))
return path
}
}
@available(iOS 16.0, *)
struct FunView: View, Identifiable {
var id: UUID = UUID()
@State var viewType: ProfileImgType
@State var blink: Bool = false
var body: some View {
viewType.avatarType(self)
}
public func baseColor(color: Color) -> any ShapeStyle {
LinearGradient(gradient: Gradient(colors: [.brown,color,color,.clear, .clear]), startPoint: .top, endPoint: .bottom)
}
}
@available(iOS 16.0, *)
extension FunView {
fileprivate func funProfile(_ base: Color, _ color: Color, _ opacity: Double) -> some View {
let bearColor: Color = base
return ZStack {
emptyViewState(bearColor)
.controlSize(.small)
.rotationEffect( Angle(degrees: 80) )
.frame(width:50).scaledToFit().offset(y:10).zIndex(0.2)
ZStack {
AnyView(
Circle()
.fill(baseColor(color: bearColor))
.frame(width: 47).offset(y:50)
.scaleEffect(x: 1.2, y: 2, anchor: .bottom))
AnyView(
Circle()
.fill(baseColor(color: bearColor))
.frame(width: 47).offset(x:20, y:50).scaleEffect(x: 1.1, y: 1.3, anchor: .bottom))
AnyView(
Circle()
.fill(baseColor(color: bearColor))
.frame(width: 47).offset(x:-20, y:50).scaleEffect(x: 1.1, y: 1.4, anchor: .bottom))
}.zIndex(0.1)
emptyViewState(bearColor.opacity(0.5)).controlSize(.small)
.rotationEffect( Angle(degrees: 80) )
.frame(width:50).scaledToFit().offset(y:10).zIndex(0.2)
}.frame(width: 100, height:120)
.background(.white.opacity(0.05))
.background(color.opacity(opacity))
.mask(Circle())
.shadow(radius: 2)
}
fileprivate func face(_ color: Color) -> some View {
ZStack {
Circle().frame(width:10).offset(x:5).zIndex(0.2)
Circle().frame(width:2).offset(x:15).zIndex(0.2)
Circle().fill().frame(height: 5).offset(x: -1, y: 10).opacity(0.3).zIndex(0.2)
Circle().fill().frame(height: 5).offset(x: 3, y: -10).opacity(0.5).zIndex(0.2)
Circle()
.fill(RadialGradient.init(colors: [color.opacity(0.6), color.opacity(1), color.opacity(0.8)], center: .top, startRadius: 10.0, endRadius: 90.0))
.opacity(blink ? 0.7 : 0.6)
.animation(.default.speed(0.5).repeatForever(), value: blink).zIndex(0.6)
}
}
fileprivate func ears(_ color: Color) -> some View {
ZStack {
Circle().fill(LinearGradient(gradient: Gradient(colors: [color, .clear, .clear]), startPoint: .bottomLeading, endPoint: .topTrailing).opacity(0.9)).zIndex(0.2) .frame(width:35).offset(x:-15, y: 13).zIndex(0.2)
Circle().fill(LinearGradient(gradient: Gradient(colors: [color, .clear, .clear]), startPoint: .topLeading, endPoint: .bottomTrailing).opacity(0.9)).zIndex(0.2) .frame(width:35).offset(x:-12, y: -15).zIndex(0.2)
}
}
fileprivate func builderCircle(_ color: Color) -> some View {
return Circle().stroke(lineWidth: 13).fill(color.opacity(0.2)).transformEffect(CGAffineTransform(a: 0.2, b: -0.2, c: 0.4, d: 0.4, tx: -2, ty: 31)).rotationEffect(Angle(degrees: 49)).shadow(radius: 5)
}
fileprivate func emptyViewState(_ color: Color) -> some View {
ZStack {
ZStack {
if [.dog, .teddybear, .koala].contains(viewType) {
ears(color)
}
if [.dog].contains(viewType) {
//white face
Circle().fill(.white).frame(width: 50, height: 100)
//snoot
Circle().fill(.gray).frame(width: 50, height: 20).offset(x:10)
//Spot
Circle().fill(.gray.opacity(0.4)).frame(width: 50, height: 20).offset(x:-3, y:10)
}
face(color)
if viewType == .cat {
Triangle().fill(LinearGradient(gradient: Gradient(colors: [.white, .clear]), startPoint: .bottom, endPoint: .top)).frame(width: 25).scaledToFit()
.rotationEffect(Angle(degrees: 66)).offset(x:-30, y:10)
.shadow(radius: 2)
Triangle().fill(LinearGradient(gradient: Gradient(colors: [.clear, .white, .white, .white]), startPoint: .topLeading, endPoint: .bottomLeading)).frame(width: 5).scaledToFit()
.rotationEffect(Angle(degrees: 6)).offset(x:-44, y:19)
ZStack{
Line()
.stroke(style: StrokeStyle(lineWidth: 1))
.fill(.gray)
.offset(x:30, y:24)
.shadow(radius: 5)
Line()
.stroke(style: StrokeStyle(lineWidth: 1))
.fill(.gray)
.offset(x:-12, y:35)
.rotationEffect(Angle(degrees: 45), anchor: .bottom)
.shadow(radius: 5)
Line()
.stroke(style: StrokeStyle(lineWidth: 1))
.fill(.gray)
.offset(x:34, y:60)
.shadow(radius: 5)
Line()
.stroke(style: StrokeStyle(lineWidth: 1))
.fill(.gray)
.offset(x:10, y:62)
.rotationEffect(Angle(degrees: 34), anchor: .bottom)
.shadow(radius: 5)
}.zIndex(0.1)
.shadow(radius: 5)
}
}.zIndex(0.05)
.shadow(radius: blink ? 0 : 2)
.animation(.default.speed(0.1).repeatForever(), value: blink)
.zIndex(0.1)
.offset( y: blink ? 0 : 0.1)
.animation(.default.speed(0.1).repeatForever(), value: blink)
.onAppear(){
blink = true
}
}.onAppear() {
blink = blink ? false : true
}
}
}
@available(iOS 16.0, *)
struct PhotosPreview: PreviewProvider {
static var previews: some View {
Photos()
}
}
@DarrenHurst
Copy link
Author

Screenshot 2023-03-22 at 9 02 30 PM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment