Reputation: 36098
I'm trying to add a circle background for an image, then clip the image using a semi-circle of the background. This is what I'm trying to end up with:
In SwiftUI, I put together something but stuck on what clipShape
should I use:
Circle()
.fill(Color.blue)
.aspectRatio(contentMode: .fit)
.frame(width: 48)
.padding(.top, 8)
.overlay(
Image("product-sample1")
.resizable()
.scaledToFit()
//.clipShape(???)
)
This is what it looks like:
I'm not sure how to achieve this but was given a clue to use this approach:
How can this be achieved in SwiftUI, or is there a better approach to doing this?
Upvotes: 3
Views: 758
Reputation: 257729
You can create own shape. Below is a simple demo variant (for square content).
private struct DemoClipShape: Shape {
func path(in rect: CGRect) -> Path {
Path {
$0.move(to: CGPoint.zero)
$0.addLine(to: CGPoint(x: rect.maxX, y: 0))
$0.addLine(to: CGPoint(x: rect.maxX, y: rect.midY))
$0.addArc(center: CGPoint(x: rect.midX, y: rect.midY), radius: rect.midY, startAngle: Angle(degrees: 0), endAngle: Angle(degrees: 90), clockwise: false)
$0.addArc(center: CGPoint(x: rect.midX, y: rect.midY), radius: rect.midY, startAngle: Angle(degrees: 90), endAngle: Angle(degrees: 180), clockwise: false)
$0.addLine(to: CGPoint.zero)
}
}
}
And here is a sample of how it could be applied - due to padding we need to offset clipping (mask) to compensate locations (also it can be passed as constant into shape constructor, which will be more correct and accurate, but I leave it for you):
// used larger values for better visibility
Circle()
.fill(Color.blue)
.frame(width: 148, height: 148)
.padding(.top, 18)
.padding(.bottom, 10)
.overlay(
Image("product-sample1")
.resizable()
.scaledToFit()
)
.mask(DemoClipShape().offset(x: 0, y: -11)) // << here !!
gives
Upvotes: 2