I have created a background using mesh gradient and animation. I want it animate only when a variable value (colour selected by user) changes to the new state and colour. The reason I am not using the switch statement with different points and colours is that it instantly changes to the next state, I want it to animate to next position. So that it looks like when a user selected a colour the background changed and moved to a different state. I tried a few solutions available online but nothing seems to work.
struct AnimatedMeshGradient: View {
@State var appear = false
@State var appear2 = false
var matrix1: [[Double]] = []
let colour = "red"
var body: some View {
ZStack {
MeshGradient(
width: 3,
height: 3,
points: [[0.0, 0.0], appear ? [1.0, 0.0] : [0.5, 0.0], [1.0, 0.0],
[0.0, 0.5], appear ? [0.8, 0.2] : [0.1, 0.5], [1.0, -0.5],
[0.0, 1.0], appear ? [1.5, 1.0] : [0.8, 0.8], [1.0, 1.0]
],
colors: [
.purple, .purple, .white,
.purple, .white, .purple,
.purple, .purple, .purple
])
.onAppear() {
withAnimation(.easeInOut(duration: 5).repeatForever(autoreverses: true)) {
appear.toggle()
}
}
}
}
}
#Preview {
AnimatedMeshGradient()
.ignoresSafeArea()
}
Currently with this code it is animating back and forth to two positions that I want but I want it to only change when a variable value is changed. Very similar to selecting a colour and it changing the background to the newly selected colour.
I have created a background using mesh gradient and animation. I want it animate only when a variable value (colour selected by user) changes to the new state and colour. The reason I am not using the switch statement with different points and colours is that it instantly changes to the next state, I want it to animate to next position. So that it looks like when a user selected a colour the background changed and moved to a different state. I tried a few solutions available online but nothing seems to work.
struct AnimatedMeshGradient: View {
@State var appear = false
@State var appear2 = false
var matrix1: [[Double]] = []
let colour = "red"
var body: some View {
ZStack {
MeshGradient(
width: 3,
height: 3,
points: [[0.0, 0.0], appear ? [1.0, 0.0] : [0.5, 0.0], [1.0, 0.0],
[0.0, 0.5], appear ? [0.8, 0.2] : [0.1, 0.5], [1.0, -0.5],
[0.0, 1.0], appear ? [1.5, 1.0] : [0.8, 0.8], [1.0, 1.0]
],
colors: [
.purple, .purple, .white,
.purple, .white, .purple,
.purple, .purple, .purple
])
.onAppear() {
withAnimation(.easeInOut(duration: 5).repeatForever(autoreverses: true)) {
appear.toggle()
}
}
}
}
}
#Preview {
AnimatedMeshGradient()
.ignoresSafeArea()
}
Currently with this code it is animating back and forth to two positions that I want but I want it to only change when a variable value is changed. Very similar to selecting a colour and it changing the background to the newly selected colour.
Share Improve this question edited Jan 29 at 9:59 Benzy Neez 23.9k3 gold badges15 silver badges45 bronze badges asked Jan 29 at 7:21 Gurpreet Singh BhatiaGurpreet Singh Bhatia 12 bronze badges 1 |1 Answer
Reset to default 0Your example code shows the gradient moving between two positions, always purple. The properties appear2
, matrix1
and colour
are not being used.
Would I be right in thinking that you only want to see the gradient moving when the color is also changing? This change will be triggered by the user.
If you are only using two different colors then you could derive the color from the flag being toggled. Something like:
private var colour: Color {
appear ? .blue : .purple
}
MeshGradient(
width: 3,
height: 3,
points: // ... as before,
colors: [
colour, colour, .white,
colour, .white, colour,
colour, colour, colour
])
.onTapGesture {
withAnimation(.easeInOut(duration: 5)) {
appear.toggle()
}
}
A more elaborate solution would be to allow the color for the gradient to be passed in as a parameter. Then, every time the color changes, the gradient should switch position. An .onChange
callback can be used to detect the change and perform the switch.
Btw, you may have noticed that the animation was blinking before it repeated. This was being caused by the white area briefly disappearing and then appearing again at the end/start of an animation. You can prevent it from happening by changing one of the matrix parameters from 1.0 to 0.99:
struct AnimatedMeshGradient: View {
@State var appear = false
// @State var appear2 = false
// var matrix1: [[Double]] = []
let colour: Color
var body: some View {
MeshGradient(
width: 3,
height: 3,
points: [[0.0, 0.0], appear ? [1.0, 0.0] : [0.5, 0.0], [1.0, 0.0],
[0.0, 0.5], appear ? [0.8, 0.2] : [0.1, 0.5], [1.0, -0.5],
[0.0, 1.0], appear ? [1.5, 0.99] : [0.8, 0.8], [1.0, 1.0] //
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745307475a4621799.html
appear2
andcolour
are not being used. What is it you actually want to see? In particular, is it moving correctly, but not changing color correctly? If so, why not make the color dependent on theappear
flag too? It would be good if you could provide an actual example of how it is not working correctly when a value changes. – Benzy Neez Commented Jan 29 at 9:42