SwiftUI中如何实现RoundedRectangle的Trim永久旋转动画?
解决方案:实现圆角矩形Trim片段的流畅循环游动动画
要实现你想要的两条蛇依次沿圆角矩形边缘移动的效果,核心是通过动态调整trim的from和to参数,配合持续的线性动画进度来驱动,而非依赖布尔值切换和旋转缩放。以下是修改后的代码:
import SwiftUI struct SnakeTrimAnimationView: View { // 示例渐变颜色 private let colors: [Color] = [.blue, .purple, .pink] // 动画进度值,从0到1循环递增 @State private var progress = 0.0 // 单个蛇形片段占总路径的比例 private let segmentLength = 0.25 // 两个片段的偏移差,实现依次移动的错开效果 private let segmentOffset = 0.5 var body: some View { ZStack { // 背景灰色圆角矩形 RoundedRectangle(cornerRadius: 20, style: .continuous) .foregroundColor(.gray.opacity(0.1)) .frame(width: 195, height: 50) // 第一条蛇形片段 RoundedRectangle(cornerRadius: 20, style: .continuous) .trim( from: progress.truncatingRemainder(dividingBy: 1), to: (progress + segmentLength).truncatingRemainder(dividingBy: 1) ) .stroke( LinearGradient(gradient: Gradient(colors: colors), startPoint: .topLeading, endPoint: .bottomTrailing), style: StrokeStyle(lineWidth: 3, lineCap: .round) ) .frame(width: 195, height: 50) // 第二条蛇形片段(偏移半程,实现依次移动) RoundedRectangle(cornerRadius: 20, style: .continuous) .trim( from: (progress + segmentOffset).truncatingRemainder(dividingBy: 1), to: (progress + segmentOffset + segmentLength).truncatingRemainder(dividingBy: 1) ) .stroke( LinearGradient(gradient: Gradient(colors: colors), startPoint: .topLeading, endPoint: .bottomTrailing), style: StrokeStyle(lineWidth: 3, lineCap: .round) ) .frame(width: 195, height: 50) // 标题文本 Text("title") .foregroundStyle(LinearGradient(gradient: Gradient(colors: colors), startPoint: .topLeading, endPoint: .bottomTrailing)) } .onAppear { // 启动永久循环的线性动画 withAnimation(.linear(duration: 4).repeatForever(autoreverses: false)) { progress = 1.0 } } } } #Preview { SnakeTrimAnimationView() }
关键修改说明:
- 用
progress进度值替代布尔值:通过从0到1的持续递增进度,精准控制trim的起始和结束位置,实现平滑的路径移动。 - 循环路径计算:利用
truncatingRemainder(dividingBy: 1)让进度值超过1后自动归零,形成无限循环的动画。 - 片段偏移设置:第二条片段的进度加上
segmentOffset(0.5),让两个片段始终保持半程距离,实现"依次移动"的蛇形效果。 - 统一帧尺寸:去掉原代码中动态缩放的逻辑,让trim片段始终贴合背景矩形的边缘,避免变形。
- 渐变描边:将渐变直接应用到stroke上,让蛇形片段的颜色和标题保持一致。
你可以调整duration(动画时长)和segmentLength(片段长度)来控制动画的速度和片段大小,适配你想要的视觉效果。
内容的提问来源于stack exchange,提问作者Rares
相关产品推荐
相关产品推荐

