Skip to content

Instantly share code, notes, and snippets.

@Viktorianec
Created August 27, 2022 10:35
Show Gist options
  • Save Viktorianec/84d87a166bc7f5bb46dac8c606bb3857 to your computer and use it in GitHub Desktop.
Save Viktorianec/84d87a166bc7f5bb46dac8c606bb3857 to your computer and use it in GitHub Desktop.
Secret iOS Dev gist for cool SwiftUI Animation
import SwiftUI
struct Home: View {
@GestureState var location:CGPoint = .zero
var body: some View {
GeometryReader{proxy in
let size = proxy.size
// to fit into whole view
let width = size.width/10
let itemCount = Int((size.height / width).rounded()) * 10
// Раскомментируйте, чтобы посмотреть на эффект с градиентом
// А вместо картинки можете использовать свою или заполнить любым цветом
// LinearGradient(colors: [.cyan, .yellow, .mint, .pink, .purple], startPoint: .topLeading, endPoint: .bottomTrailing)
// .mask {
LazyVGrid(columns: Array(repeating: GridItem(.flexible(), spacing: 0), count: 10), spacing: 0) {
let colors:[Color] = [.cyan, .yellow, .mint, .pink, .purple, .orange, .blue, .brown]
ForEach(0..<itemCount, id: \.self) {i in
GeometryReader{ innerProxy in
let rect = innerProxy.frame(in: .named("GESTURE"))
let scale = itemScale(rect: rect, size: size)
let trasnformedRect = rect.applying(.init(scaleX: scale, y: scale))
let transformedLocation = location.applying(.init(scaleX: scale, y: scale))
RoundedRectangle(cornerRadius: 4)
.fill(colors[i % colors.count])
.overlay(Image("iosdev")
.resizable()
.scaledToFill())
.scaleEffect(scale)
.offset(x: trasnformedRect.midX - rect.midX,
y: trasnformedRect.midY - rect.midY)
.offset(x: location.x - transformedLocation.x,
y: location.y - transformedLocation.y)
}
.padding(5)
.frame(height:width)
}
}
// }
}
.padding(5)
.gesture(DragGesture(minimumDistance: 0)
.updating($location, body: { value, out, _ in
out = value.location
}))
.coordinateSpace(name: "GESTURE")
.preferredColorScheme(.dark)
.animation(.easeInOut, value: location == .zero)
}
func itemScale(rect: CGRect, size:CGSize) -> CGFloat {
let a = location.x - rect.midX
let b = location.y - rect.midY
let root = sqrt(a*a + b*b)
let diagonalValue = sqrt(size.width * size.width + size.height * size.height)
let scale = root / (diagonalValue / 2)
let modifiedScale = location == .zero ? 1 : (1 - scale)
return modifiedScale > 0 ? modifiedScale : 0.001
}
}
struct Home_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment