如何解决在SwiftUI中用波浪动画填充圆圈
我在swiftUI中创建了一个圆圈,我想用正弦波动画填充它以实现水波效果/动画。我想用类似的外观填充它:
下面是我的代码:
import SwiftUI
struct CircleWaveView: View {
var body: some View {
Circle()
.stroke(Color.blue,lineWidth: 10)
.frame(width: 300,height: 300)
}
}
struct CircleWaveView_Previews: PreviewProvider {
static var previews: some View {
CircleWaveView()
}
}
我想主要在SwiftUI上实现它,以便支持暗模式!感谢您的帮助!
解决方法
这是一个完整的独立示例。它具有一个滑块,可让您更改百分比:
import SwiftUI
struct ContentView: View {
@State private var percent = 50.0
var body: some View {
VStack {
CircleWaveView(percent: Int(self.percent))
Slider(value: self.$percent,in: 0...100)
}
.padding(.all)
}
}
struct Wave: Shape {
var offset: Angle
var percent: Double
var animatableData: Double {
get { offset.degrees }
set { offset = Angle(degrees: newValue) }
}
func path(in rect: CGRect) -> Path {
var p = Path()
// empirically determined values for wave to be seen
// at 0 and 100 percent
let lowfudge = 0.02
let highfudge = 0.98
let newpercent = lowfudge + (highfudge - lowfudge) * percent
let waveHeight = 0.015 * rect.height
let yoffset = CGFloat(1 - newpercent) * (rect.height - 4 * waveHeight) + 2 * waveHeight
let startAngle = offset
let endAngle = offset + Angle(degrees: 360)
p.move(to: CGPoint(x: 0,y: yoffset + waveHeight * CGFloat(sin(offset.radians))))
for angle in stride(from: startAngle.degrees,through: endAngle.degrees,by: 5) {
let x = CGFloat((angle - startAngle.degrees) / 360) * rect.width
p.addLine(to: CGPoint(x: x,y: yoffset + waveHeight * CGFloat(sin(Angle(degrees: angle).radians))))
}
p.addLine(to: CGPoint(x: rect.width,y: rect.height))
p.addLine(to: CGPoint(x: 0,y: rect.height))
p.closeSubpath()
return p
}
}
struct CircleWaveView: View {
@State private var waveOffset = Angle(degrees: 0)
let percent: Int
var body: some View {
GeometryReader { geo in
ZStack {
Text("\(self.percent)%")
.foregroundColor(.black)
.font(Font.system(size: 0.25 * min(geo.size.width,geo.size.height) ))
Circle()
.stroke(Color.blue,lineWidth: 0.025 * min(geo.size.width,geo.size.height))
.overlay(
Wave(offset: Angle(degrees: self.waveOffset.degrees),percent: Double(percent)/100)
.fill(Color(red: 0,green: 0.5,blue: 0.75,opacity: 0.5))
.clipShape(Circle().scale(0.92))
)
}
}
.aspectRatio(1,contentMode: .fit)
.onAppear {
withAnimation(Animation.linear(duration: 2).repeatForever(autoreverses: false)) {
self.waveOffset = Angle(degrees: 360)
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
CircleWaveView(percent: 58)
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。