ProductPromotion
Logo

Swift

made by https://0x3d.site

GitHub - MacPaw/CocoaSprings: Interactive spring animations for macOS/iOS
Interactive spring animations for macOS/iOS. Contribute to MacPaw/CocoaSprings development by creating an account on GitHub.
Visit Site

GitHub - MacPaw/CocoaSprings: Interactive spring animations for macOS/iOS

GitHub - MacPaw/CocoaSprings: Interactive spring animations for macOS/iOS

CocoaSprings

Contents

About

CocoaSprings is a lightweight Swift package that simulates damped spring physics for basic AppKit & UIKit components. The package provides subclasses of CALayer, UIView, NSView, and NSWindow, which can be moved around the UI repeatedly without breaking the continuity of their motion. This allows for the implementation of fluid, interactive animations similar to this one:

About

The math behind the animations is based on this excellent blog post by Ryan Juckett. In it, he explains the algorithm he uses for moving third-person cameras in video games, provided that a camera's motion should be smooth and continuous despite the possible abrupt changes in the player's movement. This is the exact effect we wanted to achieve for animating UI elements inside our apps, so we applied the same algorithm to move layers, views, and windows on the 2D plane of the user interface.

Installation

CocoaSprings is available through SPM. Just add this repository as a dependency to your package or project.

dependencies: [
    .package(url: "https://github.com/MacPaw/CocoaSprings.git", branch: "main")
]

Usage

SpringConfiguration

The physics of CocoaSprings components is configured via the SpringConfiguration struct. It has two properties:

  • angularFrequency controls how fast an object moves towards its destination. The higher the value, the faster an object moves. The default value is 7.5.
  • dampingRatio controls how fast the spring motion decays. The lower the value, the less velocity is lost upon each oscillation. The value must range from 0 to 1; the default is 0.5.

Set the configuration on any component to adjust its physics:

let layer = SpringMotionLayer()
layer.configuration = SpringConfiguration(angularFrequency: 10, dampingRatio: 0.7)

SpringMotionLayer

SpringMotionLayer is a CALayer subclass available for both iOS & macOS.

Add it as a sublayer to the desired parent layer and call the move(to:) method to update the layer's position with spring animation.

Below is an example of a macOS NSView subclass that hosts a SpringMotionLayer and moves it to whichever point inside it gets clicked:

import AppKit
import CocoaSprings

final class ClickableView: NSView {
    
    override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
        setup()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setup()
    }
    
    private lazy var rootLayer = CALayer()
    
    private lazy var springMotionLayer: SpringMotionLayer = {
        let layer = SpringMotionLayer()
        layer.backgroundColor = NSColor.systemRed.cgColor
        layer.cornerRadius = 10
        layer.frame.size = .init(width: 20, height: 20)
        return layer
    }()
    
    private func setup() {
        layer = rootLayer
        wantsLayer = true
        rootLayer.addSublayer(springMotionLayer)
    }
    
    override func mouseDown(with event: NSEvent) {
        super.mouseDown(with: event)
        springMotionLayer.move(to: convert(event.locationInWindow, from: nil))
    }
}

Layer Example

SpringMotionView

SpringMotionView is an NSView/UIView subclass, depending on the platform you're building for.

Due to the fact that views are usually positioned using constraints, the client is responsible for updating the view's position during animation. On each frame of movement the view executes its onUpdatePosition closure, you must set it to update the relevant view's constraints.

Consider an example iOS snippet below, assume we've set up SpringMotionView and its constraints via Interface Builder:

import UIKit
import CocoaSprings

final class ViewController: UIViewController {

    @IBOutlet weak var springMotionView: SpringMotionView!
    @IBOutlet weak var springMotionViewTopConstraint: NSLayoutConstraint!
    @IBOutlet weak var springMotionViewLeftConstraint: NSLayoutConstraint!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Here we set up how the view should update its position
        // depending on the provided `point` parameter.
        springMotionView.onPositionUpdate = { [weak self] point in
            guard let self else { return }
            let size = self.springMotionView.frame.size
            self.springMotionViewLeftConstraint.constant = point.x - size.width / 2
            self.springMotionViewTopConstraint.constant = point.y - size.height / 2
        }
    }

    // UITapGestureRecognizer action
    @IBAction func handleTap(_ sender: UITapGestureRecognizer) {
        // Start moving to the tapped location
        springMotionView.move(to: sender.location(in: view))
    }
}

View Example

SpringMotionWindow

SpringMotionWindow is an NSWindow subclass, available for macOS only.

  • Call move(to:) to start animating position to a point on screen.
  • Call pinToWindow(_:offsetFromCenter:) to make the window follow any other window on screen with spring animation (example below).
  • Call unpinFromWindow() to stop following a previously followed window.
import AppKit
import CocoaSprings

final class ViewController: NSViewController {

    override func viewDidAppear() {
        super.viewDidAppear()
        
        let springMotionWindow = SpringMotionWindow()
        springMotionWindow.contentView = NSView()
        springMotionWindow.contentView?.wantsLayer = true
        springMotionWindow.contentView?.layer?.backgroundColor = NSColor.systemRed.cgColor
        springMotionWindow.contentView?.layer?.cornerRadius = 10
        springMotionWindow.setFrame(.init(origin: .zero, size: .init(width: 100, height: 100)), display: true)
        springMotionWindow.makeKeyAndOrderFront(nil)
        springMotionWindow.level = .mainMenu
        springMotionWindow.styleMask = [.borderless, .fullSizeContentView]
        springMotionWindow.backgroundColor = .clear
        springMotionWindow.isMovableByWindowBackground = true
        
        if let mainWindow = view.window {
            springMotionWindow.pinToWindow(mainWindow, offsetFromCenter: .init(x: 300, y: 100))
        }
    }
}

View Example

Demo

For your convenience, most of the features described above are implemented in a demo project in this repository. Please refer to it for package usage examples.

View Example

License

CocoaSprings is available under the MIT license.

See the LICENSE file for more info.

More Resources
to explore the angular.

mail [email protected] to add your project or resources here ๐Ÿ”ฅ.

Related Articles
to learn about angular.

FAQ's
to learn more about Angular JS.

mail [email protected] to add more queries here ๐Ÿ”.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory