I’m including a border and blur impact on a form throughout an animation (root view showing on web page) and seeing FPS drops when utilizing an AngularGradient as the colour of the border. I dont see the drops when utilizing a traditional colour. The drop is noticeable when setting a tool to “low battery” mode.
My code is ready up as a customized view modifier, and the border is added as overlays within the form of myShape
, the place myShape
matches the form of the view/form being modified.
struct BorderBlur: ViewModifier {
var fillColor: some ShapeStyle {
AngularGradient(
colours: [.blue, .purple, .green, .blue],
middle: .middle)
.opacity(borderOpacity)
}
var myShape : some Form {
RoundedRectangle(cornerRadius:36)
}
let borderWidth : CGFloat
let blurRadius: CGFloat
let borderOpacity: CGFloat
init(borderWidth: CGFloat, blurRadius: CGFloat, borderOpacity: CGFloat) {
self.borderWidth = borderWidth
self.blurRadius = blurRadius
self.borderOpacity = borderOpacity
}
public func physique(content material: Content material) -> some View {
content material
.overlay(
myShape
.stroke(lineWidth: borderWidth)
.fill(fillColor)
.padding(borderWidth)
)
.overlay(
myShape
.stroke(lineWidth: borderWidth)
.fill(fillColor)
.blur(radius: blurRadius)
.padding(borderWidth)
)
.overlay(
myShape
.stroke(lineWidth: borderWidth)
.fill(fillColor)
.blur(radius: blurRadius / 2)
.padding(borderWidth)
)
}
}
extension View {
public func borderBlur(borderWidth: CGFloat, blurRadius: CGFloat, borderOpacity: CGFloat) -> some View {
return modifier(BorderBlur(borderWidth: borderWidth, blurRadius: blurRadius, borderOpacity: borderOpacity))
}
}
struct MyRootView: View {
@State var didAppear = false
var borderWidth: CGFloat {
didAppear ? 3 : 0
}
var borderBlurRadius: CGFloat {
didAppear ? 10 : 0
}
var borderOpacity: CGFloat {
didAppear ? 1 : 0
}
var physique: some View {
VStack {
RoundedRectangle(cornerRadius:36).fill(.clear)
.borderBlur(borderWidth: borderWidth, blurRadius: borderBlurRadius, borderOpacity: borderOpacity)
.body(width: didAppear ? 300 : 100, peak: didAppear ? 400 : 100)
.offset(y: didAppear ? 0 : -400)
}
.onAppear {
withAnimation(.linear(length:2.0)) {
didAppear = true
}
}
}
}
If I alter the fillColor to an ordinary colour like Coloration.blue
, I see no FPS drops. Any concepts as to easy methods to make the gradient render extra effectively? I attempted drawingGroup()
, which does enhance FPS, however it makes the blur look dangerous, and I additionally need to have the ability to animate blur dimension (+ border width, opacity).