Swift combine radial gradients
Asked Answered
C

1

7

Imagine a couple radial gradients with some radius scattered in a plane. The centers of the gradients arranged like this, for example:

A     D
  B 
    C
E     F

Now coming out of each of these centers is a radial gradient with some radius. I know how to create the gradients, but I am wondering how to combine these gradients when they overlap.

This above arrangement would look like the following image. As you can see, there is a red radial gradient at (0,0), blue at (3,0), yellow at (1,1), red at (2,2), etc, and they are all blended together. Additionally, there are varying radii containing each gradient.

Desired effect 1

Here is an example for what the blending of radial gradients in the following arrangement would look like:

       B


A

Desired effect 2

I have tried to find reading about this, but there are surprisingly very few hits (only 5 or 6), all of which are how to do this in Illustrator or Photoshop. I have also tried to program my own, but the problem is that I do not know what to do when it comes to the intersection of gradients; averaging the colors is wrong and comes out choppy, and that is what my (rather long) first attempt did.

How could I achieve this effect where the gradients are blended together on iOS in Swift? Any suggestions, references, or anything is greatly appreciate

Corruptible answered 7/2, 2018 at 3:43 Comment(5)
To me it feels like using gradients is the wrong thing to do, particularly if you wish to (a) copy an effect that Photoshop (with their vastly greater resources) does. If you wish to go that route, then think GPU, be it GPUImage or CoreImage. Instead, the easier route to go is look at your sample image as simply blurred... what would it look like unblurred? Start with that. Blur it. Understand you'll have limitations. An unblurred-but-gradient background with 2-3 circular colored areas... than blurred will get you close. Trying to force a UIKit view to mimic what Photoshop does? I wouldn't.Ashly
Why the downvote? Unexplained downvotes don’t help me fix my question!Corruptible
The down vote wasn't me.... I thought you gave enough specifics, including something about what you've tried. My comment was an attempt to steer you in a different direction, as (a) I don't have any feedback of help in the direction you've been headed in and (b) when I hear "choppy" I think you've come up against something that may be insurmountable. Keep in mind that Photoshop is a much larger app that likely utilizes things I already mentioned (like directly coding in the GPU) along with proprietary code.Ashly
@dfd sorry that wasn’t meant to be directed at you. I guess it automatically sent to you because you were the only commentor.Corruptible
And you had every right to think it was me - like you said, I was the only commentor. Peace. I hope you figure out how to get this working. (And I do down vote questions, sometimes without a comment. Just not this time!)Ashly
N
0

It's not UIKit but if you want to do this in SwiftUI you can easily do this using a ZStack of rectangles with radial gradients as the fill and blend them together. Using state you can even animate them to your liking.

import SwiftUI

struct ContentView: View {
    @State var show = false

    var body: some View {
        VStack{
            ZStack{
                Rectangle()
                    .fill(Color.white)
                    .frame(width: 300, height: 200)
                Rectangle()
                    .fill(RadialGradient(gradient: Gradient(colors: [.orange, .white]), center: show ? UnitPoint(x: 0.3, y: 0.3) : UnitPoint(x: -0.3, y: -1.0), startRadius: 5, endRadius: 100))
                    .animation(.easeInOut(duration: 0.5))
                    .frame(width: 300, height: 200)
                Rectangle()
                    .fill(RadialGradient(gradient: Gradient(colors: [.yellow, .white]), center: show ? UnitPoint(x: 0.75, y: 0.75) : UnitPoint(x: 2.0, y: 2.0), startRadius: 5, endRadius: 150))
                    .animation(.easeInOut(duration: 0.5))
                    .frame(width: 300, height: 200)
                Rectangle()
                    .fill(RadialGradient(gradient: Gradient(colors: [.purple, .white]), center: show ? UnitPoint(x: 0.0, y: 0.75) : UnitPoint(x: 0.0, y: 2.0), startRadius: 5, endRadius: 100))
                    .animation(.easeInOut(duration: 0.5))
                    .frame(width: 300, height: 200)
                Rectangle()
                    .fill(RadialGradient(gradient: Gradient(colors: [.green, .white]), center: show ? UnitPoint(x: 0.75, y: 0.0) : UnitPoint(x: 1.0, y: -2.0), startRadius: 5, endRadius: 50))
                    .animation(.easeInOut(duration: 0.5))
                    .frame(width: 300, height: 200)
            }
            .blur(radius: 20)
            .blendMode(.multiply)
            .clipped()
            .cornerRadius(10)
            .shadow(color: Color.gray.opacity(0.5), radius: 5, y: 2)

            Toggle(isOn: $show) {
                Text("text")
            }
        }
    }
}
Narration answered 20/9, 2019 at 14:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.