             case .linear:
                 break
             case .progressive:
-                //                duration = Double(index+1) * animationDuration / Double(items.count)
-                delay = Double(index) * 0.2
+                delay = Double(index) * 0.02
             case .progressiveInverse:
-                //                duration = Double(items.count - index) * animationDuration / Double(items.count)
-                delay = Double(items.count - (index+1)) * 0.2
-            }
-            
-            // TODO: adjust for bounce effect
+                delay = Double(items.count - (index+1)) * 0.02
+            }
             
             DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: {
+                let animated = self.itemsAnimationType != .none
                 
-                let animated = self.itemsAnimationType != .none
+                item.expand(animated: animated, duration: duration)
+                
                 if animated {
                     var damping: CGFloat = 1.0
                     if self.itemsAnimationType == .bounce {
                         damping = 0.7
-                        duration = Double(index) * self.animationDuration / Double(self.items.count) + self.animationDuration
+                        var durationOffset: TimeInterval = 0
+                        if self.itemsAnimationOrder == .progressive {
+                            durationOffset = Double(index) * duration / Double(self.items.count)
+                        } else if self.itemsAnimationOrder == .progressiveInverse {
+                            durationOffset = Double(self.items.count - index) * duration / Double(self.items.count)
+                        }
+                        duration += durationOffset
                     }
                     
                     let animation = self.openAnimations(forItem: item, to: center, type: self.itemsAnimationType)

            switch type {
            case .none: break
            case .fade:
                self.backgroundView.alpha = 1.0
            case .bubble:
                if opening {
                    let diameter = self.coveringBubbleDiameter(for: self.backgroundView.center)

        for (index, item) in self.items.enumerated() {
            
            let center = self.center(forItem: item, index: index, itemsPosition: itemsPosition, opening: false)
            var duration = self.animationDuration
            var delay = 0.0
            
            switch itemsAnimationOrder {
            case .linear:
                break
            case .progressive:
                    delay = Double(index) * 0.02
            case .progressiveInverse:
                    delay = Double(items.count - (index+1)) * 0.02
            }
            
            DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: {
                let animated = self.itemsAnimationType != .none
                
                item.reduce(animated: animated, duration: duration)
                
                if animated {
                    var damping: CGFloat = 1.0
                    var velocity: CGFloat = 0.0
                    if self.itemsAnimationType == .bounce {
                        damping = 1.0
                        velocity = -5
                        
                        var durationOffset: TimeInterval = 0
                        if self.itemsAnimationOrder == .progressive {
                            durationOffset = Double(index) * duration / Double(self.items.count)
                        } else if self.itemsAnimationOrder == .progressiveInverse {
                            durationOffset = Double(self.items.count - index) * duration / Double(self.items.count)
                        }
                        duration += durationOffset
                        duration *= 2
                    }
                    
                    let animation = self.closeAnimations(forItem: item, to: center, type: self.itemsAnimationType)
