                         self.collectionView.panGestureRecognizer.enabled = true
                         self.isPanVertical = false
                         self.hasReachNormalHeightFromFullScreen = false
+                        self.reachNormalLocationYFromFullScreen = 0
+                        self.reachNormalTransitionYFromFullScreen = 0
                 })
             }
+        }
+    }
+    
+    // panOffY * panOffY = (locationY / screenH) * (locationY / screenH) * (maxRatio - 1) * (maxRatio - 1) * screenH * (-translationY)
+    func computeCellHeightUnderExtraZoomIn() -> CGFloat {
+        let gap = isFromFullScreen == false ? (-translationInView.y + reachNormalTransitionYFromFullScreen < 0 ? 0 : -translationInView.y + reachNormalTransitionYFromFullScreen) : -translationInView.y
+        let panOffsetY = locationInView.y / SCREEN_HEIGHT * (maxCellRatio - 1) * sqrt(SCREEN_HEIGHT * (gap))
+        return SCREEN_HEIGHT + panOffsetY
+    }
+    
+    // (normalHeight - locationY) / normalHeight = (normalHeight - (locationY + transitionY)) / newCellHeight
+    func computeCellHeightUnderNormalZoomInOut() -> CGFloat {
+        let targetCellheight = isFromFullScreen == false ? CELL_NORMAL_HEIGHT : SCREEN_HEIGHT
+        return ((targetCellheight - (locationInView.y + translationInView.y)) * targetCellheight) / (targetCellheight - locationInView.y)
+    }
+    
+    // panOffY * panOffY = (1- minRatio) * (1- minRatio) * normalHeight * normalHeight * transitionY/ (normalHeight - locationY)
+    func computeCellHeightUnderExtraZoomOut() -> CGFloat {
+        let gap = isFromFullScreen == false ? translationInView.y : (translationInView.y - reachNormalTransitionYFromFullScreen < 0 ? 0 : translationInView.y - reachNormalTransitionYFromFullScreen)
+        let denominator = isFromFullScreen == false ? CELL_NORMAL_HEIGHT - locationInView.y : CELL_NORMAL_HEIGHT - reachNormalLocationYFromFullScreen + POSTER_HEIGHT
+        let numerator = (1 - minCellRatio) * (1 - minCellRatio) * CELL_NORMAL_HEIGHT * CELL_NORMAL_HEIGHT * (gap)
+        let panOffsetY = sqrt(numerator / denominator)
+        return CELL_NORMAL_HEIGHT - panOffsetY
+    }
+    
+    func reachNormalHeightSetting(recognizer:UIPanGestureRecognizer) {
+        if hasReachNormalHeightFromFullScreen == false {
+            reachNormalLocationYFromFullScreen = recognizer.locationInView(collectionView).y
+            reachNormalTransitionYFromFullScreen = recognizer.translationInView(collectionView).y
+            hasReachNormalHeightFromFullScreen = true
         }
     }
 }

    private var reachNormalLocationYFromFullScreen:CGFloat = 0.0
    private var reachNormalTransitionYFromFullScreen:CGFloat = 0.0
    private var locationInView:CGPoint = CGPointZero
    private var locationRatio:CGFloat = 0
    
    override func viewWillAppear(animated: Bool) {

            }
        } else if recognizer.state == UIGestureRecognizerState.Changed {
            if isPanVertical {
                translationInView = recognizer.translationInView(view)
                var newCellHeight:CGFloat = 0
                if isFromFullScreen == false {
                    if translationInView.y >= 0 {
                        newCellHeight = computeCellHeightUnderExtraZoomOut()
                    }else {
                        newCellHeight = computeCellHeightUnderNormalZoomInOut()
                        if newCellHeight >= SCREEN_HEIGHT {
                            reachNormalHeightSetting(recognizer)
                            newCellHeight = computeCellHeightUnderExtraZoomIn()
                        }
                    }
                }else {
                    if translationInView.y >= 0 {
                        newCellHeight = computeCellHeightUnderNormalZoomInOut()
                        if newCellHeight <= CELL_NORMAL_HEIGHT {
                            reachNormalHeightSetting(recognizer)
                            newCellHeight = computeCellHeightUnderExtraZoomOut()
                        }
                    }else {
                        newCellHeight = computeCellHeightUnderExtraZoomIn()
                    }
                }
                let newCellWidth = normalCellWidth * newCellHeight / CELL_NORMAL_HEIGHT
                let ratio = newCellWidth / normalCellWidth
                let newCellGap = ratio * cellGap
                let fastenCellGap = locationInView.x - locationRatio * (newCellWidth + newCellGap)
                let targetCellheight = isFromFullScreen == false ? CELL_NORMAL_HEIGHT : SCREEN_HEIGHT
                collectLayout.itemSize = CGSizeMake(newCellWidth, newCellHeight)
                collectLayout.minimumLineSpacing = newCellGap
                collectLayout.sectionInset = UIEdgeInsetsMake(targetCellheight - newCellHeight, newCellGap + fastenCellGap + translationInView.x, 0, newCellGap)
            }
        }else if (recognizer.state == UIGestureRecognizerState.Cancelled || recognizer.state == UIGestureRecognizerState.Ended){
            if isPanVertical == true {
                let isZoomed = collectLayout.itemSize.width / normalCellWidth > 1
                let duration = isZoomed ? 0.3 : 0.2
