TokamakUI / Tokamak

SwiftUI-compatible framework for building browser apps with WebAssembly and native apps for other platforms
Apache License 2.0
2.57k stars 106 forks source link

Overlay is not laid out properly #323

Open j-f1 opened 3 years ago

j-f1 commented 3 years ago
Image("turtlerock.jpg")
    .clipShape(Circle())
    .overlay(
        Circle()
            .stroke(Color(white: 0.5), lineWidth: 4)
    )

When rendering this at first, the expected gray stroke does not appear. After manually removing the width: 0; height: 0; parameter to the SVG element describing the circle, this appears:

Screenshot_2020-12-05 17 12 36

Note that the circle actually appears underneath the image, and that the circle’s shape does not match the image’s shape.

The first issue can be resolved by setting the z-index of the second generated grid-area to 1, which appears to be necessary because the clip-path property creates a new stacking context.

I’m not sure how to resolve the second issue.

carson-katri commented 3 years ago

I noticed issues with overlay and background when working on preference keys. In SwiftUI they seem to clip to their parents bounds (which we can do when it’s just a simple color but not otherwise). Maybe we could use geometry reader to get the parents size and set the overlay/background bounds accordingly?

j-f1 commented 3 years ago

I spent some time experimenting with how SwiftUI lays out .overlay (and the related ZStack). Here are my observations:

Here’s a visual summary:

Screenshot_2020-12-19 19 38 38
SwiftUI code ```swift let alignment: Alignment = .topLeading HStack { ```
```swift VStack { Text("ZStack") .font(.system(.title2, design: .monospaced)) ZStack(alignment: alignment) { Color.red // .frame(width: 100, height: 100) Rectangle().stroke(Color.yellow, lineWidth: 5) // .frame(width: 50, height: 50) } ZStack(alignment: alignment) { Color.red .frame(width: 100, height: 100) Rectangle().stroke(Color.yellow, lineWidth: 5) // .frame(width: 50, height: 50) } ZStack(alignment: alignment) { Color.red // .frame(width: 100, height: 100) Rectangle().stroke(Color.yellow, lineWidth: 5) .frame(width: 50, height: 50) } ZStack(alignment: alignment) { Color.red .frame(width: 100, height: 100) Rectangle().stroke(Color.yellow, lineWidth: 5) .frame(width: 150, height: 150) } ZStack(alignment: alignment) { Color.red .frame(width: 100, height: 100) Rectangle().stroke(Color.yellow, lineWidth: 5) .frame(width: 50, height: 50) } } ``` ```swift VStack { Text("overlay") .font(.system(.title2, design: .monospaced)) Color.red // .frame(width: 100, height: 100) .overlay( Rectangle().stroke(Color.yellow, lineWidth: 5) // .frame(width: 50, height: 50) , alignment: alignment ) Color.red .frame(width: 100, height: 100) .overlay( Rectangle().stroke(Color.yellow, lineWidth: 5) // .frame(width: 50, height: 50) , alignment: alignment ) Color.red // .frame(width: 100, height: 100) .overlay( Rectangle().stroke(Color.yellow, lineWidth: 5) .frame(width: 50, height: 50) , alignment: alignment ) Color.red .frame(width: 100, height: 100) .overlay( Rectangle().stroke(Color.yellow, lineWidth: 5) .frame(width: 150, height: 150) , alignment: alignment ) Color.red .frame(width: 100, height: 100) .overlay( Rectangle().stroke(Color.yellow, lineWidth: 5) .frame(width: 50, height: 50) , alignment: alignment ) } ```
```swift }.padding() ```