Я пытаюсь создать такой собственный индикатор выполнения (пока игнорируйте большой палец):
[img]https:/ /i.sstatic.net/UlUtv1ED.png[/img]
На данный момент я могу постепенно раскрыть волну, используя еще один прямоугольник, примененный в качестве маски. Я не уверен, как обрезать левую часть строки по мере увеличения прогресса. Я попытался установить представление волны с маской в качестве маски для линии, но это не сработало. Должен ли я обновлять ширину линии в зависимости от прогресса или можно использовать маску таким образом, чтобы, когда волна начинает становиться видимой от переднего края, линия сжималась по направлению к заднему краю? Посоветуйте, пожалуйста, эффективный способ это сделать. Любая помощь приветствуется.
struct Line: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
path.move(to: CGPoint(x: 0, y: rect.height/2))
path.addLine(to: CGPoint(x: rect.width, y: rect.height/2))
return path
}
}
struct Wave: Shape {
var strength: Double
var frequency: Double
var phase: Double
var animatableData: Double {
get { phase }
set { self.phase = newValue }
}
func path(in rect: CGRect) -> Path {
var path = Path()
let width = Double(rect.width)
let height = Double(rect.height)
let midHeight = height / 2
let wavelength = width / frequency
let firstX = 0.0
let firstRelativeX = firstX / wavelength
let firstSine = sin(firstRelativeX + phase)
let firstY = strength * firstSine + midHeight
path.move(to: CGPoint(x: firstX, y: firstY))
for x in stride(from: 0.0, through: width, by: 1) {
let relativeX = x / wavelength
let sine = sin(relativeX + phase)
let y = strength * sine + midHeight
path.addLine(to: CGPoint(x: x, y: y))
}
return path
}
}
struct ContentView: View {
@State private var phase = 0.0
@State private var progress = 0.0
var body: some View {
VStack {
GeometryReader(content: { geometry in
ZStack {
Line()
.stroke(Color.white.opacity(0.5), lineWidth: 5.0)
.frame(width: geometry.size.width)
Wave(strength: 10, frequency: 30, phase: phase)
.stroke(Color.white, lineWidth: 5)
.mask(
Rectangle()
.frame(width: (geometry.size.width * progress), height: geometry.size.height)
.padding(.trailing, geometry.size.width * (1 - progress))
)
}
})
Slider(value: $progress, in: 0...1)
.padding()
}
.background(Color.black.ignoresSafeArea())
.onAppear {
withAnimation(Animation.linear(duration: 2).repeatForever(autoreverses: false)) {
self.phase = .pi * 2
}
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/786 ... in-swiftui
Маскируйте несколько фигур в SwiftUI ⇐ IOS
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Маскируйте сведения об исключении, доставленные в сообщении последовательного журнала.
Anonymous » » в форуме C# - 0 Ответы
- 12 Просмотры
-
Последнее сообщение Anonymous
-