Skip to content

Commit b117299

Browse files
authored
Merge pull request #9 from 1998code/2.0
26.0 SwiftGlassUI Library 2.0
2 parents 4e7eeeb + a4a6af4 commit b117299

File tree

9 files changed

+637
-97
lines changed

9 files changed

+637
-97
lines changed

Demo/Demo.xcodeproj/project.pbxproj

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,7 @@
653653
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
654654
CODE_SIGN_ENTITLEMENTS = Demo/Demo.entitlements;
655655
CODE_SIGN_STYLE = Automatic;
656-
CURRENT_PROJECT_VERSION = 11;
656+
CURRENT_PROJECT_VERSION = 12;
657657
DEVELOPMENT_TEAM = "";
658658
ENABLE_PREVIEWS = YES;
659659
GENERATE_INFOPLIST_FILE = YES;
@@ -673,7 +673,7 @@
673673
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
674674
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
675675
MACOSX_DEPLOYMENT_TARGET = 14.0;
676-
MARKETING_VERSION = 1.9.1;
676+
MARKETING_VERSION = 26.0;
677677
PRODUCT_BUNDLE_IDENTIFIER = media.1998.Demo;
678678
PRODUCT_NAME = "$(TARGET_NAME)";
679679
REGISTER_APP_GROUPS = YES;
@@ -695,7 +695,7 @@
695695
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
696696
CODE_SIGN_ENTITLEMENTS = Demo/Demo.entitlements;
697697
CODE_SIGN_STYLE = Automatic;
698-
CURRENT_PROJECT_VERSION = 11;
698+
CURRENT_PROJECT_VERSION = 12;
699699
DEVELOPMENT_TEAM = "";
700700
ENABLE_PREVIEWS = YES;
701701
GENERATE_INFOPLIST_FILE = YES;
@@ -715,7 +715,7 @@
715715
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
716716
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
717717
MACOSX_DEPLOYMENT_TARGET = 14.0;
718-
MARKETING_VERSION = 1.9.1;
718+
MARKETING_VERSION = 26.0;
719719
PRODUCT_BUNDLE_IDENTIFIER = media.1998.Demo;
720720
PRODUCT_NAME = "$(TARGET_NAME)";
721721
REGISTER_APP_GROUPS = YES;
@@ -822,7 +822,7 @@
822822
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
823823
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
824824
CODE_SIGN_STYLE = Automatic;
825-
CURRENT_PROJECT_VERSION = 10;
825+
CURRENT_PROJECT_VERSION = 12;
826826
DEVELOPMENT_TEAM = "";
827827
ENABLE_PREVIEWS = YES;
828828
GENERATE_INFOPLIST_FILE = YES;
@@ -833,7 +833,7 @@
833833
"$(inherited)",
834834
"@executable_path/Frameworks",
835835
);
836-
MARKETING_VERSION = 1.8.0;
836+
MARKETING_VERSION = 26.0;
837837
PRODUCT_BUNDLE_IDENTIFIER = media.1998.Demo.watchkitapp;
838838
PRODUCT_NAME = "$(TARGET_NAME)";
839839
SDKROOT = watchos;
@@ -851,7 +851,7 @@
851851
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
852852
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
853853
CODE_SIGN_STYLE = Automatic;
854-
CURRENT_PROJECT_VERSION = 10;
854+
CURRENT_PROJECT_VERSION = 12;
855855
DEVELOPMENT_TEAM = "";
856856
ENABLE_PREVIEWS = YES;
857857
GENERATE_INFOPLIST_FILE = YES;
@@ -862,7 +862,7 @@
862862
"$(inherited)",
863863
"@executable_path/Frameworks",
864864
);
865-
MARKETING_VERSION = 1.8.0;
865+
MARKETING_VERSION = 26.0;
866866
PRODUCT_BUNDLE_IDENTIFIER = media.1998.Demo.watchkitapp;
867867
PRODUCT_NAME = "$(TARGET_NAME)";
868868
SDKROOT = watchos;

