Preview:
//
//  RotationTextViewDemo.swift
//  SwiftUIDemo
//
//  Created by shiyanjun on 2023/2/9.
//

import SwiftUI

struct SealViewDemo: View {
    let textArr: [String] = "北京百度网讯科技有限公司".map({String($0)})
    @State var textSize: Double = 30.0
    @State var circleLineWidth: Double = 7.0
    @State var circleRadius: CGFloat = 233
    @State var textCircleRadius: CGFloat = 90
    @State var starSize: Double = 50.0
    @State var rotationDegress: Double = 20
    @State var firstTextPox: Double = 110
    
    init() {
        // 每个字的旋转角度 = 第一个字的旋转角度的两倍/文字个数
        self.rotationDegress = 110*2.0/Double(textArr.count)
    }
    
    var body: some View {
        ZStack {
            Color.white.edgesIgnoringSafeArea(.all)
            
            VStack {
                ZStack {
                    Circle()
                        .stroke(.red, lineWidth: circleLineWidth)
                        .frame(width: circleRadius)
                    
                    ForEach(0..<textArr.count) { index in
                        RoundTextView(
                            text: textArr[index],
                            foregroundColor: .red,
                            degrees: getDegress(firstTextPox: firstTextPox,
                                                rotationDegress: rotationDegress,
                                                index: index),
                            textSize: $textSize,
                            textCircleRadius: $textCircleRadius)
                    }
                    
                    Image(systemName: "star.fill")
                        .resizable()
                        .frame(width: starSize, height: starSize)
                        .foregroundColor(.red)
                }
                
                
                VStack(alignment: .leading) {
                    VStack(alignment: .leading) {
                        Text("文字大小:\(String(format: "%.2f", textSize))")
                            .font(.system(.headline))
                        Slider(value: $textSize, in: 20...50, step: 1)
                        
                        Text("圆环宽度:\(String(format: "%.2f", circleLineWidth))")
                            .font(.system(.headline))
                        Slider(value: $circleLineWidth, in: 1...30, step: 1)
                        
                        Text("圆环半径:\(String(format: "%.2f", circleRadius))")
                            .font(.system(.headline))
                        Slider(value: $circleRadius, in: 200...300, step: 1)
                        Text("文字圆环半径:\(String(format: "%.2f", textCircleRadius))")
                            .font(.system(.headline))
                        Slider(value: $textCircleRadius, in: 50...150, step: 1)
                    }
                    
                    VStack(alignment: .leading) {
                        Text("五角星大小:\(String(format: "%.2f", starSize))")
                            .font(.system(.headline))
                        Slider(value: $starSize, in: 20...80, step: 1)
                        
                        Text("文字间距:\(String(format: "%.2f", rotationDegress))")
                            .font(.system(.headline))
                        Slider(value: $rotationDegress, in: 15...60, step: 1)
                        
                        Text("首字位置:\(String(format: "%.2f", firstTextPox))")
                            .font(.system(.headline))
                        Slider(value: $firstTextPox, in: 90...150, step: 1)
                    }
                    
                }
            }
            .padding()
        }
    }
}

struct RotationTextViewDemo_Previews: PreviewProvider {
    static var previews: some View {
        SealViewDemo()
    }
}

// 获取当前文字的旋转角度
func getDegress(firstTextPox: Double, rotationDegress: Double, index: Int) -> Double {
    // 首字旋转角度 + 该字的索引 * 每个字的旋转角度
    return -firstTextPox + Double(index) * rotationDegress
}

struct RoundTextView: View {
    var text: String
    var foregroundColor: Color
    var degrees: Double
    @Binding var textSize: Double
    @Binding var textCircleRadius: CGFloat
    
    var body: some View {
        Text(text)
            .font(.system(size: textSize))
            .offset(y: -textCircleRadius)
            .foregroundColor(foregroundColor)
            .rotationEffect(Angle(degrees: degrees))
    }
}
downloadDownload PNG downloadDownload JPEG downloadDownload SVG

Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!

Click to optimize width for Twitter