美文网首页
个人中心波浪特效

个人中心波浪特效

作者: Ice_tree | 来源:发表于2016-08-25 15:20 被阅读0次

    相信很多人见过app个人中心的波浪动画效果吧,是不是觉得很酷?
    接下来,我会给大家分享一个实现的思路。
    先上图,看看效果。


    jswave.gif

    忽略掉这个晃眼的红色(毕竟只是用来做示例),这个波浪效果很带感吧。

    简单原理,CAShapeLayer 结合CGPath绘制图形。
    动画操作的是CAShapeLayer(CALayer的子类)层,而非直接操作UIView。
    CAShapeLayer在渲染速度,显示效果,内存占用,资源消耗上均有不小优势。对于CALayer和UIView的区别以及CAShapeLayer不是很了解的读者,可以阅读我在文章结尾附上的相关知识链接。

    看代码实现部分
    <pre><code>
    @interface ZSWave : UIView

    @property (nonatomic, assign) CGFloat waveSpeed;//浪弯曲度

    @property (nonatomic, assign) CGFloat speed;//浪速

    @property (nonatomic, assign) CGFloat waveHeight;//浪高

    @property (nonatomic, strong) UIColor *realWaveColor;//实浪颜色

    @property (nonatomic, strong) UIColor *maskWaveColor;//遮罩浪颜色

    @property (nonatomic, strong) UIView *headerImageWallView;//头像父视图

    - (void)stopWaveAnimation;

    - (void)startWaveAnimation;

    @end
    </pre></code>
    <pre><code>
    @interface ZSWave ()

    @property (nonatomic, strong) CADisplayLink *timer;//刷屏器

    @property (nonatomic, strong) CAShapeLayer *realWaveLayer;//真实浪

    @property (nonatomic, strong) CAShapeLayer *maskWaveLayer;//遮罩浪

    @property (nonatomic, assign) CGFloat offset;

    @end

    </pre></code>
    <pre><code>
    - (instancetype)initWithFrame:(CGRect)frame
    {
    if ([super initWithFrame:frame]) {
    [self initData];
    }
    return self;
    }

    - (void)initData{

    [self.layer addSublayer:self.realWaveLayer];
    [self.layer addSublayer:self.maskWaveLayer];
    [self addSubview:self.headerImageWallView];
    
    [self startWaveAnimation];
    

    }

    - (void)startWaveAnimation{

    self.timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(wave)];
    [self.timer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
    

    }

    - (void)stopWaveAnimation{

    [self.timer invalidate];
    self.timer = nil;
    

    }

    </pre></code>

    核心代码

    <pre><code>
    - (void)wave{

    [self layoutIfNeeded];
    
    self.offset += self.speed;
    
    CGFloat width = CGRectGetWidth(self.frame);
    CGFloat height = CGRectGetHeight(self.frame);
    
    //真实浪
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, NULL, 0, height );
    CGFloat y = 0.f;
    for (CGFloat x = 0.f; x <= width ; x++) {
        y = height * sinf(0.01 * self.waveSpeed * x + self.offset * 0.045);
        CGPathAddLineToPoint(path, NULL, x, y);
    }
    
    CGFloat centX = self.center.x;
    CGFloat CentY = height * sinf(0.01 * self.waveSpeed *centX  + self.offset * 0.045);
    CGRect iconFrame = [self.headerImageWallView frame];
    iconFrame.origin.y = CentY - iconFrame.size.height;
    self.headerImageWallView.frame  =iconFrame; //调整头像位置,随波浪运动
    CGPathAddLineToPoint(path, NULL, width, height);
    CGPathAddLineToPoint(path, NULL, 0, height);
    CGPathCloseSubpath(path);
    self.realWaveLayer.path = path;
    self.realWaveLayer.fillColor = self.realWaveColor.CGColor;
    CGPathRelease(path);
    //遮罩浪
    CGMutablePathRef maskpath = CGPathCreateMutable();
    CGPathMoveToPoint(maskpath, NULL, 0, height);
    CGFloat maskY = 0.f;
    for (CGFloat x = 0.f; x <= width ; x++) {
        maskY = height * cosf(0.01 * self.waveSpeed * x + self.offset * 0.045);
        CGPathAddLineToPoint(maskpath, NULL, x, maskY);
    }
    CGPathAddLineToPoint(maskpath, NULL, width, height);
    CGPathAddLineToPoint(maskpath, NULL, 0, height);
    CGPathCloseSubpath(maskpath);
    self.maskWaveLayer.path = maskpath;
    self.maskWaveLayer.fillColor = self.maskWaveColor.CGColor;
    CGPathRelease(maskpath);
    

    }

    </pre></code>
    默认属性设置及初始化
    <pre><code>
    #pragma mark - Initialize parameter

    - (CGFloat)waveSpeed {

    if (!_waveSpeed) {
        _waveSpeed = 1.5;
    }
    return _waveSpeed;
    

    }

    - (CGFloat)speed {

    if (!_speed) {
        _speed = 0.7;
    }
    return _speed;
    

    }

    - (CGFloat)waveHeight {

    if (!_waveHeight) {
        _waveHeight = 5;
    }
    return _waveHeight;
    

    }

    - (UIColor *)realWaveColor {

    if (!_realWaveColor) {
        _realWaveColor = [UIColor whiteColor];
    }
    return _realWaveColor;
    

    }

    - (UIColor *)maskWaveColor {

    if (!_maskWaveColor) {
        _maskWaveColor = [[UIColor whiteColor]colorWithAlphaComponent:0.3];
    }
    return _maskWaveColor;
    

    }

    #pragma mark - lazy loading

    - (CAShapeLayer *)realWaveLayer{

    if (!_realWaveLayer) {
        _realWaveLayer = [CAShapeLayer layer];
        _realWaveLayer.frame =  self.bounds;
        _realWaveLayer.fillColor = self.realWaveColor.CGColor;
        
    }
    return _realWaveLayer;
    

    }

    - (CAShapeLayer *)maskWaveLayer{

    if (!_maskWaveLayer) {
        _maskWaveLayer = [CAShapeLayer layer];
        _maskWaveLayer.frame =  self.bounds;
        _maskWaveLayer.fillColor = self.maskWaveColor.CGColor;
    }
    return _maskWaveLayer;
    

    }

    - (UIView *)headerImageWallView {

    if (!_headerImageWallView) {
        _headerImageWallView = [[UIView alloc]initWithFrame:CGRectMake(self.center.x - 30, -60, 60, 60)];
        _headerImageWallView.layer.borderColor = [UIColor whiteColor].CGColor;
        _headerImageWallView.layer.borderWidth = 2;
        _headerImageWallView.layer.cornerRadius = 20;
    }
    return _headerImageWallView;
    

    }

    </pre></code>
    最后一定记得重写dealloc,把定时器注销。
    <pre><code>
    - (void)dealloc{

    [self stopWaveAnimation];
    

    }
    </pre></code>
    参考资料CADisplayLinkCALayer和UIView的区别

    相关文章

      网友评论

          本文标题:个人中心波浪特效

          本文链接:https://www.haomeiwen.com/subject/xuxasttx.html