semi working scaling effect

This commit is contained in:
talksik
2021-12-16 16:29:53 -08:00
parent da8093ee2d
commit 595e49983a
+126 -47
View File
@@ -67,6 +67,8 @@ struct InnerCircleView: View {
private static let spacingBetweenRows: CGFloat = 16 private static let spacingBetweenRows: CGFloat = 16
private static let totalColumns: Int = 10 private static let totalColumns: Int = 10
let frameSize: CGPoint = CGPoint(x: UIScreen.main.bounds.size.width*0.5,y: UIScreen.main.bounds.size.height*0.5)
@State private var selectedUserIndex = 0 @State private var selectedUserIndex = 0
let gridItems: [GridItem] = Array( let gridItems: [GridItem] = Array(
@@ -84,62 +86,60 @@ struct InnerCircleView: View {
// .frame(width: universalSize.width * 0.75) // .frame(width: universalSize.width * 0.75)
// .frame(maxWidth: .infinity) // .frame(maxWidth: .infinity)
// .blur(radius: 8) // .blur(radius: 8)
GeometryReader {proxy in
let localValues = proxy.frame(in: .local)
ScrollView([.horizontal, .vertical], showsIndicators: false) {
LazyVGrid(
columns: gridItems,
alignment: .center,
spacing: Self.spacingBetweenRows
) {
ScrollView([.horizontal, .vertical], showsIndicators: false) { ForEach(1..<60) { value in
LazyVGrid( GeometryReader {gridProxy in
columns: gridItems, let posRelToGrid = gridProxy.frame(in: .global) // relative to the entire lazygrid
alignment: .center,
spacing: Self.spacingBetweenRows Image("Artboards_Diversity_Avatars_by_Netguru-\(value)")
) { .resizable()
ForEach(1..<60) { value in .scaledToFit()
VStack(alignment: .center) { .background(Color.white.opacity(0.5))
Image("Artboards_Diversity_Avatars_by_Netguru-\(value)") .cornerRadius(100)
.resizable() .shadow(color: Color.black.opacity(0.2), radius: 10, x: 0, y: 20)
.scaledToFit() .scaleEffect(
.frame(height: Self.size) scale(
.background(Color.white.opacity(0.5)) x: isEvenRow(value) ? gridProxy.frame(in: .global).midX + gridProxy.size.width/2 :
.cornerRadius(100) gridProxy.frame(in: .global).midX,
.shadow(color: Color.black.opacity(0.2), radius: 10, x: 0, y: 20) y: gridProxy.frame(in: .global).midY,
.scaleEffect(value == selectedUserIndex ? 1 : 0.75) value: value%43
.offset(
x: honeycombOffSetX(value),
y: 0
) )
.onTapGesture { )
self.selectedUserIndex = value .offset(
x: honeycombOffSetX(value),
y: 0
)
.onTapGesture {
self.selectedUserIndex = value
print("the selected item is: \(value)") print("the selected item is: \(value)")
let rowNumber = value / Self.totalColumns // 10 / 10 let rowNumber = value / Self.totalColumns // 10 / 10
print("the rownumber is: \(rowNumber)") print("the rownumber is: \(rowNumber)")
// make every even row have the honeycomb offset // make every even row have the honeycomb offset
if rowNumber % 2 == 0 { if rowNumber % 2 == 0 {
print("the offset is \(Self.size / 2 + Self.spacingBetweenColumns / 2 )") // account for the column spacing from before print("the offset is \(Self.size / 2 + Self.spacingBetweenColumns / 2 )") // account for the column spacing from before
} else { } else {
print("there is no offset") print("there is no offset")
}
} }
.animation(Animation.spring(), value: selectedUserIndex) }
.animation(Animation.spring(), value: selectedUserIndex)
// Text("local min x: \(localValues.minX)")
// .font(.caption)
// Text("local min x: \(localValues.minY)")
// .font(.caption)
}
} }
.frame(height: Self.size)
} }
} } // lazyvgrid
.foregroundColor(Color.blue) .padding(.trailing, Self.size / 2 + Self.spacingBetweenColumns / 2)
.frame(maxWidth: .infinity) } // scrollview
}
// navigation/footer // navigation/footer
@@ -147,10 +147,89 @@ struct InnerCircleView: View {
} }
} }
private func getScale(_ value: Int) -> CGFloat { private func isEvenRow(_ value: Int) -> Bool {
return 2 return (value / gridItems.count) % 2 == 0
} }
private func slope(p1: CGPoint, p2: CGPoint) -> CGFloat {
return (p2.y - p1.y)/(p2.x - p1.x)
}
private func distanceBetweenPoints(p1: CGPoint, p2: CGPoint) -> CGFloat {
let xDist = abs(p2.x - p1.x)
let yDist = abs(p2.y - p2.y)
return CGFloat(
sqrt(
pow(xDist, 2) + pow(yDist, 2)
)
)
}
func offsetY(proxy: GeometryProxy, factor: CGFloat) -> CGFloat {
let y = proxy.frame(in: .global).midY
if y < frameSize.y {
return abs(y - frameSize.y) * factor
}
return -abs(y - frameSize.y) * factor
}
func offset(a: CGFloat, b: CGFloat, factor: CGFloat) -> CGFloat {
return abs(a - b) * factor
}
func distance2(x: CGFloat, y: CGFloat, value: Int) -> CGFloat {
//Fix crash with Slope
let m = (frameSize.y - y)/(frameSize.x - x)
let angle = abs(atan(m) * 180 / .pi)
//print("Angle: ", angle, apps[value])
//print("Slope: ", m, apps[value])
let ipadAngle: CGFloat = 35
if angle > ipadAngle {
let y2 = (y > frameSize.y) ? frameSize.y*2 : 0
let x2 = (y2 - y)/m + x
//print(apps[value], x2, y2)
return distance3(x: x2, y: y2, value: value)
} else {
let x2 = (x > frameSize.x) ? frameSize.x*2 : 0
let y2 = m * (x2 - x) + y
//print(apps[value], x2, y2)
return distance3(x: x2, y: y2, value: value)
}
}
func distance3(x: CGFloat, y: CGFloat, value: Int) -> CGFloat {
let xDist = abs(x - frameSize.x)
let yDist = abs(y - frameSize.y)
return CGFloat(sqrt(xDist * xDist + yDist * yDist))
}
func scale(x: CGFloat, y: CGFloat, value: Int) -> CGFloat {
let xDist = abs(x - frameSize.x)
let yDist = abs(y - frameSize.y)
let maxDistanceToCenter = distance2(x: x, y: y, value: value)//CGFloat(sqrt(frameSize.x * frameSize.x + frameSize.y * frameSize.y))
let result = CGFloat(sqrt(xDist * xDist + yDist * yDist))
//print("distance: \(apps[value]) ", result)
//print("center: \(apps[value]) ", maxDistanceToCenter)
let total = min(abs(result - maxDistanceToCenter), maxDistanceToCenter*0.7)
let finalResult = total/(maxDistanceToCenter) * 1.4
return finalResult
}
private func honeycombOffSetX(_ value: Int) -> CGFloat { private func honeycombOffSetX(_ value: Int) -> CGFloat {
let rowNumber = ceil(Double(value) / Double(Self.totalColumns)) // round up let rowNumber = ceil(Double(value) / Double(Self.totalColumns)) // round up