Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI Circular Stroke Gradient

I have implemented a circular stroke as you can see in the picture below (of course without the numbers 😉).

Unfortunately, I encounter two problems that you may be able to help me with.

  1. I want the gradient to go along the line, i.e. the darkest point in this picture should always be at the end of the stroke (1b) and not as currently at (1a)

  2. Is it possible to give a stroke a lineCap .round on one side and a lineCap .butt on the other side? I would like to have a rounded line end at (1b) and a straight line at (2), which corresponds to .butt.

Here is my example code

struct CircularGradientLine: View {
    private let gradient = LinearGradient(
        gradient: Gradient(colors: [StyleGuide.Color.primary, .white]),
        startPoint: .leading,
        endPoint: .trailing)
    public var body: some View {
        ZStack {
            Circle()
                .stroke(Color.white, lineWidth: 46)

            Circle()
                .trim(from: 0, to: CGFloat(0.8))
                .stroke(gradient, style:
                    StrokeStyle(lineWidth: 46,
                                lineCap: .round))
        }.padding(60)
    }
}

I would be delighted if someone could help me there 😇

enter image description here

like image 317
Phillipp Avatar asked Jun 17 '20 11:06

Phillipp


2 Answers

for 1) you could try:

private let gradient = AngularGradient(
    gradient: Gradient(colors: [Color.blue, .white]),
    center: .center,
    startAngle: .degrees(270),
    endAngle: .degrees(0))

for 2) you could try something like this:

public var body: some View {
    ZStack {
        Circle().stroke(Color.white, lineWidth: 46)

        Circle()
            .trim(from: 0, to: CGFloat(0.8))
            .stroke(gradient, style: StrokeStyle(lineWidth: 46, lineCap: .round))
            .overlay(
                Circle().trim(from: 0, to: CGFloat(0.8))
                .rotation(Angle.degrees(-4))
                .stroke(gradient, style: StrokeStyle(lineWidth: 46, lineCap: .butt)))

    }.padding(60)
}
like image 113
workingdog support Ukraine Avatar answered Oct 21 '22 14:10

workingdog support Ukraine


For Nr.1 you could try lineJoin:

.stroke(Color.red, style: StrokeStyle(lineWidth: 10, lineCap: .round, lineJoin: .round))

For No.1: This sounds more challenging. Thinking out loud:

Since

AngularGradient(gradient: yourGradient, center: .bottomTrailing, angle: .degrees(0))

has an angle property you could adjust the angle with a value from stroke.

like image 31
Peter Pohlmann Avatar answered Oct 21 '22 15:10

Peter Pohlmann