@@ -81,31 +81,33 @@ import UIKit
8181 // Clamp startLocation to valid range
8282 let clampedStartLocation = min ( max ( startLocation, 0.0 ) , 1.0 )
8383
84- // Calculate gradient values for each pixel
85- for i in 0 ..< length {
86- // Determine normalized position along the gradient (0.0 to 1.0)
87- let normalizedPosition = length > 1 ? CGFloat ( i) / CGFloat( length - 1 ) : 0.0
88-
89- // Calculate alpha with starting inset
90- let alpha : CGFloat = {
91- // Adjust for starting inset - pixels before startLocation are fully opaque/transparent
92- let adjustedPosition : CGFloat
93- if clampedStartLocation >= 1.0 {
94- adjustedPosition = 0.0
95- } else if normalizedPosition <= clampedStartLocation {
96- adjustedPosition = 0.0
97- } else {
98- adjustedPosition = ( normalizedPosition - clampedStartLocation) / ( 1.0 - clampedStartLocation)
99- }
100-
101- // Apply easing for smooth transition, or use linear interpolation
102- let finalPosition = smooth ? easeInOutSine ( adjustedPosition) : adjustedPosition
103-
104- // Apply direction
105- return reversed ? finalPosition : 1.0 - finalPosition
106- } ( )
107-
108- // Write gray (0) and alpha values
84+ // Precompute reciprocals used in the gradient calculation
85+ let lengthReciprocal : CGFloat = length > 1 ? 1.0 / CGFloat( length - 1 ) : 0.0
86+ let gradientRangeReciprocal : CGFloat = clampedStartLocation < 1.0 ? 1.0 / ( 1.0 - clampedStartLocation) : 0.0
87+
88+ // Calculate the pixel boundary where the gradient transition starts.
89+ // Pixels before this boundary all share the same constant alpha value.
90+ let gradientStartPixel : Int = {
91+ guard length > 1 , clampedStartLocation > 0.0 else { return 0 }
92+ return min ( Int ( clampedStartLocation * CGFloat( length - 1 ) ) + 1 , length)
93+ } ( )
94+
95+ // Bulk-fill the constant region before the gradient (no per-pixel math needed)
96+ if gradientStartPixel > 0 {
97+ let constantAlpha : UInt8 = reversed ? 0 : 255
98+ for i in stride ( from: 0 , to: gradientStartPixel * bytesPerPixel, by: bytesPerPixel) {
99+ pixels [ i] = 0
100+ pixels [ i + 1 ] = constantAlpha
101+ }
102+ }
103+
104+ // Generate the gradient transition for the remaining pixels
105+ for i in gradientStartPixel..< length {
106+ let normalizedPosition = CGFloat ( i) * lengthReciprocal
107+ let adjustedPosition = ( normalizedPosition - clampedStartLocation) * gradientRangeReciprocal
108+ let eased = smooth ? easeInOutSine ( adjustedPosition) : adjustedPosition
109+ let alpha = reversed ? eased : 1.0 - eased
110+
109111 let pixelIndex = i * bytesPerPixel
110112 pixels [ pixelIndex] = 0
111113 pixels [ pixelIndex + 1 ] = UInt8 ( min ( max ( alpha * 255.0 , 0.0 ) , 255.0 ) )
0 commit comments