SwiftUI - 动画

SwiftUI - 动画,第1张

文章目录 @[toc]动画方式:尺寸、透明度、偏移量、旋转角度、亮度动画效果:速度、延时、循环次数Toggle 动画效果移入移出动画其他动画示例滑动解锁Rotation3DEffect色变动画AngularGradientAnimation圆形收缩动画遮罩扫描动画万花筒Sequence电动履带动画 Drawing and Animation
https://developer.apple.com/documentation/swiftui/drawing-and-animation
动画方式:尺寸、透明度、偏移量、旋转角度、亮度
struct ContentView : View
{
    @State var factor: Double = 1       // 尺寸大小
    @State var alpha: Double = 1        // 透明度
    @State var distance: Double = 0     // 偏移量
    @State var angle: Double = 0        // 旋转角度
    @State var brightness: Double = 0   // 亮度


    var body: some View
    {
        Image("logo")
            .scaleEffect(CGFloat(factor))
            .opacity(alpha)
            .onTapGesture   // 点击
            {
                withAnimation(.linear(duration: 1.0))
                {
                    self.factor += 0.1
                    self.alpha -= 0.2
                }
            }
        
        Image("logo")
            .animation(.easeOut(duration: 2))
//            .animation(.spring())
            .offset(x: 0, y: CGFloat(distance))
            .rotationEffect(Angle.init(degrees: angle))
            .brightness(brightness)
        
        Divider().fixedSize()
        
        Button(action:
        {
            self.distance -= 120
            self.angle += 90
            self.brightness = 2
            
        }) {
            Text("Move Effect")
        }
        
    }
}

动画效果:速度、延时、循环次数
struct ContentView : View
{
    @State var factor: Double = 1.0
    @State var angle: Double = 0
    
    var animation: Animation
    {
        Animation.linear(duration: 1)
            .speed(5)  // 5 倍于 速度1
            .delay(1)   // 延迟 1s 后再进行动画
    }


    var animation1: Animation
    {
        Animation.spring()
             .repeatForever()  // 循环,回到原来的状态再次运行
//            .repeatForever(autoreverses: false)  // 循环
//            .repeatCount(3)  // 玄幻次数
    }

    var body: some View
    {
        VStack
        {
            Image("logo")
                .scaleEffect(CGFloat(factor))
                .animation(animation)
            
            Divider().fixedSize()
            
            Button(action:
            {
                self.factor += 0.5
            }) {
                Text("Zoom In Effect")
            }
        }

VStack
        {
            Image("couples")
                .rotationEffect(Angle.init(degrees: angle))
                .animation(animation1)
            
            Divider().fixedSize()
            
            Button(action:
            {
                self.angle = 45
            }) {
                Text("Repeat Forever Effect")
            }
        }

    }
}


Toggle 动画效果
struct ContentView : View
{
    @State private var showingPassword = false
    @State private var password = ""

    var body: some View
    {
        VStack
        {
            Toggle(isOn: $showingPassword.animation(.linear(duration: 1)))
            {
                Text("Toggle Password")
            }

            if showingPassword
            {
                TextField("Password", text: $password)
                    .padding()
                    .border(Color.green, width: 2)
            }
        }
        .padding()
    }
}

移入移出动画

struct ContentView : View
{
    @State var showPicture = false
    
    var body: some View
    {
        VStack
        {
            Button(action:
                    {
                        withAnimation
                        {
                            self.showPicture.toggle()
                        }
                    }) {
                Text("Show picture")
            }
            
            if showPicture
            {
//                Image("05")  // 显示、隐藏 无动画
//
//                Image("05")
//                    .transition(.move(edge: .top)) // 从上往下 移入
//
//                Image("05")
//                    .transition(.scale(scale: 0))  // 从中间放大 移入
//
//                Image("05")
                    .transition(.slide)  // 从左滑入
//
//                Image("05")
//                    .transition(.asymmetric(insertion: .scale(scale: 0),
//                                            removal: .slide)) // 中间方法进入,右滑移出
                
                Image("05")
                    .transition(AnyTransition.scale(scale: 0).combined(with:.slide))  // 左滑放大进入,右滑变小移出
            }
        }
    }
}

