From 595e49983a4bddbb401b42af3b5c25a86dfaa3f1 Mon Sep 17 00:00:00 2001 From: talksik Date: Thu, 16 Dec 2021 16:29:53 -0800 Subject: [PATCH] semi working scaling effect --- .../v2/InnerCircle/InnerCircleView.swift | 185 +++++++++++++----- 1 file changed, 132 insertions(+), 53 deletions(-) diff --git a/nirvana-ios/v2/InnerCircle/InnerCircleView.swift b/nirvana-ios/v2/InnerCircle/InnerCircleView.swift index bf34b51..4f2fd47 100644 --- a/nirvana-ios/v2/InnerCircle/InnerCircleView.swift +++ b/nirvana-ios/v2/InnerCircle/InnerCircleView.swift @@ -67,6 +67,8 @@ struct InnerCircleView: View { private static let spacingBetweenRows: CGFloat = 16 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 let gridItems: [GridItem] = Array( @@ -84,73 +86,150 @@ struct InnerCircleView: View { // .frame(width: universalSize.width * 0.75) // .frame(maxWidth: .infinity) // .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 - ) { - ForEach(1..<60) { value in - VStack(alignment: .center) { - Image("Artboards_Diversity_Avatars_by_Netguru-\(value)") - .resizable() - .scaledToFit() - .frame(height: Self.size) - .background(Color.white.opacity(0.5)) - .cornerRadius(100) - .shadow(color: Color.black.opacity(0.2), radius: 10, x: 0, y: 20) - .scaleEffect(value == selectedUserIndex ? 1 : 0.75) - .offset( - x: honeycombOffSetX(value), - y: 0 + ScrollView([.horizontal, .vertical], showsIndicators: false) { + LazyVGrid( + columns: gridItems, + alignment: .center, + spacing: Self.spacingBetweenRows + ) { + + ForEach(1..<60) { value in + GeometryReader {gridProxy in + let posRelToGrid = gridProxy.frame(in: .global) // relative to the entire lazygrid + + Image("Artboards_Diversity_Avatars_by_Netguru-\(value)") + .resizable() + .scaledToFit() + .background(Color.white.opacity(0.5)) + .cornerRadius(100) + .shadow(color: Color.black.opacity(0.2), radius: 10, x: 0, y: 20) + .scaleEffect( + scale( + x: isEvenRow(value) ? gridProxy.frame(in: .global).midX + gridProxy.size.width/2 : + gridProxy.frame(in: .global).midX, + y: gridProxy.frame(in: .global).midY, + value: value%43 ) - .onTapGesture { - self.selectedUserIndex = value - - print("the selected item is: \(value)") - - let rowNumber = value / Self.totalColumns // 10 / 10 - - print("the rownumber is: \(rowNumber)") - - // make every even row have the honeycomb offset - if rowNumber % 2 == 0 { - print("the offset is \(Self.size / 2 + Self.spacingBetweenColumns / 2 )") // account for the column spacing from before - } else { - print("there is no offset") - } + ) + .offset( + x: honeycombOffSetX(value), + y: 0 + ) + .onTapGesture { + self.selectedUserIndex = value + + print("the selected item is: \(value)") + + let rowNumber = value / Self.totalColumns // 10 / 10 + + print("the rownumber is: \(rowNumber)") + + // make every even row have the honeycomb offset + if rowNumber % 2 == 0 { + print("the offset is \(Self.size / 2 + Self.spacingBetweenColumns / 2 )") // account for the column spacing from before + } else { + print("there is no offset") } - .animation(Animation.spring(), value: selectedUserIndex) - - - -// Text("local min x: \(localValues.minX)") -// .font(.caption) -// Text("local min x: \(localValues.minY)") -// .font(.caption) - } + } + .animation(Animation.spring(), value: selectedUserIndex) + } + .frame(height: Self.size) } - } - .foregroundColor(Color.blue) - .frame(maxWidth: .infinity) - } + } // lazyvgrid + .padding(.trailing, Self.size / 2 + Self.spacingBetweenColumns / 2) + } // scrollview - // navigation/footer Spacer() } } - private func getScale(_ value: Int) -> CGFloat { - return 2 + private func isEvenRow(_ value: Int) -> Bool { + 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 { let rowNumber = ceil(Double(value) / Double(Self.totalColumns)) // round up