In a recent custom PageControl - KYAnimatedPageControl, I implemented the deformation animation of CALayer and the elastic animation of CALayer. Here are the effects: Let’s make an outline first: The first topic I want to share is "How to make CALayer deform". This technology was involved in my previous project KYCuteView, and I also wrote a short blog post on the implementation principle. Today I will give another example. I have also made elastic animations similar to jelly effects before, such as this project - KYGooeyMenu. The core technology used is CAKeyframeAnimation, and then setting several keyframes in different states can initially achieve this elastic effect. However, after all, there are only a few keyframes, and they need to be calculated manually, which is not accurate, and the animation is not delicate enough. After all, you can't create 60 keyframes manually. Therefore, the second topic today is - "How to create 60 keyframes with damped vibration function", so as to realize CALayer to produce elastic animations similar to [UIView animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion]. text. How to make CALayer deform? The key technique is very simple: you need to use multiple Bezier curves to "piece together" this layer. The reason for doing this is self-evident, because it makes it easier for us to deform. For example, the ball in KYAnimatedPageControl is actually drawn like this: The ball is composed of four arcs: arc AB, arc BC, arc CD, and arc DA. Each arc is bound to two control points: arc AB is bound to C1 and C2; arc BC is bound to C3 and C4.... How to express each point? First, A, B, C, and D are four moving points, and the variable that controls their movement is contentOffset.x of ScrollView. We can get this variable in real time in -(void)scrollViewDidScroll:(UIScrollView *)scrollView and convert it into a coefficient controlled between 0 and 1, named factor. Assume that the maximum change distance of A, B, C, and D is 2/5 of the diameter of the ball. Then, combined with this coefficient of 0~1, we can deduce that the actual change distance of A, B, C, and D is extra = (self.width * 2 / 5) * factor. When factor == 1, the maximum deformation state is reached, and the change distance of the four points is (self.width * 2 / 5). Note: Depending on the sliding direction, we also need to determine whether point B is moving or point D is moving.
Then the control points: The key is to know the lengths of the horizontal and vertical dashed lines A-C1, B-C2, B-C3, C-C4, etc. in the above figure, named offSet. After many attempts, I came to the conclusion that: When the offSet is set to the diameter divided by 3.6, the arc can fit perfectly into a circular arc. I vaguely feel that this 3.6 is inevitable, and it seems to have some relationship with 360 degrees. Perhaps the inevitability of the value of 3.6 can be obtained through calculation, but I didn't try it. Therefore, the coordinates of each control point are:
With the end point and control point, you can use the method provided in UIBezierPath - (void)addCurveToPoint:(CGPoint)endPoint controlPoint1:(CGPoint)controlPoint1 controlPoint2:(CGPoint)controlPoint2; to draw a line segment. Override CALayer's - (void)drawInContext:(CGContextRef)ctx; method and draw the pattern in it:
Now, when you scroll the ScrollView, the ball will deform. How to create 60 keyframes using the damped vibration function? In the above example, there is a very important factor, which is the contentOffset.x variable in ScrollView. Without this input, nothing will happen next. However, to obtain this variable, the user needs to touch and slide to interact. In a certain animation, the user does not have direct interactive input. For example, when the finger is removed, the ball needs to bounce back to the initial state with a jelly effect. In this process, the finger has left the screen and there is no input. Therefore, the above method will definitely not work. Therefore, we can use CAAnimation. We know that in iOS7, Apple added a new factory method for making elastic animations in UIView (UIViewAnimationWithBlocks):
But there is no direct elastic CAAnimation subclass, like CABasicAnimation or CAKeyframeAnimation, to directly add animation to CALayer. The good news is that iOS 9 adds the public CASpringAnimation. But for compatibility with lower versions and for the sake of knowledge, we can learn how to manually create an elastic animation for CALayer. Before we begin, you need to review some high school physics knowledge - damped vibration. You can click on the highlighted link for a brief review. According to Wikipedia, we can get the following general formula for vibration function: Of course, this is just a general formula. We need to let the image pass through (0,0) and finally decay to 1. We can first flip the original image 180 degrees around the X axis, that is, add a negative sign. Then translate it one unit upward along the y axis. So with a slight deformation, we can get the following function: Want to see the graph of the function? No problem. I recommend a website for viewing function graphs online - Desmos. Copy and paste this formula 1-\left(e^{-5x}\cdot \cos (30x)\right) into it to see the graph. The improved function graph is as follows: This perfectly meets our requirement that the graph passes through (0,0) and the oscillation decays to 1. The 5 in the formula is equivalent to the damping coefficient, the smaller the value, the greater the amplitude; the 30 in the formula is equivalent to the oscillation frequency, the larger the value, the more oscillations. Next we need to convert it into code. The overall idea is to create 60 keyframes (because the maximum refresh rate of the screen is 60FPS), and then assign these 60 frames of data to the values property of CAKeyframeAnimation. Use the following code to generate 60 frames, save them into an array and return them, where //1 is to create 60 values using the formula just now:
Next, create an external class method that returns a CAKeyframeAnimation:
Another key Above, we created CAKeyframeAnimation. But who do these values work for? If you are familiar with CoreAnimation, yes, it works on the keypath passed in. And these keypaths are actually the @property attributes in CALayer. For example, the reason why CAKeyframeAnimation rotates the layer when the passed keypath is transform.rotation.x is because CAKeyframeAnimation finds that there is such a property called transform in CALayer, so the animation occurs. Now what we need to change is the factor variable in Topic 1, so it is natural to think that we can add a property called factor to CALayer, so that when CAKeyframeAnimation is added to the layer and finds that the layer has this factor attribute, it will assign 60 frames of different values to the factor. Of course, we have to control fromValue and toValue between 0 and 1:
The last step is that although CAKeyframeAnimation changes the factor we want in real time, we still have to notify the screen to refresh so that we can see the animation.
The above code notifies the screen to refresh the screen in real time when the factor changes. Finally, you need to override the -(id)initWithLayer:(GooeyCircle *)layer method in CALayer. In order to ensure the continuity of the animation, you need to copy the layer and all its properties in the previous state.
Summarize: The key to making custom animations is to have variables and inputs. For example, when sliding a ScrollView, the sliding distance is the animation input and can be used as the animation variable. When there is no interaction, CAAnimation can be used. In fact, CAAnimation has a timer at the bottom layer, and the function of the timer is to generate variables. Time is a variable, which can generate variable inputs and see the changing state. When connected together, it becomes an animation. |
<<: Exclusive interview with APICloud CTO Zou Da: A full-stack engineer forced out
>>: Apple's secret to success: Don't be the first to strike back
Because of the collapse of the Internet TV concep...
On December 15, BYD Dynasty Network's B-class...
Original title: Changing your cerebrospinal fluid...
Not long ago, the news about Xiaohongshu conducti...
If we were to add an adjective to Apple, there wo...
Mixed Knowledge Specially designed to cure confus...
“Wine and coffee, I love this one” Source: Weibo ...
More and more businesses are paying attention to ...
Mark's Favorite Musk July and August 2021 Cou...
The article mainly introduces two strategic imple...
Recently, foreign media released the global new e...
A friend told Huazi that he had seen an article f...
Household cleaning has become a habit in our mode...
Source: Youlai Healthy Life...