Skip to content
37 changes: 37 additions & 0 deletions Sources/SwiftNEW/Animations/FloatingParticlesView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// FloatingParticlesView.swift
// SwiftNEW
//

import SwiftUI

struct FloatingParticlesView: View {
private let particleCount = 30
private let particleColors: [Color] = [
.red, .orange, .yellow, .green, .mint, .teal, .cyan, .blue, .indigo, .purple, .pink
]

var body: some View {
TimelineView(.animation) { timeline in
Canvas { context, size in
let time = timeline.date.timeIntervalSinceReferenceDate
for i in 0..<particleCount {
let seed = Double(i) * 137.508
let x = (sin(time * 0.3 + seed) * 0.45 + 0.5) * size.width
let y = (cos(time * 0.2 + seed * 0.7) * 0.45 + 0.5) * size.height
let radius = CGFloat(3 + sin(seed) * 3)
let opacity = 0.5 + sin(time * 0.5 + seed) * 0.2
let color = particleColors[i % particleColors.count]

context.opacity = 0.4
context.fill(
Path(ellipseIn: CGRect(x: x - radius, y: y - radius, width: radius * 2, height: radius * 2)),
with: .color(color.opacity(opacity))
)
}
}
}
.allowsHitTesting(false)
.accessibilityHidden(true)
}
}
56 changes: 27 additions & 29 deletions Sources/SwiftNEW/Animations/SnowfallView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,38 @@
import SwiftUI

