swiftUI编写圣诞树三维旋转动画
二、编写环境三、代码实现 1、基础图形构建Xcode:13.1
macOS Monterey版本12.1
语言:swiftUI
首先,想象一下静态看到的圣诞树大概可以长成什么样子,反正我想的是下面这样🤔,那么,首先需要写的就是一根树枝。
一根树枝由什么构成呢,无非就是上面链接一个公共定点,下面放射出多段线,中间加两个圆点,以特定的角度旋转。
代码如下:
VStack(alignment: .center, spacing: 5) {
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "staroflife.fill")
.foregroundColor(.white)
}
.rotationEffect(.degrees(30),anchor: .top)
VStack(alignment: .center, spacing: 5) {
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "staroflife.fill")
.foregroundColor(.white)
}
.rotationEffect(.degrees(-30),anchor: .top)
可以改变颜色和角度,逐步实现的步骤图如下:
为基本图形添加三位旋转效果,让其绕着y轴旋转360度且一直重复,为不同的view添加不同的延迟时间
代码实现:
view(){
}
.rotation3DEffect(
.degrees(StartRotate ? 0 : 360),
axis: (x: 0.0, y: 1.0, z: 0.0),
anchor: .top,
perspective: 0.5
)
.animation(
.linear(duration: 7)
.delay(0.1)
.repeatForever(autoreverses: false)
)
3、背景图等修饰元素添加
Image("图片 1")
.resizable()
.frame(width: UIScreen.main.bounds.width * 1.2, height: UIScreen.main.bounds.height )
.edgesIgnoringSafeArea(.all)
四、完整代码
无非就是简单代码的堆叠,当然可以将重复的部分抽取成组件,但是我懒。。
//
// ContentView.swift
// ChristmasTree
//
// Created by 张原溥 on 2021/12/26.
//
import SwiftUI
struct ContentView: View {
@State var StartRotate = false
@State var SumAngle: Int = 40
var body: some View {
ZStack(alignment: .top) {
Image("图片 1")
.resizable()
.frame(width: UIScreen.main.bounds.width * 1.2, height: UIScreen.main.bounds.height )
.edgesIgnoringSafeArea(.all)
ZStack{
Rectangle()
.frame(width:1, height: 400)
.foregroundColor(.white)
.offset(y:50)
VStack {
Image(systemName: "star.fill")
.foregroundColor(Color.yellow)
ZStack (alignment: .top){
ZStack(alignment: .top) {
HStack(alignment: .top, spacing: 0.0) {
VStack(alignment: .center, spacing: 5) {
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "staroflife.fill")
.foregroundColor(.white)
}
.rotationEffect(.degrees(30),anchor: .top)
VStack(alignment: .center, spacing: 5) {
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "staroflife.fill")
.foregroundColor(.white)
}
.rotationEffect(.degrees(-30),anchor: .top)
}
.rotation3DEffect(.degrees(StartRotate ? 0 : 360), axis: (x: 0.0, y: 1.0, z: 0.0),anchor: .top,perspective: 0.5)
.animation(.linear(duration: 7).repeatForever(autoreverses: false))
HStack(alignment: .top, spacing: 0.0) {
VStack {
Rectangle()
.frame(width: 1, height: 250)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.yellow)
}
.rotationEffect(.degrees(35),anchor: .top)
VStack {
Rectangle()
.frame(width: 1, height: 250)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.yellow)
}
.rotationEffect(.degrees(-35),anchor: .top)
}
.frame(width: 1, height: 250)
.foregroundColor(.yellow)
.rotation3DEffect(.degrees(StartRotate ? 0 : 360), axis: (x: 0.0, y: 1.0, z: 0.0),anchor: .top,perspective: 0.5)
.animation(.linear(duration: 7).delay(0.1).repeatForever(autoreverses: false))
}
ZStack(alignment: .top) {
HStack(alignment: .top, spacing: 0.0) {
VStack(alignment: .center, spacing: 5) {
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "staroflife.fill")
.foregroundColor(.white)
}
.rotationEffect(.degrees(30),anchor: .top)
VStack(alignment: .center, spacing: 5) {
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "staroflife.fill")
.foregroundColor(.white)
}
.rotationEffect(.degrees(-30),anchor: .top)
}
.rotation3DEffect(.degrees(StartRotate ? 0 : 360), axis: (x: 0.0, y: 1.0, z: 0.0),anchor: .top,perspective: 0.5)
.animation(.linear(duration: 5).delay(0.2).repeatForever(autoreverses: false))
HStack(alignment: .top, spacing: 0.0) {
VStack {
Rectangle()
.frame(width: 1, height: 250)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.yellow)
}
.rotationEffect(.degrees(35),anchor: .top)
VStack {
Rectangle()
.frame(width: 1, height: 250)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.yellow)
}
.rotationEffect(.degrees(-35),anchor: .top)
}
.frame(width: 1, height: 250)
.foregroundColor(.yellow)
.rotation3DEffect(.degrees(StartRotate ? 0 : 360), axis: (x: 0.0, y: 1.0, z: 0.0),anchor: .top,perspective: 0.5)
.animation(.linear(duration: 7).delay(0.3).repeatForever(autoreverses: false))
}
ZStack(alignment: .top) {
HStack(alignment: .top, spacing: 0.0) {
VStack(alignment: .center, spacing: 5) {
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "staroflife.fill")
.foregroundColor(.white)
}
.rotationEffect(.degrees(30),anchor: .top)
VStack(alignment: .center, spacing: 5) {
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "staroflife.fill")
.foregroundColor(.white)
}
.rotationEffect(.degrees(-30),anchor: .top)
}
.rotation3DEffect(.degrees(StartRotate ? 0 : 360), axis: (x: 0.0, y: 1.0, z: 0.0),anchor: .top,perspective: 0.5)
.animation(.linear(duration: 5).delay(0.4).repeatForever(autoreverses: false))
HStack(alignment: .top, spacing: 0.0) {
VStack {
Rectangle()
.frame(width: 1, height: 250)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.yellow)
}
.rotationEffect(.degrees(35),anchor: .top)
VStack {
Rectangle()
.frame(width: 1, height: 250)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.yellow)
}
.rotationEffect(.degrees(-35),anchor: .top)
}
.frame(width: 1, height: 250)
.foregroundColor(.yellow)
.rotation3DEffect(.degrees(StartRotate ? 0 : 360), axis: (x: 0.0, y: 1.0, z: 0.0),anchor: .top,perspective: 0.5)
.animation(.linear(duration: 7).delay(0.5).repeatForever(autoreverses: false))
}
ZStack(alignment: .top) {
HStack(alignment: .top, spacing: 0.0) {
VStack(alignment: .center, spacing: 5) {
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "staroflife.fill")
.foregroundColor(.white)
}
.rotationEffect(.degrees(30),anchor: .top)
VStack(alignment: .center, spacing: 5) {
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "staroflife.fill")
.foregroundColor(.white)
}
.rotationEffect(.degrees(-30),anchor: .top)
}
.rotation3DEffect(.degrees(StartRotate ? 0 : 360), axis: (x: 0.0, y: 1.0, z: 0.0),anchor: .top,perspective: 0.5)
.animation(.linear(duration: 5).delay(0.6).repeatForever(autoreverses: false))
HStack(alignment: .top, spacing: 0.0) {
VStack {
Rectangle()
.frame(width: 1, height: 250)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.yellow)
}
.rotationEffect(.degrees(35),anchor: .top)
VStack {
Rectangle()
.frame(width: 1, height: 250)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.yellow)
}
.rotationEffect(.degrees(-35),anchor: .top)
}
.frame(width: 1, height: 250)
.foregroundColor(.yellow)
.rotation3DEffect(.degrees(StartRotate ? 0 : 360), axis: (x: 0.0, y: 1.0, z: 0.0),anchor: .top,perspective: 0.5)
.animation(.linear(duration: 7).delay(0.7).repeatForever(autoreverses: false))
}
ZStack(alignment: .top) {
HStack(alignment: .top, spacing: 0.0) {
VStack(alignment: .center, spacing: 5) {
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "staroflife.fill")
.foregroundColor(.white)
}
.rotationEffect(.degrees(30),anchor: .top)
VStack(alignment: .center, spacing: 5) {
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "staroflife.fill")
.foregroundColor(.white)
}
.rotationEffect(.degrees(-30),anchor: .top)
}
.rotation3DEffect(.degrees(StartRotate ? 0 : 360), axis: (x: 0.0, y: 1.0, z: 0.0),anchor: .top,perspective: 0.5)
.animation(.linear(duration: 5).delay(0.8).repeatForever(autoreverses: false))
HStack(alignment: .top, spacing: 0.0) {
VStack {
Rectangle()
.frame(width: 1, height: 250)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.yellow)
}
.rotationEffect(.degrees(35),anchor: .top)
VStack {
Rectangle()
.frame(width: 1, height: 250)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.yellow)
}
.rotationEffect(.degrees(-35),anchor: .top)
}
.frame(width: 1, height: 250)
.foregroundColor(.yellow)
.rotation3DEffect(.degrees(StartRotate ? 0 : 360), axis: (x: 0.0, y: 1.0, z: 0.0),anchor: .top,perspective: 0.5)
.animation(.linear(duration: 7).delay(0.9).repeatForever(autoreverses: false))
}
ZStack(alignment: .top) {
HStack(alignment: .top, spacing: 0.0) {
VStack(alignment: .center, spacing: 5) {
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "staroflife.fill")
.foregroundColor(.white)
}
.rotationEffect(.degrees(30),anchor: .top)
VStack(alignment: .center, spacing: 5) {
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "staroflife.fill")
.foregroundColor(.white)
}
.rotationEffect(.degrees(-30),anchor: .top)
}
.rotation3DEffect(.degrees(StartRotate ? 0 : 360), axis: (x: 0.0, y: 1.0, z: 0.0),anchor: .top,perspective: 0.5)
.animation(.linear(duration: 7).delay(1).repeatForever(autoreverses: false))
HStack(alignment: .top, spacing: 0.0) {
VStack {
Rectangle()
.frame(width: 1, height: 250)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.yellow)
}
.rotationEffect(.degrees(35),anchor: .top)
VStack {
Rectangle()
.frame(width: 1, height: 250)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.yellow)
}
.rotationEffect(.degrees(-35),anchor: .top)
}
.frame(width: 1, height: 250)
.foregroundColor(.yellow)
.rotation3DEffect(.degrees(StartRotate ? 0 : 360), axis: (x: 0.0, y: 1.0, z: 0.0),anchor: .top,perspective: 0.5)
.animation(.linear(duration: 7).delay(1.1).repeatForever(autoreverses: false))
}
ZStack(alignment: .top) {
HStack(alignment: .top, spacing: 0.0) {
VStack(alignment: .center, spacing: 5) {
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "staroflife.fill")
.foregroundColor(.white)
}
.rotationEffect(.degrees(30),anchor: .top)
VStack(alignment: .center, spacing: 5) {
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "staroflife.fill")
.foregroundColor(.white)
}
.rotationEffect(.degrees(-30),anchor: .top)
}
.rotation3DEffect(.degrees(StartRotate ? 0 : 360), axis: (x: 0.0, y: 1.0, z: 0.0),anchor: .top,perspective: 0.5)
.animation(.linear(duration: 7).delay(1.2).repeatForever(autoreverses: false))
HStack(alignment: .top, spacing: 0.0) {
VStack {
Rectangle()
.frame(width: 1, height: 250)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.yellow)
}
.rotationEffect(.degrees(35),anchor: .top)
VStack {
Rectangle()
.frame(width: 1, height: 250)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.yellow)
}
.rotationEffect(.degrees(-35),anchor: .top)
}
.frame(width: 1, height: 250)
.foregroundColor(.yellow)
.rotation3DEffect(.degrees(StartRotate ? 0 : 360), axis: (x: 0.0, y: 1.0, z: 0.0),anchor: .top,perspective: 0.5)
.animation(.linear(duration: 7).delay(1.3).repeatForever(autoreverses: false))
}
ZStack(alignment: .top) {
HStack(alignment: .top, spacing: 0.0) {
VStack(alignment: .center, spacing: 5) {
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "staroflife.fill")
.foregroundColor(.white)
}
.rotationEffect(.degrees(30),anchor: .top)
VStack(alignment: .center, spacing: 5) {
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.green)
Rectangle()
.frame(width:1, height: 80)
.foregroundColor(.green)
Image(systemName: "staroflife.fill")
.foregroundColor(.white)
}
.rotationEffect(.degrees(-30),anchor: .top)
}
.rotation3DEffect(.degrees(StartRotate ? 0 : 360), axis: (x: 0.0, y: 1.0, z: 0.0),anchor: .top,perspective: 0.5)
.animation(.linear(duration: 7).delay(1.4).repeatForever(autoreverses: false))
HStack(alignment: .top, spacing: 0.0) {
VStack {
Rectangle()
.frame(width: 1, height: 250)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.yellow)
}
.rotationEffect(.degrees(35),anchor: .top)
VStack {
Rectangle()
.frame(width: 1, height: 250)
Image(systemName: "circle.fill")
.resizable()
.frame(width: 5, height: 5)
.foregroundColor(.yellow)
}
.rotationEffect(.degrees(-35),anchor: .top)
}
.frame(width: 1, height: 250)
.foregroundColor(.yellow)
.rotation3DEffect(.degrees(StartRotate ? 0 : 360), axis: (x: 0.0, y: 1.0, z: 0.0),anchor: .top,perspective: 0.5)
.animation(.linear(duration: 7).delay(1.5).repeatForever(autoreverses: false))
}
}
}
.onAppear(perform: {
self.StartRotate.toggle()
})
}
.offset(y:250)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
.preferredColorScheme(.dark)
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)