user1824518
user1824518

Reputation: 223

"Squash" animation effect

I'm trying to make my image look like it's being stepped on, or "squashed". This is the code I have to far, but instead of only squashing, it pushes the bottom up as well (since it's a scale animation). Is there a way I could make the image simply shorten rather than downscale? Perhaps I need to use two images?:

            [UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseInOut
                             animations:^{
                                 basketView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1, 0.9);}
                             completion:^(BOOL finished){if (finished){

                [UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionCurveEaseInOut
                                 animations:^{
                                     basketView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.0);}
                                 completion:NULL];}}];

Upvotes: 1

Views: 285

Answers (1)

Tommy
Tommy

Reputation: 100622

Scaling will occur relative to the view's layer's anchorPoint, which is the centre of the layer by default.

Options are therefore: - change the anchor point; - compose the transform in three parts: (1) translate anchor to the bottom; (2) scale; (3) translate anchor back to where it was; - compose the transform in two parts: (1) scale; (2) translate the bottom to where it originally was.

Changing the anchor point has the same effect as a translation if everything else is equal so the summary version is to add a translation in some form, regardless of how you describe the whole process. The easiest thing is probably to set the layer's center at the same time as you set the transform. As both scaling and translation are linear transforms being applied simultaneously they'll exactly synchronise.

So e.g. you'd change:

basketView.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1, 0.9);

To something more like:

CGFloat amountToScale = 0.9f;

CGAffineTransform transform =
            CGAffineTransformMakeTranslation(0.0f, 
                      (1.0f - amountToScale)*0.5f*basketView.bounds.size.height);

basketView.transform = CGAffineTransformScale(transform, 
                                    1.0f, amountToScale);

In that specific case, scaling to 0.9 would eliminate a total of 0.1 of the original size. The anchor point is at the centre so 0.05 of that comes off the top and 0.05 of it comes off the bottom. You don't want anything to come off the bottom so you shift the view down to counteract that.

Upvotes: 2

Related Questions