struct SnowfallView: View {
@State private var snowflakes = [Snowflake]()
private let timer = Timer.publish(every: 0.05, on: .main, in: .common).autoconnect()
private let snowflakeCount = 100

var body: some View {
GeometryReader { geometry in
ZStack {
ForEach(snowflakes) { snowflake in
Circle()
.fill(Color.white)
.frame(width: snowflake.size, height: snowflake.size)
.position(x: snowflake.x, y: snowflake.y)
}
}
.onAppear {
for _ in 0..<100 {
let snowflake = Snowflake(
id: UUID(),
x: CGFloat.random(in: 0...geometry.size.width),
y: CGFloat.random(in: -geometry.size.height...0),
size: CGFloat.random(in: 2...6),
speed: CGFloat.random(in: 1...3)
TimelineView(.animation) { timeline in
Canvas { context, size in
let time = timeline.date.timeIntervalSinceReferenceDate
for i in 0..<snowflakeCount {
let seed = Double(i) * 73.156
let speed = 1.0 + (seed.truncatingRemainder(dividingBy: 3.0))
let snowflakeSize = CGFloat(2 + (seed.truncatingRemainder(dividingBy: 5.0)))

// Horizontal drift using sine wave
let drift = sin(time * 0.5 + seed) * 30
let x = ((seed * 7.3).truncatingRemainder(dividingBy: size.width)) + drift
// Vertical fall with wrapping
let y = ((time * speed * 30) + seed * 5).truncatingRemainder(dividingBy: Double(size.height + 20)) - 10
let opacity = 0.5 + sin(seed) * 0.3

context.opacity = opacity
context.fill(
Path(ellipseIn: CGRect(
x: x - snowflakeSize / 2,
y: y - snowflakeSize / 2,
width: snowflakeSize,
height: snowflakeSize
)),
with: .color(.white)
)
snowflakes.append(snowflake)
}
}
.onReceive(timer) { _ in
for index in snowflakes.indices {
snowflakes[index].y += snowflakes[index].speed
if snowflakes[index].y > geometry.size.height {
snowflakes[index].y = -snowflakes[index].size
snowflakes[index].x = CGFloat.random(in: 0...geometry.size.width)
}
}
}
}
.allowsHitTesting(false)
.accessibilityHidden(true)
}
}
42 changes: 20 additions & 22 deletions Sources/SwiftNEW/Extensions/SwiftNEW+Functions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,31 +42,29 @@ extension SwiftNEW {
}

public func loadData() {
if data.contains("http") {
// MARK: Remote Data
let url = URL(string: data)
URLSession.shared.dataTask(with: url!) { data, response, error in
if let data = data {
do {
let decoder = JSONDecoder()
items = try decoder.decode([Vmodel].self, from: data)
self.loading = false
} catch {
print(error)
}
let source = data
Task {
do {
let decoded: [Vmodel]
if source.contains("http") {
// MARK: Remote Data
guard let url = URL(string: source) else { return }
let (responseData, _) = try await URLSession.shared.data(from: url)
decoded = try JSONDecoder().decode([Vmodel].self, from: responseData)
} else {
// MARK: Local Data
guard let url = Bundle.main.url(forResource: source, withExtension: "json") else { return }
decoded = try await Task.detached {
let fileData = try Data(contentsOf: url)
return try JSONDecoder().decode([Vmodel].self, from: fileData)
}.value
}
}.resume()
} else {
// MARK: Local Data
if let url = Bundle.main.url(forResource: data, withExtension: "json") {
do {
let data = try Data(contentsOf: url)
let decoder = JSONDecoder()
items = try decoder.decode([Vmodel].self, from: data)
await MainActor.run {
items = decoded
loading = false
} catch {
print("error: \(error)")
}
} catch {
print("SwiftNEW loadData error: \(error)")
}
}
}
Expand Down
24 changes: 12 additions & 12 deletions Sources/SwiftNEW/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
"ar" : {
"stringUnit" : {
"state" : "translated",
"value" : "الإستعمالات السابقة"
"value" : "التحديثات السابقة"
}
},
"de" : {
Expand Down Expand Up @@ -123,7 +123,7 @@
"ar" : {
"stringUnit" : {
"state" : "translated",
"value" : "...جاري التحميل"
"value" : "جاري التحميل..."
}
},
"de" : {
Expand Down Expand Up @@ -229,7 +229,7 @@
"ar" : {
"stringUnit" : {
"state" : "translated",
"value" : "إعرض الإستعمالات السابقة"
"value" : "إعرض التحديثات السابقة"
}
},
"de" : {
Expand Down Expand Up @@ -329,55 +329,55 @@
}
}
},
"Version" : {
"Version %@" : {
"extractionState" : "manual",
"localizations" : {
"ar" : {
"stringUnit" : {
"state" : "translated",
"value" : "الإصدار"
"value" : "الإصدار %@"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Version"
"value" : "Version %@"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Version"
"value" : "Version %@"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "La Version"
"value" : "La Version %@"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "La Versione"
"value" : "La Versione %@"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "版本"
"value" : "版本 %@"
}
},
"zh-Hant" : {
"stringUnit" : {
"state" : "translated",
"value" : "版本"
"value" : "版本 %@"
}
},
"zh-HK" : {
"stringUnit" : {
"state" : "translated",
"value" : "版本"
"value" : "版本 %@"
}
}
}
Expand Down
12 changes: 3 additions & 9 deletions Sources/SwiftNEW/Model.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,15 @@
import SwiftUI

// MARK: - Model
public struct Vmodel: Codable, Hashable {
public struct Vmodel: Codable, Hashable, Sendable {
var version: String
var subVersion: String?
var new: [Model]
}
public struct Model: Codable, Hashable {
public struct Model: Codable, Hashable, Sendable {
var icon: String
var title: String
var subtitle: String
var body: String
}
struct Snowflake: Identifiable {
let id: UUID
var x: CGFloat
var y: CGFloat
var size: CGFloat
var speed: CGFloat
}

3 changes: 2 additions & 1 deletion Sources/SwiftNEW/Styles/MeshView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ struct MeshView: View {
])
.ignoresSafeArea(.all)
.overlay(
NoiseView(size: 100000)
NoiseView(size: 5000)
.drawingGroup()
)
} else {
// Fallback on earlier versions
Expand Down
Loading