• SwiftUI 动画


    import SwiftUI
    
    struct Demo01: View {
        @State private var enable = false
        var body: some View {
            demo01
    //        demo02
    //        demo03
    //        demo04
    //        demo05
    //        demo06
    //        demo07
        }
        
        var demo01 : some View{
            VStack(alignment: .center, spacing: 0) {
    //            Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
    //                .font(.title)
    //                .padding()
    //            Text("Animation")
    //                .font(.title2)
    //                .foregroundColor(.red)
    //                .fontWeight(.bold)
    //                .scaleEffect(enable ? 3.0 : 1.0)
    //                .animation(.default.repeatForever())//repeatForever永远重复
    //                .padding()
                Image(systemName: "heart.fill")
                    .foregroundColor(.red)
                    .font(.largeTitle)
                    .scaleEffect(enable ? 5.0 : 1.0)
                    .animation(
                        .timingCurve(0.76, 0, 0.24, 1,duration: 1)
                            .repeatForever()
                    )
            }
            .onAppear {
                enable = true
            }
        }
        //隐式声明动画
        var demo02 : some View{
            VStack(spacing: 50){
                RoundedRectangle(cornerRadius: enable ? 200 : 0)
    //                .fill(enable ? .red : .green)
    //                .opacity(enable ? 1.0 : 0.3)//透明度
    //                .animation(.default)
    //                .animation(.linear)
    //                .animation(.easeIn)
    //                .animation(.easeOut)
    //                .animation(.easeInOut)
    //                .animation(.spring())
    //                .animation(.timingCurve(0.87, 0, 0.13, 1,duration: 1))//时间曲线 easings.net
    //                .animation(.interactiveSpring())
                    .animation(.interpolatingSpring(mass: 0.7, stiffness: 200, damping: 5, initialVelocity: 4))//弹性动画 kiteapp.co
                    .frame( 300, height: 300, alignment: .center)
                Button {
                    enable.toggle()
                } label: {
                    Text("执行动画")
                }
    
            }
        }
        //显式声明动画
        @State private var state1 = false
        @State private var state2 = false
        @State private var state3 = false
        var demo03 : some View {
            VStack(spacing: 50){
                RoundedRectangle(cornerRadius: state1 ? 200 : 0)
                    .fill(state2 ? .red : .green)
                    .opacity(state3 ? 1.0 : 0.3)//透明度
                    .frame( 300, height: 300, alignment: .center)
                Button {
                    //显示的声明动画
                    withAnimation (.linear) {
                        state3.toggle()
                    }
                    state2.toggle()
                    state1.toggle()
                } label: {
                    Text("执行动画")
                }
    
            }
        }
        
        var demo04 : some View {
            VStack(spacing: 50){
                RoundedRectangle(cornerRadius: enable ? 200 : 0)
                    .fill(enable ? .red : .green)
                    .opacity(enable ? 1.0 : 0.3)//透明度
                    .animation(
                        .linear
    //                        .delay(5)//延迟5秒执行动画
    //                        .repeatCount(7)//动画执行次数
                            .repeatForever()//永远重复执行
    //                        .repeatForever(autoreverses: false)//不返回执行
                            .speed(3)//动画执行速度
                    )
                    .frame( 300, height: 300, alignment: .center)
                
                Button {
                    enable.toggle()
                } label: {
                    Text("执行动画")
                }
    
            }
        }
        
        @State private var isShow = true
        var demo05 : some View{
            Form{
                HStack {
                    if isShow{
                        Text("标题1")
                    }
                    Spacer()
                    Toggle(isOn: $isShow) {
                        Text("")
                    }
                    .onChange(of: isShow) { newValue in
                        withAnimation {
                            isShow.toggle()
                        }
                    }
                    .labelsHidden()
                }
                HStack {
                    if isShow{
                        Text("标题2")
                    }
                    Spacer()
                    Toggle(isOn: $isShow.animation(.linear)) {
                        Text("")
                    }
                    .labelsHidden()
                }
            }
        }
        
        
        @State private var state4 = false
        var width : CGFloat {
            state4 ? 100 : 50
        }
        var demo06 : some View {
            VStack(spacing : 50) {
                HStack {
                    Text("color")
                    Spacer()
                    Rectangle()
                        .fill(state4 ? .red : .green)
                        .frame( 100, height: 100)
                }
                
                HStack {
                    Text("size")
                    Spacer()
                    Rectangle()
                        .fill(.purple)
                        .frame( width, height: width)
                    Rectangle()
                        .fill(.yellow)
                        .frame( 100, height: 100)
                        .scaleEffect(state4 ? 1 : 0.5)
                }
                HStack {
                    Text("opacity")
                    Spacer()
                    Rectangle()
                        .fill(.blue)
                        .frame( 100, height: 100)
                        .opacity(state4 ? 1.0 : 0)
                }
                HStack {
                    Text("border")
                    Spacer()
                    Rectangle()
                        .fill(.orange)
                        .frame( 100, height: 100, alignment: .center)
                        .border(.green, state4 ? 10 : 2)
                    Circle()
                        .fill(.orange)
                        .frame( 100, height: 100, alignment: .center)
                        .overlay(
                            Circle()
                                .strokeBorder(.blue,lineWidth: state4 ? 10 : 2)
                        )
                }
                HStack {
                    Text("opacity")
                    Spacer()
                    Rectangle()
                        .fill(.blue)
                        .frame( 100, height: 100)
                        .cornerRadius(state4 ? 30 : 0)
                }
                HStack {
                    Text("opacity")
                    Spacer()
                    Rectangle()
                        .fill(.red)
                        .frame( 100, height: 100)
                        .rotationEffect(.degrees(state4 ? 360 : 0))
                        
                }
                
            }
            .animation(.linear(duration: 2).repeatForever())
            .padding()
            .font(.title)
            .onAppear {
                state4 = true
            }
        }
        
        let letters = Array("阿巴阿巴阿巴阿巴阿巴")
        @State private var dragPosition : CGSize = .zero
        var demo07 : some View {
            HStack {
                ForEach(0..<letters.count){
                    Text(String(letters[$0]))
                        .padding(5)
                        .font(.title)
                        .textCase(.uppercase)
                        .background(state4 ? Color.blue : Color.red)
                        .offset(dragPosition)
                        .animation(.linear.delay(Double($0)/20))
                }
            }
            .gesture(
                    DragGesture()
                        .onChanged({ po in
                            self.dragPosition = po.translation
                        })
                        .onEnded({ _ in
                            self.dragPosition = .zero
                            self.state4.toggle()
                        })
    //                    .onChanged{
    //                        self.dragPosition = $0.translation
    //                    }
    //                    .onEnded{_ in
    //                        self.dragPosition = .zero
    //                        self.state4.toggle()
    //                    }
            )
        }
    }
    
    
    struct Demo02: View {
        var body: some View {
    //        demo01//水波纹开始按钮
    //        demo02//点赞红心效果
    //        demo03//圆圈加载loading
    //        demo04//圆形进度条
    //        demo05//条形进度条
    //        demo06//跑马灯
    //        demo07//Transition通过combined组合动画(preview效果不如模拟器效果好)
            demo08//Transition自定义扩展动画
        }
        
        
        @State private var state1 = false
        var demo01 : some View {
            Button("开始") {
                state1 = true
            }
            .padding(50)
            .background(Color.red)
            .foregroundColor(Color.white)
            .clipShape(Circle())
            .overlay(
                Circle()
                    .stroke(Color.red)
                    .scaleEffect(state1 ? 2.0 : 1.0)
                    .opacity(state1 ? 0 : 1)
                    .animation(.easeInOut(duration: 1).repeatForever(autoreverses: false))
            )
        }
        
        var demo02 : some View {
            Image(systemName: "heart.fill")
                .font(.title)
                .foregroundColor(.red)
                .scaleEffect(state1 ? 3 : 1)
                .opacity(state1 ? 1 : 0.2)
                .animation(.interpolatingSpring(mass: 0.7, stiffness: 200, damping: 10, initialVelocity: 4).repeatForever(autoreverses: false))
                .onAppear {
                    state1 = true
                }
        }
        
        let strokestyle = StrokeStyle(lineWidth:2,lineCap: .round)
        var demo03 : some View {
            VStack{
    //            ProgressView()
                demo03_1
                
            }
            .frame( 30, height: 30, alignment: .center)
            .padding()
            .background(Color.white)
            .shadow(radius: 3.0)
        }
        var demo03_1 : some View {
            VStack{
                Circle()
                    .trim(from: 0.0, to: 0.7)
                    .stroke(
                        AngularGradient(gradient: Gradient(colors: [Color.gray,Color.gray.opacity(0.5)]), center: .center),style: strokestyle)
                    .rotationEffect(.degrees(state1 ? 360.0 : 0.0))
                    .animation(.linear(duration: 0.7).repeatForever(autoreverses: false))
                    .onAppear {
                        state1.toggle()
                    }
            }
        }
        
        let timer = Timer.publish(every: 1, on: RunLoop.main, in: .common).autoconnect()
        @State private var progress : CGFloat = 0
        var demo04 : some View{
            ZStack {
                Circle()
                    .stroke(Color.gray.opacity(0.3),style: strokestyle)
                Circle()
                    .trim(from: 0.0, to: self.progress)
                    .stroke(Color.gray,style: strokestyle)
                    .animation(.default)
                    .rotationEffect(.degrees(-90))
                    .onReceive(timer) { _ in
                        self.progress += 0.1
                        if self.progress > 1 {
                            self.progress = 0
                        }
                    }
            }
            .frame( 30, height: 30, alignment: .center)
            .padding()
            .background(Color.white)
            .shadow(radius: 3.0)
        }
        
        
        @State private var barWidth : CGFloat = 300.0
        @State private var progressWidth : CGFloat = 0.0
        var demo05 : some View {
            ZStack {
                Capsule()
                    .stroke(Color.gray)
                    .frame( barWidth, height: 20)
                    .overlay(
                        VStack(alignment: .leading) {
                            Capsule()
                            .fill(Color.gray)
                            .frame( progressWidth, height: 15, alignment: .leading)
                            .padding(.horizontal,5)
                            .animation(.linear)
                        }
                            .frame( barWidth, height: 20, alignment: .leading)
                    )
                    .onReceive(timer) { _ in
                        self.progressWidth += 5
                        if self.progressWidth >= barWidth{
                            self.progressWidth = 0.0
                        }
                    }
            }
            
        }
        
        @State private var scrollText = false
        var demo06 : some View {
            Text("好难啊,秃头了,阿巴阿巴阿巴")
                .foregroundColor(.red)
                .offset(x: scrollText ? 400 : 0)
                .animation(.linear(duration: 30).speed(10).repeatForever(autoreverses: false))
    //            .frame(maxWidth: .infinity, alignment: .leading)
                .onAppear {
                    scrollText.toggle()
                }
        }
        
        
        @State private var showText = true
        var demo07 : some View {
            Button {
                withAnimation {
                    showText.toggle()
                }
            } label: {
                ZStack {
                    Rectangle()
                        .fill(Color.clear)
                        .frame( 150, height: 60)
                        .border(.red, 4)
                    if showText {
                        Text("按钮")
                            .font(.largeTitle)
                            .transition(.move(edge: .top).combined(with: .opacity.combined(with: .scale)))
                    }
                }
            }
    
        }
        
        var demo08 : some View {
            Button {
                withAnimation {
                    showText.toggle()
                }
            } label: {
                ZStack {
                    Rectangle()
                        .fill(Color.clear)
                        .frame( 150, height: 60)
                        .border(.red, 4)
                    if showText {
                        Text("按钮")
                            .font(.largeTitle)
                            .transition(.moveInScaleOut)
    //                        .transition(.moveWithFade)
                    }
                }
            }
        }
    }
    
    extension AnyTransition {
        static var moveWithFade : AnyTransition {
            return AnyTransition.move(edge: .top).combined(with: .opacity).combined(with: .scale)
        }
    }
    
    extension AnyTransition {
        static var moveInScaleOut : AnyTransition {
            let insertion = AnyTransition.move(edge: .top).combined(with: .opacity)
            let removal = AnyTransition.scale.combined(with: .opacity)
            return AnyTransition.asymmetric(insertion: insertion, removal: removal)
        }
    }
    
    struct Demo01_Previews: PreviewProvider {
        static var previews: some View {
    //        Demo01()
            Demo02()
        }
    }
    
    
    
  • 相关阅读:
    黄金连分数
    第39级台阶
    四、绘图可视化之Seaborn
    三、绘图和可视化之matplotlib
    二、pandas入门
    python_111_动态导入模块
    爬虫_python3_抓取猫眼电影top100
    爬虫_python3_urllib
    python_112_网络编程 Socket编程
    python_111_异常处理
  • 原文地址:https://www.cnblogs.com/chaostudy/p/15044638.html
Copyright © 2020-2023  润新知