design-ops / sketch-to-swiftUI

23 stars 5 forks source link

Applying multiple shadows to a view #35

Open kerrmarin opened 3 years ago

kerrmarin commented 3 years ago

In Sketch, you can apply multiple shadows to a layer. The shadows then "blend" in.

In SwiftUI, there is a modifier called shadow that adds a shadow to a layer. The problem is that when you apply more than one shadow modifier, each subsequent shadow is applied to the prior result so the second shadow is of the shape of the original view + the first shadow.

We currently apply shadows like:

        stylist.addStyle(identifier: "layer-shadows") {
            AnyView($0
                        .background(Color(red: 0.85, green: 0.85, blue: 0.85, opacity: 1)
                                        .shadow(color: Color(red: 0, green: 0, blue: 0, opacity: 0.5), radius: 3, x: 20, y: 20)
                                        .shadow(color: Color(red: 1, green: 0, blue: 0, opacity: 0.5), radius: 3, x: 10, y: 10)) // <- Will have the shape of the background + the shadow on the line above
            )
        }

Any ideas?

deanWombourne commented 3 years ago

This is shit, obviously, but I think it has the effect we want.

import SwiftUI

struct ShadowTest: View {

    var body: some View {

        let view = Text("Hello, World!")

        ZStack {
            view.background(Color(red: 0.85, green: 0.85, blue: 0.85, opacity: 1))
            view.shadow(color: Color(red: 0, green: 0, blue: 0, opacity: 0.5), radius: 3, x: 20, y: 20)
            view.shadow(color: Color(red: 1, green: 0, blue: 0, opacity: 0.5), radius: 3, x: 10, y: 10)
        }
    }
}

struct ShadowTest_Previews: PreviewProvider {
    static var previews: some View {
        ShadowTest()
            .previewLayout(.fixed(width: 200, height: 200))
    }
}

i.e. I'm drawing the main view (in my dumb example it's just text) three times - which is sub-optimal. Though, if we can get a snapshot of the view somehow, or if we can just get a shadow without the view itself needing to be rendered then this becomes more workable.

deanWombourne commented 3 years ago

^ Also, this won't work at all if the view is translucent - the translucent areas will just multiply each other and get darker.