I'm trying to drag the gray square inside the white square manteinig the starting point CGPoint(x: 0, y: 0)
and respecting the extreme coordinates, see of the image.
The code works but I have two problems:
- the mouse doesn't match the center of the gray square when it is dragged;
- I can't subtract the size of the gray rectangle
30x30
(like red rectangle) from the geometry without changing the extreme value of the coordinate.
I tried to solve both problems with
location.x = max (0, min (geometry.size.width - 15, value.location.x) - 15)
location.y = max (0, min (geometry.size.height - 15 , value.location.y) - 15)
but vertices x
and y
becomes 0.94
instead 1
and 0.06000000000000005
instead 0
.
struct ContentView: View {
@State private var location: CGPoint = CGPoint(x: 0, y: 0)
var body: some View {
VStack(alignment: .leading, spacing: 20) {
GeometryReader { geometry in
ZStack(alignment: .topLeading) {
Rectangle()
.fill(.white)
Rectangle()
.fill(.gray)
.frame(width: 30, height: 30)
.offset(x: location.x, y: location.y)
}
.gesture(
DragGesture(minimumDistance: 0, coordinateSpace: .local)
.onChanged { value in
location.x = max(0, min(geometry.size.width, value.location.x))
location.y = max(0, min(geometry.size.height, value.location.y))
print("location",location)
print("value location",value.location)
let distanceA = distanceA(0, location.x) / geometry.size.width // < -30
let distanceB = distanceB(0, location.y) / geometry.size.height // < -30
print(min(distanceA, 1))
print(1 - distanceB)
}
)
}
.frame(width: 500, height: 500)
}
}
func distanceA(_ a: Double, _ b: Double) -> Double {
let B = b > 0.0 ? b : 0
let xDist = a - (B)
return Double(sqrt(pow(xDist, 2)))
}
func distanceB(_ a: Double, _ b: Double) -> Double {
let B = b > 0.0 ? b : 0
let yDist = (B) - a
return Double(sqrt(pow(yDist, 2)))
}
}
You are attempting to take the small square size into account in the wrong place. The
GeometryReader
coordinates are the size of the larger square, and that doesn't change. You just need to handle the placement of the smaller square within the larger one. Essentially you need to move it up and left half the size of the square. Commented code: