1 //  Copyright (c) 2018, Applidium. All rights reserved
2 //  RubberBandOverlayTranslationFunction.swift
3 //  OverlayContainer
4 //
5 //  Created by Gaétan Zanella on 29/11/2018.
6 //
7 
8 import UIKit
9 
10 /// `RubberBandOverlayTranslationFunction` specifies an overlay that will move linearly between
11 /// the translation boundaris and limit its progression once reached.
12 public class RubberBandOverlayTranslationFunction: OverlayTranslationFunction {
13 
14     /// A factor defining how much the translation should be limited once one of the boundaries is reached.
15     public var factor: CGFloat = 0.5
16 
17     public var bouncesAtMaximumHeight = true
18     public var bouncesAtMinimumHeight = true
19 
20     // MARK: - Life Cycle
21 
22     public init() {}
23 
24     // MARK: - OverlayTranslationFunction
25 
overlayTranslationHeightnull26     public func overlayTranslationHeight(using context: OverlayTranslationParameters) -> CGFloat {
27         if context.translation >= context.maximumHeight && bouncesAtMaximumHeight {
28             return logarithmicTranslation(translation: context.translation, limit: context.maximumHeight)
29         }
30         if context.translation <= context.minimumHeight && bouncesAtMinimumHeight {
31             let translation = context.minimumHeight + (context.minimumHeight - context.translation)
32             let height = logarithmicTranslation(translation: translation, limit: context.minimumHeight)
33             return context.minimumHeight - (height - context.minimumHeight)
34         }
35         return max(context.minimumHeight, min(context.translation, context.maximumHeight))
36     }
37 
38     // MARK: - Private
39 
logarithmicTranslationnull40     private func logarithmicTranslation(translation: CGFloat, limit: CGFloat) -> CGFloat {
41         guard limit > 0 else { return 0 }
42         return (limit * (1 + factor * log10(translation / limit))).oc_rounded()
43     }
44 }
45