Demo/Demo/Samples/Advanced/GlassFlower/GlassFlower.swift

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -32,32 +32,7 @@ struct GlassFlower: View {
3232
// Flower petals: Eight capsules arranged in a circle pattern
3333
// Each petal is a gradient-filled capsule with glass effect applied
3434
ForEach(0..<8, id: \.self) { index in
35-
Capsule()
36-
.fill(
37-
LinearGradient(
38-
gradient: Gradient(stops: [
39-
.init(color: colors[index % colors.count], location: 0),
40-
.init(color: colors[index % colors.count].opacity(0.5), location: 1)
41-
]),
42-
startPoint: .bottom,
43-
endPoint: .top
44-
)
45-
)
46-
47-
// Apply glass effect from SwiftGlass library to create translucent look
48-
.glass(color: colors[index % colors.count], colorOpacity: 1, shadowColor: .white)
49-
50-
.frame(width: 55, height: 100) // Petal dimensions
51-
.offset(x: 0, y: 0) // Position petals away from center
52-
.rotationEffect(.degrees(Double(index) * 45), anchor: .bottom) // Distribute evenly in 360° (8×45°)
53-
.offset(y: -50) // Adjust vertical position of entire flower
54-
.scaleEffect(isPulsing ? 0.97 : 1.05) // Size animation range
55-
.animation(
56-
Animation.easeInOut(duration: 2.0)
57-
.delay(Double(index) * 0.1) // Staggered animation for flowing effect
58-
.repeatForever(autoreverses: true),
59-
value: isPulsing
60-
)
35+
petalView(for: index)
6136
}
6237
}
6338
.frame(width: 300, height: 300)
@@ -66,6 +41,33 @@ struct GlassFlower: View {
6641
isPulsing.toggle()
6742
}
6843
}
44+
45+
@ViewBuilder
46+
private func petalView(for index: Int) -> some View {
47+
let color = colors[index % colors.count]
48+
let gradient = LinearGradient(
49+
gradient: Gradient(stops: [
50+
.init(color: color, location: 0),
51+
.init(color: color.opacity(0.5), location: 1)
52+
]),
53+
startPoint: .bottom,
54+
endPoint: .top
55+
)
56+
let rotation = Double(index) * 45
57+
let animation = Animation.easeInOut(duration: 2.0)
58+
.delay(Double(index) * 0.1)
59+
.repeatForever(autoreverses: true)
60+
61+
Capsule()
62+
.fill(gradient)
63+
.glass(color: color, colorOpacity: 1, shadowColor: .white)
64+
.frame(width: 55, height: 100)
65+
.offset(x: 0, y: 0)
66+
.rotationEffect(.degrees(rotation), anchor: .bottom)
67+
.offset(y: -50)
68+
.scaleEffect(isPulsing ? 0.97 : 1.05)
69+
.animation(animation, value: isPulsing)
70+
}
6971
}
7072

7173
// MARK: - Previews

Demo/Demo/Samples/Advanced/GlassFlower/GlassFlowerRotate.swift

Lines changed: 49 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -34,62 +34,65 @@ struct GlassFlowerRotate: View {
3434
// Flower petals: Eight capsules arranged in a circle pattern
3535
// Each petal is a gradient-filled capsule with glass effect applied
3636
ForEach(0..<8, id: \.self) { index in
37-
Capsule()
38-
.fill(
39-
LinearGradient(
40-
gradient: Gradient(stops: [
41-
.init(color: colors[index % colors.count], location: 0),
42-
.init(color: colors[index % colors.count].opacity(0.5), location: 1)
43-
]),
44-
startPoint: .bottom,
45-
endPoint: .top
46-
)
47-
)
48-
49-
// Apply glass effect from SwiftGlass library to create translucent look
50-
.glass(color: colors[index % colors.count], colorOpacity: 1, shadowColor: .white)
51-
52-
.frame(width: 55, height: 100) // Petal dimensions
53-
.offset(x: 0, y: 0) // Position petals away from center
54-
.rotationEffect(.degrees(Double(index) * 45), anchor: .bottom) // Distribute evenly in 360° (8×45°)
55-
.rotationEffect(rotateToCenter ? .degrees(720) : .degrees(0), anchor: .bottom) // Rotate petals to face center when activated
56-
.offset(y: -50) // Adjust vertical position of entire flower
57-
.scaleEffect(isPulsing ? 0.97 : 1.05) // Size animation range
58-
.animation(
59-
Animation.easeInOut(duration: 2.0)
60-
.delay(Double(index) * 0.1) // Staggered animation for flowing effect
61-
.repeatForever(autoreverses: true),
62-
value: isPulsing
63-
)
64-
.animation(
65-
Animation.easeInOut(duration: 3.5)
66-
.delay(Double(index) * 0.15), // Slightly staggered rotation
67-
value: rotateToCenter
68-
)
37+
petalView(for: index)
6938
}
7039

7140
// Button to toggle rotation to center
72-
Button(action: {
73-
withAnimation {
74-
rotateToCenter.toggle()
75-
}
76-
}) {
77-
Text(rotateToCenter ? "Reset Rotation" : "Rotate to Center")
78-
.foregroundColor(.white)
79-
.padding(15)
80-
}
81-
.cornerRadius(8)
82-
83-
.glass(color: .blue, shadowColor: .blue)
84-
85-
.offset(y: 240) // Position button below the flower
41+
rotationButton
8642
}
8743
.frame(width: 300, height: 300)
8844
// Start the pulsing animation when view appears
8945
.onAppear {
9046
isPulsing.toggle()
9147
}
9248
}
49+
50+
@ViewBuilder
51+
private func petalView(for index: Int) -> some View {
52+
let color = colors[index % colors.count]
53+
let gradient = LinearGradient(
54+
gradient: Gradient(stops: [
55+
.init(color: color, location: 0),
56+
.init(color: color.opacity(0.5), location: 1)
57+
]),
58+
startPoint: .bottom,
59+
endPoint: .top
60+
)
61+
let baseRotation = Double(index) * 45
62+
let centerRotation = rotateToCenter ? 720.0 : 0.0
63+
let pulseAnimation = Animation.easeInOut(duration: 2.0)
64+
.delay(Double(index) * 0.1)
65+
.repeatForever(autoreverses: true)
66+
let rotateAnimation = Animation.easeInOut(duration: 3.5)
67+
.delay(Double(index) * 0.15)
68+
69+
Capsule()
70+
.fill(gradient)
71+
.glass(color: color, colorOpacity: 1, shadowColor: .white)
72+
.frame(width: 55, height: 100)
73+
.offset(x: 0, y: 0)
74+
.rotationEffect(.degrees(baseRotation), anchor: .bottom)
75+
.rotationEffect(.degrees(centerRotation), anchor: .bottom)
76+
.offset(y: -50)
77+
.scaleEffect(isPulsing ? 0.97 : 1.05)
78+
.animation(pulseAnimation, value: isPulsing)
79+
.animation(rotateAnimation, value: rotateToCenter)
80+
}
81+
82+
private var rotationButton: some View {
83+
Button(action: {
84+
withAnimation {
85+
rotateToCenter.toggle()
86+
}
87+
}) {
88+
Text(rotateToCenter ? "Reset Rotation" : "Rotate to Center")
89+
.foregroundColor(.white)
90+
.padding(15)
91+
}
92+
.cornerRadius(8)
93+
.glass(color: .blue, shadowColor: .blue)
94+
.offset(y: 240)
95+
}
9396
}
9497

