Post

Replies

Boosts

Views

Activity

why is the view.shadow offset from the correct position.
while working with a swiftUI playground, I came across an issue with the rendering of the view.shadow() function. where the shadow may be offset from the object it is shadowing by the distance from that object to the containing frame origin. (top left) the following is an example showing the issue. it can be run as a macOS playground or an iOS playground, the problem is similar. but it may be more visible as an iOS playground. when I run this, there should be 3 frames, stacked vertically, with a dot and a line rendered in each one. the shadow of the line is drawn offset down and to the right, the equivalent distance as the closest point to the top left origin. for the dot, the effect only seems to occur in the middle of the two frames. I had other graphics in the project I was working on, but they all had elements in the top left corner, therefore they rendered correctly, so I've removed them for simplicity. import PlaygroundSupport struct BaseStart: Shape {     var size = 10     var startPoint:InitialBase = .none     init(_ initial:InitialBase) {         startPoint = initial     }     func path(in rect: CGRect) -> Path {         let size = min(rect.size.width, rect.size.height) * 0.15         var x: CGFloat         var y: CGFloat         var path = Path()         switch startPoint {             case .firstBase:                 x = 3*(rect.size.width/4)                 y = 3*(rect.size.height/4)             case .secondBase :                 x = 3*(rect.size.width/4)                 y = (rect.size.height/4)             case .thirdBase :                 x = (rect.size.width/4)                 y = (rect.size.height/4)             default:                 return path         }         path.addEllipse(in: CGRect(x: x-size/2, y: y-size/2, width: size, height: size))         return path     } } struct BaseRunner: Shape {     var runnerStartingBase:InitialBase     var advancedBy=0     init(runnerStart:InitialBase, advancedBy:Int){         runnerStartingBase = runnerStart         self.advancedBy = advancedBy     }     func path(in rect:CGRect) -> Path {         let width = rect.size.width/4         let height = rect.size.height/4         let firstBase = CGPoint(x: width*3, y: height*3)         let secondBase = CGPoint(x: width*3, y: height)         let thirdBase = CGPoint(x: width, y: height)         let home = CGPoint(x: width, y: height*3)         var path = Path()         //uncomment the following 2 lines to establish a drawn pixel in the top left corner that "fixes" the problem         //                path.move(to: CGPoint(x: 0, y: 0))         //                path.addLine(to: CGPoint(x:1, y: 1))         switch runnerStartingBase {             case .firstBase:                 path.move(to: firstBase)                 if advancedBy>0 {path.addLine(to: secondBase)}                 if advancedBy>1 {path.addLine(to: thirdBase)}                 if advancedBy>2 {path.addLine(to: home)}             case .secondBase:                 path.move(to: secondBase)                 if advancedBy>0 {path.addLine(to: thirdBase)}                 if advancedBy>1 {path.addLine(to: home)}             case .thirdBase:                 path.move(to: thirdBase)                 if advancedBy>0 {path.addLine(to: home)}             case .none:                 let _ = 0         }         return path     } } enum InitialBase {     case none     case firstBase     case secondBase     case thirdBase } public struct BatterView : View {     init(_ start:InitialBase, _ runnerPosition:Int) {         initialBase = start         self.runnerPosition = runnerPosition     }     var initialBase:InitialBase = .none     var runnerPosition:Int     mutating func advanceRunner() {         self.runnerPosition += 1     }     public var body: some View {         ZStack{             BaseRunner(runnerStart: initialBase, advancedBy: runnerPosition)                 .stroke(lineWidth:3)                 .foregroundColor(.black)                 .shadow(color: .green, radius: 1, x: 0.2, y: 0)             BaseStart(initialBase)                 .fill()                 .foregroundColor(.black)                 .shadow(color: .green, radius: 1, x: 2, y: 2)             //should be noted that the problem exists whether the shadow is done on the individual             //shapes or the stack as a whole.             //uncommenting the following line and commenting out the above shadows will have similar effect.         }//.shadow(color: .green, radius: 2, x: 1, y: 1)     } } struct Preview: View {     @State private var position = 1     func advanceRunner(){         position += 1         update.toggle()     }     @State var update = false     var body: some View {         VStack (alignment: .center, spacing: 1){             BatterView(.thirdBase, position)                 .frame(minWidth: 44, idealWidth: 88, maxWidth: 88, minHeight: 44, idealHeight: 88, maxHeight: 88, alignment: .center)             BatterView(.secondBase, position)                 .frame(minWidth: 44, idealWidth: 88, maxWidth: 88, minHeight: 44, idealHeight: 88, maxHeight: 88, alignment: .center)                 .environment(\.colorScheme, .light)             BatterView(.firstBase, position)                 .frame(minWidth: 44, idealWidth: 88, maxWidth: 88, minHeight: 44, idealHeight: 88, maxHeight: 88, alignment: .center)                 .environment(\.colorScheme, .light)             Button(action: advanceRunner){                 Text("run!")             }         }     } } PlaygroundPage.current.setLiveView(Preview() )
1
0
435
Sep ’20