传统的七夕快到了,作为一个程序猿,最浪漫的礼物当然是自己写的啦!
思来想去也不知道写什么好,在某天在某音上学习时看到点赞的动画效果还不错,那不如就做一个表达爱意的动画吧。
说干就干。
项目搭建
首先,创建一个新的SwiftUI
项目,命名为LoveAnimation
。
逻辑分析
我们先分析下整个点赞效果的逻辑,当我们点击“白色爱心”时,会冒出很多“红色爱心”出来,并且呈现的效果是出现后向上随机散开后消失。
如果我们需要实现这个效果,那么不妨设想下实现过程,先有一个“白色爱心”,然后使用ZStack
层叠视图覆盖一层“红色爱心”,当点击“白色爱心”时触发交互动画,“红色爱心”在出现时增加交互效果,实现向上随机散开后消失。
页面样式
页面样式部分,我们可以创建两个心形视图。示例:
struct ContentView: View {
@State var loveCount = 0
func TapAction() {
loveCount += 1
}
var body: some View {
ZStack {
Color.black.ignoresSafeArea()
VStack(alignment: .center, spacing: 40) {
ZStack {
Image(systemName: "heart.fill")
.resizable()
.foregroundColor(.white)
.frame(width: 120, height: 120)
.padding()
.onTapGesture {
TapAction()
}
ForEach(0 ..< loveCount, id: \.self) { _ in
Image(systemName: "heart.fill")
.resizable()
.frame(width: 120, height: 120)
.padding()
}
}
Text("我喜欢你")
.font(.largeTitle)
.foregroundColor(.white)
}
}
}
}
上述代码中,我们声明了一个变量loveCount
来存储心形的数量,然后定义了一个方法TapAction
,当我们点击的时候,loveCount
心形数量增加。
样式部分我们将背景变成黑色,然后绘制了一个白色的心形,再使用ZStack
包裹了一个红色的心形,当白色的心形点击时,调用TapAction
方法。
初步的样式就完成了。
动画逻辑
页面比较简单,我们接下来完成动画逻辑部分。
import SwiftUI
struct LoveGeometryEffect : GeometryEffect {
var time : Double
var speed = Double.random(in: 100 ... 200)
var xDirection = Double.random(in: -0.1 ... 0.1)
var yDirection = Double.random(in: -Double.pi ... 0)
var animatableData: Double {
get { time }
set { time = newValue }
}
func effectValue(size: CGSize) -> ProjectionTransform {
let xTranslation = speed * xDirection
let yTranslation = speed * sin(yDirection) * time
let affineTranslation = CGAffineTransform(translationX: xTranslation, y: yTranslation)
return ProjectionTransform(affineTranslation)
}
}
上述代码中,我们创建了一个爱心动画LoveGeometryEffect
,它遵循GeometryEffect
协议。
我们首先声明了4个变量,分别是时间time、速度speed、X轴出现的位置xDirection,Y轴出现的位置yDirection。
其中,speed、xDirection、yDirection
都使用随机数,这样我们就能实现线性出现的效果,不至于那么死板。
然后使用get、set
属性,在获得time
初始值时,调用了get
属性计算出的新值。
最后我们定义了一个方法effectValue
返回一个ProjectionTransform
投影转换效果,来实现红色爱心的移动效果。
视图修饰符
有了交互动画逻辑后,我们可以创建一个视图修饰符,用于之后修饰我们的红色爱心视图。示例:
import SwiftUI
struct LoveTapModifier: ViewModifier {
@State var time = 0.0
let duration = 1.0
func body(content: Content) -> some View {
ZStack {
content
.foregroundColor(.red)
.modifier(LoveGeometryEffect(time: time))
.opacity(time == 1 ? 0 : 1)
}
.onAppear {
withAnimation (.easeOut(duration: duration)) {
self.time = duration
}
}
}
}
上述代码中,我们创建了一个视图修饰LoveTapModifier
,它的内容包含设置视图的填充色为红色,并使用之前创建好的LoveGeometryEffect
动画进行修饰。
为了让红色爱心出现后跟随时间逐渐消失,我们使用opacity
修饰符,让视图跟随时间慢慢隐藏。
效果呈现
完成后,我们将LoveTapModifier
修饰符作用在红色心形视图上。示例:
.modifier(LoveTapModifier())
不错不错!
赶紧发给喜欢的女生,收一张好人卡先。
如果本专栏对你有帮助,不妨点赞、评论、关注~
我正在参加「创意开发 投稿大赛」详情请看:掘金创意开发大赛来了!