其他动画示例
滑动解锁
struct ContentView : View
{
    @State private var hueShift: Bool = false

    var body: some View
    {
        ZStack
        {
            Text("Slide to unlock")
                .font(.largeTitle)
                .foregroundColor(.purple)
                .brightness(-0.2)
                .hueRotation(.degrees(hueShift ? 0 : 720))
                .animation(Animation.easeInOut(duration: 4))
                .onTapGesture
                {
                    self.hueShift = true
                }
            
            Rectangle()
                .frame(maxWidth: 220, maxHeight: 40)
                .foregroundColor(.white)  // blue
                .opacity(0.5)
                .rotationEffect(.degrees(0), anchor: .trailing)
                .scaleEffect(x:hueShift ? 0 : 1, y:1, anchor: .trailing)
                .animation(Animation.easeInOut(duration: 4))
        }
    }
}

Rotation3DEffect
struct ContentView : View
{
    @State var angle: Double = 0
    @State var scale: Double = 0
    @State var offsetY: Double = -200

    var body: some View
    {
        VStack
        {
            Image("bitcoin")
                .offset(x: 0, y: CGFloat(offsetY))
                .scaleEffect(CGFloat(scale))
                .rotation3DEffect(.degrees(angle), axis: (x: 0, y: 1, z: 0))
                .animation(.interpolatingSpring(stiffness: 100, damping: 10))
            
            Divider().fixedSize()
            
            Button(action:
            {
                if(self.angle == 0)
                {
                    self.offsetY = 0
                    self.scale = 1
                    self.angle = 360*10
                }
                else
                {
                    self.offsetY = -200
                    self.scale = 0
                    self.angle = 0
                }
            }) {
                Text("Rotation Effect")
            }
        }
    }
}

色变动画
struct ContentView : View
{
    @State var rotation: Bool = false

    var body: some View
    {
        VStack
        {
            Image("couples")
                .background(LinearGradient(gradient: Gradient(colors: [.blue, .red, .green]), startPoint: .topTrailing, endPoint: .bottomLeading))
                .hueRotation(.degrees(rotation ? 720 : 0))
                .animation(.linear(duration: 3))
            
            Divider().fixedSize()
            
            Button(action:
            {
                self.rotation.toggle()
            }) {
                Text("Start animation")
            }
        }
    }
}

AngularGradientAnimation
struct ContentView : View
{
    @State var shouldRotate = false

    var body: some View
    {
        ZStack
        {
            Circle()
                .stroke(style: .init(lineWidth: 50))
                .fill(AngularGradient(
                    gradient: Gradient(colors: [.red, .orange, .yellow, .blue, .green, .purple, .red]),
                    center: .center))
                .padding(40)
                .rotationEffect(.degrees(shouldRotate ? 720 : 0))
                .animation(.easeInOut(duration: 4))
            
            Button(action:
            {
                self.shouldRotate.toggle()
            }) {
                Text("Rock and roll")
            }
        }
    }
}

圆形收缩动画

struct ContentView : View
{
    @State var isAnimating: Bool = false

    var body: some View
    {
        VStack
        {
            Image("05")
                .clipShape(
                    Circle()
                        .inset(by: isAnimating ? 120 : 0)
                        .offset(x: isAnimating ? 30 : 0, y: isAnimating ? -100 : 0)
                )
                .animation(.easeOut(duration: 2))
            
            Divider().fixedSize()
            
            Button(action:
            {
                self.isAnimating.toggle()
            }) {
                Text("Start animation")
            }.foregroundColor(.red)
        }
    }
}

