swiftui-gesture-velocity

1.0.0

In SwiftUI, a property-wrapper provides velocity in pt/s from gesture
FluidGroup/swiftui-gesture-velocity

What's New

1.0.0

2023-05-06T18:15:16Z

What's Changed

  • Update module name - now SwiftUIGestureVelocity by @muukii in #1

New Contributors

  • @muukii made their first contribution in #1

Full Changelog: 0.1.0...1.0.0

swiftui-GestureVelocity

In SwiftUI, a property-wrapper provides velocity in pt/s from gesture

Instructions

@GestureVelocity private var velocity: CGVector
.gesture(
  DragGesture(...)
  ... some declarations
  .updatingVelocity($velocity)

Example

CleanShot 2023-04-08 at 16 32 28

struct Joystick: View {

  /**
   ???
   Use just State instead of GestureState to trigger animation on gesture ended.
   This approach is right?

   refs:
   https://stackoverflow.com/questions/72880712/animate-gesturestate-on-reset
   */
  @State private var position: CGSize = .zero

  @GestureVelocity private var velocity: CGVector

  var body: some View {
    stick
      .padding(10)
  }

  private var stick: some View {
    Circle()
      .fill(Color.blue)
      .frame(width: 100, height: 100)
      .animatableOffset(position) // https://github.com/FluidGroup/swiftui-support
      .gesture(
        DragGesture(
          minimumDistance: 0,
          coordinateSpace: .local
        )
        .onChanged({ value in
          withAnimation(.interactiveSpring()) {
            position = value.translation
          }
        })
        .onEnded({ value in

          let distance = CGSize(
            width: -position.width,
            height: -position.height
          )

          let mappedVelocity = CGVector(
            dx: velocity.dx / distance.width,
            dy: velocity.dy / distance.height
          )
          
          withAnimation(
            .interpolatingSpring(
              stiffness: 50,
              damping: 10,
              initialVelocity: mappedVelocity.dx
            )
          ) {
            position.width = 0
          }
          
          withAnimation(
            .interpolatingSpring(
              stiffness: 50,
              damping: 10,
              initialVelocity: mappedVelocity.dy
            )
          ) {
            position.height = 0
          }
        })
        .updatingVelocity($velocity)

      )

  }
}

Example

RoundedRectangle(cornerRadius: 16, style: .continuous)
  .fill(Color.blue)
  .frame(width: 100, height: 100)
  .modifier(VerticalDragModifier())
struct VerticalDragModifier: ViewModifier {
  
  /**
   ???
   Use just State instead of GestureState to trigger animation on gesture ended.
   This approach is right?
   
   refs:
   https://stackoverflow.com/questions/72880712/animate-gesturestate-on-reset
   */
  @State private var position: CGSize = .zero
  
  @GestureVelocity private var velocity: CGVector
  
  func body(content: Content) -> some View {
    content
      .offset(position)
      .gesture(
        DragGesture(
          minimumDistance: 0,
          coordinateSpace: .local
        )
        .onChanged({ value in
          withAnimation(.interactiveSpring()) {
            position.height = value.translation.height
          }
        })
        .onEnded({ value in
          
          let distance = CGSize(
            width: -position.width,
            height: -position.height
          )
          
          let mappedVelocity = CGVector(
            dx: velocity.dx / distance.width,
            dy: velocity.dy / distance.height
          )
          
          withAnimation(
            .interpolatingSpring(
              stiffness: 50,
              damping: 10,
              initialVelocity: mappedVelocity.dy
            )
          ) {
            position.width = 0
            position.height = 0
          }
        })
        .updatingVelocity($velocity)
        
      )
  }
  
}

Description

  • Swift Tools 5.7.0
View More Packages from this Author

Dependencies

  • None
Last updated: Thu Apr 11 2024 11:02:21 GMT-0900 (Hawaii-Aleutian Daylight Time)