             arrowPosition = .bottom
             
             // Restart the entire process
-            let flippedFrame = calculateFrame(with: font)
+            let flippedFrame = bubbleViewFrame
             y = flippedFrame.origin.y
             height = flippedFrame.size.height
         } else if (arrowPosition == .bottom && y < 0) {
             arrowPosition = .top
             
             // Restart the entire process
-            let flippedFrame = calculateFrame(with: font)
+            let flippedFrame = bubbleViewFrame
             y = flippedFrame.origin.y
             height = flippedFrame.size.height
         }


        // Tip of the arrow needs to be centered under highlighted region
        // This center area is always arrow size divided by 2
        let center = ARROW_SIZE / 2

        //  points used to draw arrow
        //  Wide Arrow --> x = center + - ArrowSize
        //  Skinny Arrow --> x = center + - center
        //  Normal Arrow -->
        let startPoint = CGPoint(x: center - ARROW_SIZE, y: ARROW_SIZE)
        let midPoint = CGPoint(x: center, y: 0)
        let endPoint = CGPoint(x: center + ARROW_SIZE, y: ARROW_SIZE)

        let path = UIBezierPath()
        path.move(to: startPoint)

        path.stroke()
        ctx.restoreGState()
    }
        
    /// Start bounce animation
    func animate() {
        UIView.animate(withDuration: 2.0, delay: 0.3, options: [.repeat, .autoreverse], animations: {
            self.transform = CGAffineTransform(translationX: 0, y: -5)
        }, completion: nil)
    }
    
    /// Check if bubble is going off the screen using the position and size. If it is, return true
    func fixFrameIfOutOfBounds() {
        guard let window = UIApplication.shared.keyWindow?.frame else {
            print("Couldn't get app window")