遮罩扫描动画
ZStack
{
    // 图片的遮罩
    Image("Picture")
        .blur(radius: 6)
        .brightness(0.4)
    
    Image("Picture")
        .clipShape(Rectangle()
            .size(CGSize(width: 340, height: 100))
            .offset(x: 0, y: isAnimating ? 590 : -100))
        .animation(.linear(duration: 2))
        .onTapGesture
        {
            self.isAnimating.toggle()
        }
}

万花筒

struct ContentView : View {
    
    @State private var shouldRotate: Bool = false
    @State private var shouldScale: Bool = false

    var body: some View {
        
        CircleCapsule()
            .rotationEffect(.degrees(shouldRotate ? 0 : 360), anchor: .center)
            .scaleEffect(shouldScale ? 0.2 : 1)
            .animation(.easeInOut(duration: 4))
            .onTapGesture {
                self.shouldRotate.toggle()
                self.shouldScale.toggle()
        }
        
        CircleCapsule()
            .rotationEffect(.degrees(shouldRotate ? 0 : 360), anchor: .center)
            .scaleEffect(shouldScale ? 0.2 : 1)
            .onTapGesture  {
                withAnimation(.easeInOut(duration: 2))
                {
                    self.shouldRotate.toggle()
                    self.shouldScale.toggle()
                }

        }
    }
}
 
struct CircleCapsule: View
{
    var body: some View
    {
        ZStack
        {
            NewCapsule(color: .red, degree: 0)
            NewCapsule(color: .red, degree: 45)
            NewCapsule(color: .yellow, degree: 90)
            NewCapsule(color: .yellow, degree: 135)
            NewCapsule(color: .blue, degree: 180)
            NewCapsule(color: .blue, degree: 225)
            NewCapsule(color: .green, degree: 270)
            NewCapsule(color: .green, degree: 315)
        }
    }
}
struct NewCapsule: View {
    
    var color : Color
    var degree : Double
    
    var body: some View {
        Capsule()
            .foregroundColor(color)
            .frame(width : 60, height: 90)
            .offset(x: 0, y: 60)
            .opacity(0.75)
            .rotationEffect(.degrees(degree))
    }
}


Sequence


struct ContentView: View
{
    @State var offsetX: CGFloat = 0
    
    let colors : [Color] = [.red, .orange, .yellow, .green, .blue]
    let animations : [Animation] =
        [Animation.interpolatingSpring(stiffness: 100, damping: 10),
         Animation.interpolatingSpring(stiffness: 100, damping: 10).delay(0.3),
         Animation.interpolatingSpring(stiffness: 100, damping: 10).delay(0.6),
         Animation.interpolatingSpring(stiffness: 100, damping: 10).delay(0.9),
         Animation.interpolatingSpring(stiffness: 100, damping: 10).delay(1.2)]
    
    var body: some View
    {
        VStack
        {
            List(0..<5)
            { item in
                Rectangle()
                    .fill(self.colors[item])
                    .frame(width:50, height:50)
                    .offset(x: self.offsetX, y: 0)
                    .animation(self.animations[item])
            }
            
            Button(action: {
                self.offsetX += 200
            }) {
                Text("Start animation")
            }
        }
    }
}

电动履带动画
struct ContentView : View
{
    @State private var isAnimating = false
    
    var body: some View
    {
        ZStack
        {
            Capsule()
                .stroke(Color.orange,
                        style: StrokeStyle(lineWidth: 10,
                                             lineCap: .butt,
                                            lineJoin: .bevel,
                                          miterLimit: 10,
                                                dash: [20,11],
                                           dashPhase: isAnimating ? 200 : 0))
                .frame(width : 300, height:100)
                .animation(.easeInOut(duration: 3))
            
            Button(action: {
                self.isAnimating.toggle()
            }) {
                Text("Rock and roll")
            }
        }
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/996951.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-21
下一篇2022-05-21

发表评论

登录后才能评论

评论列表(0条)

    保存