9598
// MARK: - Previews
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
//
2+
// Capsule.swift
3+
// Demo
4+
//
5+
// Created by Ming on 22/4/2025.
6+
//
7+
8+
import SwiftUI
9+
import SwiftGlass
10+
11+
struct CapsuleGlass: View {
12+
var body: some View {
13+
ZStack {
14+
#if !os(visionOS) && !os(watchOS) && !os(macOS)
15+
background
16+
#endif
17+
18+
VStack(spacing: 30) {
19+
// Capsule shape example
20+
HStack {
21+
Image(systemName: "capsule.fill")
22+
.font(.title2)
23+
Text("Capsule Glass")
24+
.font(.headline)
25+
}
26+
.foregroundStyle(.white)
27+
.padding(.horizontal, 30)
28+
.padding(.vertical, 15)
29+
.glass(shape: .capsule, color: .purple, shadowColor: .purple)
30+
31+
// Multiple capsules with different styles
32+
VStack(spacing: 20) {
33+
Button(action: {}) {
34+
HStack {
35+
Image(systemName: "play.fill")
36+
Text("Play Music")
37+
}
38+
.foregroundStyle(.white)
39+
.padding(.horizontal, 25)
40+
.padding(.vertical, 12)
41+
}
42+
.glass(shape: .capsule, color: .blue, shadowColor: .blue)
43+
44+
Button(action: {}) {
45+
HStack {
46+
Image(systemName: "pause.fill")
47+
Text("Pause")
48+
}
49+
.foregroundStyle(.white)
50+
.padding(.horizontal, 25)
51+
.padding(.vertical, 12)
52+
}
53+
.glass(shape: .capsule, color: .orange, shadowColor: .orange)
54+
55+
Button(action: {}) {
56+
HStack {
57+
Image(systemName: "stop.fill")
58+
Text("Stop")
59+
}
60+
.foregroundStyle(.white)
61+
.padding(.horizontal, 25)
62+
.padding(.vertical, 12)
63+
}
64+
.glass(shape: .capsule, color: .red, shadowColor: .red)
65+
}
66+
67+
// Horizontal capsule badges
68+
HStack(spacing: 15) {
69+
Text("New")
70+
.font(.caption.bold())
71+
.foregroundStyle(.white)
72+
.padding(.horizontal, 12)
73+
.padding(.vertical, 6)
74+
.glass(shape: .capsule, color: .green, shadowColor: .green)
75+
76+
Text("Hot")
77+
.font(.caption.bold())
78+
.foregroundStyle(.white)
79+
.padding(.horizontal, 12)
80+
.padding(.vertical, 6)
81+
.glass(shape: .capsule, color: .red, shadowColor: .red)
82+
83+
Text("Sale")
84+
.font(.caption.bold())
85+
.foregroundStyle(.white)
86+
.padding(.horizontal, 12)
87+
.padding(.vertical, 6)
88+
.glass(shape: .capsule, color: .yellow, shadowColor: .yellow)
89+
}
90+
}
91+
#if !os(watchOS)
92+
.padding(25)
93+
#else
94+
.padding(15)
95+
#endif
96+
}
97+
}
98+
99+
// Add a background for better looking
100+
var background: some View {
101+
Group {
102+
Color.black
103+
.ignoresSafeArea()
104+
105+
AsyncImage(url: URL(string: "https://shareby.vercel.app/3vj7gk")) { image in
106+
image
107+
.resizable()
108+
.scaledToFill()
109+
} placeholder: {
110+
ProgressView()
111+
}.opacity(0.3)
112+
.ignoresSafeArea()
113+
}
114+
}
115+
}
116+
117+
#Preview("Light") {
118+
CapsuleGlass()
119+
}
120+
121+
#Preview("Dark") {
122+
CapsuleGlass()
123+
.preferredColorScheme(.dark)
124+
}
125+

0 commit comments

Comments
 (0)