diff --git a/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift b/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift index 085cd4e4..eef61dc6 100644 --- a/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift +++ b/experiments/swift-programmatic-modal/AdaptiveModal/AdaptiveModalManager.swift @@ -11,43 +11,77 @@ import UIKit class AdaptiveModalManager { - static func interpolate( - inputValue : CGFloat, - rangeInput : [CGFloat], - rangeOutput: [CGFloat] - ) -> CGFloat? { - guard rangeInput.count == rangeOutput.count, - rangeInput.count >= 2 - else { return nil }; + static func interpolate( + inputValue : CGFloat, + rangeInput : [CGFloat], + rangeOutput: [CGFloat] +) -> CGFloat? { + guard rangeInput.count == rangeOutput.count, + rangeInput.count >= 2 + else { return nil }; + + // A - Extrapolate Left + if inputValue < rangeInput.first! { + + let rangeInputStart = rangeInput.first!; + let rangeOutputStart = rangeOutput.first!; + + let delta1 = rangeInputStart - inputValue; + let percent = delta1 / rangeInputStart; + + // extrapolated "range output end" + let rangeOutputEnd = rangeOutputStart - (rangeOutput[1] - rangeOutputStart); + + let interpolatedValue = RNIAnimator.EasingFunctions.lerp( + valueStart: rangeOutputEnd, + valueEnd: rangeOutputStart, + percent: percent + ); + + let delta2 = interpolatedValue - rangeOutputEnd; + return rangeOutputStart - delta2; + }; + + let (rangeStartIndex, rangeEndIndex): (Int, Int) = { + let rangeInputEnumerated = rangeInput.enumerated(); + + let match = rangeInputEnumerated.first { + guard let nextValue = rangeInput[safeIndex: $0.offset + 1] + else { return false }; + + return inputValue >= $0.element && inputValue < nextValue; + }; + // B - Interpolate Between + if let match = match { + let rangeStartIndex = match.offset; + return (rangeStartIndex, rangeStartIndex + 1); + }; + let lastIndex = rangeInput.count - 1; let secondToLastIndex = rangeInput.count - 2; + + // C - Extrapolate Right + return (secondToLastIndex, lastIndex); + }(); - let rangeInputEnumerated = rangeInput.enumerated(); - - let rangeInputStartMatch = - rangeInputEnumerated.first { $0.element >= inputValue }; - - let rangeInputStartIndex = rangeInputStartMatch?.offset ?? secondToLastIndex; - let rangeInputEndIndex = rangeInputStartIndex + 1; - - guard let rangeInputStart = rangeInput [safeIndex: rangeInputStartIndex], - let rangeInputEnd = rangeInput [safeIndex: rangeInputEndIndex ], - let rangeOutputStart = rangeOutput[safeIndex: rangeInputStartIndex], - let rangeOutputEnd = rangeOutput[safeIndex: rangeInputEndIndex ] - else { return nil }; - - let inputValueAdj = inputValue - rangeInputStart; - let rangeInputEndAdj = rangeInputEnd - rangeInputStart; + guard let rangeInputStart = rangeInput [safeIndex: rangeStartIndex], + let rangeInputEnd = rangeInput [safeIndex: rangeEndIndex ], + let rangeOutputStart = rangeOutput[safeIndex: rangeStartIndex], + let rangeOutputEnd = rangeOutput[safeIndex: rangeEndIndex ] + else { return nil }; + + let inputValueAdj = inputValue - rangeInputStart; + let rangeInputEndAdj = rangeInputEnd - rangeInputStart; - let progress = inputValueAdj / rangeInputEndAdj; - - return RNIAnimator.EasingFunctions.lerp( - valueStart: rangeOutputStart, - valueEnd : rangeOutputEnd, - percent : progress - ); - }; + let progress = inputValueAdj / rangeInputEndAdj; + + return RNIAnimator.EasingFunctions.lerp( + valueStart: rangeOutputStart, + valueEnd : rangeOutputEnd, + percent : progress + ); +}; var targetRectProvider: () -> CGRect; var currentSizeProvider: () -> CGSize; @@ -200,7 +234,7 @@ class AdaptiveModalManager { let rangeInputGesture: [CGFloat] = { var range: [CGFloat] = []; - range.append(targetRect.minY); + // range.append(targetRect.minY); range += snapRects.reversed().map { $0.minY }; range.append(targetRect.maxY); @@ -223,7 +257,7 @@ class AdaptiveModalManager { rangeOutput: { var range: [CGFloat] = []; - range.append(0); + // range.append(0); range += snapRects.map { $0.height }; range.append(targetRect.height); @@ -241,7 +275,7 @@ class AdaptiveModalManager { rangeOutput: { var range: [CGFloat] = []; - range.append(targetRect.width); + // range.append(targetRect.width); range += snapRects.map { $0.width }; range.append(targetRect.width); @@ -259,7 +293,7 @@ class AdaptiveModalManager { rangeOutput: { var range: [CGFloat] = []; - range.append(targetRect.minX); + // range.append(targetRect.minX); range += snapRects.map { $0.minX }; range.append(targetRect.minX); @@ -277,7 +311,7 @@ class AdaptiveModalManager { rangeOutput: { var range: [CGFloat] = []; - range.append(targetRect.minY); + // range.append(targetRect.minY); range += snapRects.reversed().map { $0.minY }; range.append(targetRect.maxY);