From 06186e112703e822744588fb02bc950256b272c3 Mon Sep 17 00:00:00 2001 From: Dominic Go <18517029+dominicstop@users.noreply.github.com> Date: Wed, 7 Jun 2023 05:17:34 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=AB=20Update:=20Exp=20-=20`AdaptiveMod?= =?UTF-8?q?al`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: * Update experiment/test - `swift-programmatic-modal/AdaptiveModal`. * Custom modal corner radius. --- .../AdaptiveModal/AdaptiveModalManager.swift | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift b/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift index 694ab8f8..af5d342f 100644 --- a/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift +++ b/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift @@ -943,15 +943,40 @@ class AdaptiveModalManager { let modalMaskAnimator: CABasicAnimation? = { guard let modalLayerMask = modalLayerMask else { return nil }; - let animator = CABasicAnimation(keyPath: "path"); + let animator = CASpringAnimation(keyPath: "path"); animator.fromValue = modalLayerMask.path; animator.toValue = interpolationPoint.modalCornerRadiusPath.cgPath; - animator.duration = modalAnimator.duration; - animator.timingFunction = - CAMediaTimingFunction(name: CAMediaTimingFunctionName.default); + if let gestureInitialVelocity = self.gestureInitialVelocity { + let snapAnimationConfig = self.modalConfig.snapAnimationConfig; + + + //Set initial velocity and desired duration + let initialVelocity: CGFloat = gestureInitialVelocity.dy; + let relaxationTime: CGFloat = animator.settlingDuration; + + //Spring constants + let dampingRatio: CGFloat = snapAnimationConfig.springDampingRatio; + + //Only allow damping ratio between just above 0 and 1 (critically damped) + let clippedDampingRatio: CGFloat = min(1, max(dampingRatio, 0.01)) + let mass: CGFloat = 1 + let fractionOfAmplitude: CGFloat = 1500 //A spring never gets to 0 amplitude, it gets infinitely smaller. This fraction represents the perceived 0 point. + let logOfFraction: CGFloat = log(fractionOfAmplitude) + let stiffness: CGFloat = (mass * pow(logOfFraction, 2)) / (pow(relaxationTime, 2) * pow(clippedDampingRatio, 2)) + let angularFrequency: CGFloat = sqrt(stiffness/mass) + let damping: CGFloat = 2 * mass * angularFrequency * clippedDampingRatio + + animator.initialVelocity = initialVelocity + animator.mass = mass + animator.stiffness = stiffness + animator.damping = damping + + animator.duration = min(animator.settlingDuration, modalAnimator.duration); + }; + animator.isRemovedOnCompletion = false; animator.fillMode = .both;