lottie-ios icon indicating copy to clipboard operation
lottie-ios copied to clipboard

Aspect Fit Content Mode animation drawing outside expected view port

Open bencallis opened this issue 5 years ago • 1 comments

Check these before submitting:

  • [ ] The issue doesn't involve an Unsupported Feature
  • [x] This issue isn't related to another open issue

This issue is a:

  • [x] Non-Crashing Bug (Visual or otherwise)
  • [] Crashing Bug
  • [] Feature Request
  • [] Regression (Something that once worked, but doesn't work anymore)

Which Version of Lottie are you using?

Lottie 3.1.8

What Platform are you on?

  • [] MacOS
  • [x] iOS

What Language are you in?

  • [x] Swift
  • [] Objective-C

Expected Behavior

When using the scaleAspectFit content mode I expect the animation to be clipped to the newly scaled size. Using the same animation on Android with fitCentre works as expected.

Actual Behavior

The animation is centred and scaled within the animationView as expected, however, parts of the animation which go outside the animation frame are still displayed

Screenshot_09_09_2020__14_06

For debug purposes I have set an orange background on animationView. This is shown in the following screenshot and video. animation aspectfill issue.mov.zip

Simulator_Screen_Shot_-iPhone_SE-_2020-09-09_at_15_10_22

Code Example

    lazy var animationView: AnimationView = {
        let lottieView = AnimationView()
        lottieView.contentMode = .scaleAspectFit
        lottieView.backgroundBehavior = .pauseAndRestore
        lottieView.translatesAutoresizingMaskIntoConstraints = false
        lottieView.accessibilityIdentifier = "animatedImage"
        return lottieView
    }()
Below code is debuted after the view has 
(lldb) po animation.size
▿ (316.0, 200.0)
  - width : 316.0
  - height : 200.0

po animationView.frame
▿ (28.0, 0.0, 264.0, 200.0)
  ▿ origin : (28.0, 0.0)
    - x : 28.0
    - y : 0.0
  ▿ size : (264.0, 200.0)
    - width : 264.0
    - height : 200.0

There is less width available than required so the animation has to be scaled with scaleAspectFit.

Given that the available width is only 264 and the animation aspect ratio is (316 / 200) the height will be ~167.

The animation is centred and scaled within the animationView as expected, however, the animation includes items that go out of the animation view but are still included.

Possible work arounds

  1. Instead of using intrinsic content size to get the image height. We could programatically work out the image height based on the available screen width and set an explicit height constraint.
  2. I notice there is a viewport property that we could set if we work out the actual size in code.

bencallis avatar Sep 09 '20 14:09 bencallis

We are currently working around this issue by adding an explicit aspect ratio constraint to the animationView

        let aspectRatio = animation.size.width / animation.size.height
        animationView.widthAnchor.constraint(equalTo: animationView.heightAnchor, multiplier: aspectRatio).isActive = true

This means that the height of the animationView is always relative to the aspect ratio of the image and if the animation need to be scaled down due to the available width the height will automatically change too. Rather than just relying on the intrinsic content size.

It would still be nice if the animationView would clip automatically though in these cases as it does on Android.

bencallis avatar Sep 11 '20 14:09 bencallis

I believe this was fixed by https://github.com/airbnb/lottie-ios/pull/1814

calda avatar Nov 29 '22 17:11 calda