The layer mask attribute is used to achieve the animation effect gradually revealed.

Source: Internet
Author: User

The layer mask attribute is used to achieve the animation effect gradually revealed.

Github saw a good animation (https://github.com/rounak/RJImageLoader), so I want to achieve the following by myself do not know, this animation really does not look so simple, I think for a long time is not done out, finally, I read the author's code to know how to implement it. However, I learned a trick from the author, that is, the usage of layer. mask. Self-implemented effect demo here: https://github.com/Phelthas/LXMRevealDemo (the circle in front of the animation, This Is A CAShaperLayer to modify its strokeEnd animation, relatively simple, there is no more to write) This animation is difficult to say it is not difficult, the key lies in the layer. if you do not know how to use mask features. it is quite difficult to implement the features of the mask. On the contrary, if you know it, the idea will suddenly become open. The key is this:/* A layer whose alpha channel is used as a mask to select between the * layer's background and the result of compositing the layer's
* Contents with its filtered background. Defaults to nil. When used
* A mask the layer's 'compositingfilter' and 'backgroundfilters'
* Properties are ignored. When setting the mask to a new layer,
* New layer must have a nil superlayer, otherwise the behavior is
* Undefined. nested masks (mask layers with their own masks) are * unsupported. */@ property (strong) CALayer * mask; the mask attribute can implement many shapes of masks. The basic effect is: for example, layerA is the mask of layerB, that is, layerB. mask = layerA; then the transparent part on layerA will be drawn in white to block layerB (it seems to be white and I don't know if it can be made into other colors); the opaque part on layerA, the content of layerB is displayed as transparent. Note: The layer Used as the mask cannot have a superLayer or subLayer! With this in mind, the idea of animation is as follows: The imageView has a mask, and the transparent part of the mask gradually grows and expands outward at the same time, so that the image after the mask is revealed. Here, we need a circular CAShapeLayer and two animations to make the layer expand outward at the same time. So the question is, there is only one layer, and there is no subLayer. How can we make it larger and smaller at the same time? The answer is: in another way. Note that CAShapeLayer is drawn by line, the line also has color, and the width is lineWidth, and these attributes can also be animated. Therefore, the final solution is to set the color of the circle to transparent, the filled color of the circle to opaque, and the color outside the garden to opacity (the setting here refers to the effect seen ), gradually increase the circle to display the entire view, and gradually increase the lineWidth of the circle to the radius of the circle. The effect is that the image is gradually displayed as shown above. The core animation code is as follows:-(void) reveal {
Self. backgroundColor = [UIColor clearColor];
[Self. circleLayer removeFromSuperlayer]; // theoretically, a layer as a mask cannot have a parent layer, so remove it.
Self. superview. layer. mask = self. circleLayer;

// Animation that makes the circle bigger
CABasicAnimation * pathAnimation = [CABasicAnimation animationWithKeyPath: @ "path"];
UIBezierPath * toPath = [self pathWithDiameter: self. bigDiameter];
// UIBezierPath * toPath = [self pathWithDiameter: 0]; // reduce the animation of the current path
PathAnimation. toValue = (id) toPath. CGPath;
PathAnimation. duration= 1.0;
 

// The animation that increases the width of the line of the circle. The effect is that the inner circle is smaller.
CABasicAnimation * lineWidthAnimation = [CABasicAnimation animationWithKeyPath: NSStringFromSelector (@ selector (lineWidth)];
LineWidthAnimation. toValue = @ (self. bigDiameter );
LineWidthAnimation. duration = 1.0;

CAAnimationGroup * group = [CAAnimationGroup animation];
Group. animations = @ [pathAnimation, lineWidthAnimation];
Group. duration= 1.0;
Group. removedOnCompletion = NO; // The effect of the two sentences is that the animation will not return to the original place after the animation ends. You must add
Group. fillMode = kCAFillModeForwards; // The effect of the two statements is that the animation will not return to the original position after the animation ends. You must add
Group. delegate = self;

[Self. circleLayer addAnimation: group forKey: @ "revealAnimation"];}/**
* Generate the circle path based on the diameter. Note that the dot is the center point of self, so (x, y) is not (0, 0)
*/
-(UIBezierPath *) pathWithDiameter :( CGFloat) diameter {
Return [UIBezierPath parameters: CGRectMake (CGRectGetWidth (self. bounds)-diameter)/2, (CGRectGetHeight (self. bounds)-diameter)/2, diameter, diameter)];
}


# Pragma mark-CAAnimationDelegate

-(Void) animationDidStop :( CAAnimation *) anim finished :( BOOL) flag {
Self. superview. layer. mask = nil;
[Self removeFromSuperview];
}


# Pragma mark-property

-(CAShapeLayer *) circleLayer {
If (! _ CircleLayer ){
_ CircleLayer = [CAShapeLayer layer];
_ CircleLayer. fillColor = [UIColor clearColor]. CGColor; // This must be transparent, because the incircle is not transparent.
_ CircleLayer. strokeColor = [UIColor yellowColor]. CGColor;
_ CircleLayer. path = [self pathWithDiameter: self. smallDiameter]. CGPath;
}
Return _ circleLayer;} For the complete code, see github: https://github.com/phelthas/lxmrevealdemo

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.