水波紋-iOS

簡(jiǎn)介

使用iOS原生CoreGraphic框架完成,主要內(nèi)容就是在給定的路徑上繪制出圖形,水波紋的實(shí)現(xiàn)是按照三角函數(shù)的sin函數(shù)來實(shí)現(xiàn)的,利用sin函數(shù)計(jì)算出大量的點(diǎn),然后做顏色填充。

實(shí)現(xiàn)方法

首先一個(gè)波紋需要一個(gè)layer來進(jìn)行渲染,越底層的波紋要越早繪制,本Demo只實(shí)現(xiàn)了雙波紋交錯(cuò)。
水波紋基本屬性:

不需要對(duì)外暴露的屬性

@interface WaterRippleView(){
    float _currentLinePointY;
}
@property (nonatomic, strong)CADisplayLink *rippleDisplayLink;//蘋果的垂直同步
@property (nonatomic, strong)CAShapeLayer *mainRippleLayer;//主波圖層
@property (nonatomic, strong)CAShapeLayer *minorRippleLayer;//次波圖層
@property (nonatomic, assign)CGFloat rippleWidth;//波浪寬度
@end

可以對(duì)外暴露的屬性

@property (nonatomic, strong)UIColor *mainRippleColor;//主波填充顏色
@property (nonatomic, strong)UIColor *minorRippleColor;//次波填充顏色
@property (nonatomic, assign)CGFloat mainRippleoffsetX;//主波偏移量
@property (nonatomic, assign)CGFloat minorRippleoffsetX;//次波偏移量
@property (nonatomic, assign)CGFloat rippleSpeed;//波浪速度
@property (nonatomic, assign)CGFloat ripplePosition;//波浪Y軸位置
@property (nonatomic, assign)float rippleAmplitude;//波浪振幅

各屬性的默認(rèn)值設(shè)置

        self.mainRippleColor = [UIColor colorWithRed:255/255.0f green:127/255.0f blue:80/255.0f alpha:1];
        self.minorRippleColor = [UIColor whiteColor];
        self.mainRippleoffsetX = 1;
        self.minorRippleoffsetX = 2;
        self.rippleSpeed = .5f;
        self.rippleWidth = frame.size.width;
        self.ripplePosition = frame.size.height-10.0f;
        self.rippleAmplitude = 5;

對(duì)外暴露的方法

//設(shè)置frame 主波填充顏色  次波填充顏色
- (instancetype)initWithFrame:(CGRect)frame mainRippleColor:(UIColor *)mainRippleColor minorRippleColor:(UIColor *)minorRippleColor;
//設(shè)置frame 主波填充顏色  次波填充顏色 主波偏移量 次波偏移量 波浪速度 波浪Y軸位置 波浪振幅
- (instancetype)initWithFrame:(CGRect)frame mainRippleColor:(UIColor *)mainRippleColor minorRippleColor:(UIColor *)minorRippleColor mainRippleoffsetX:(float)mainRippleoffsetX minorRippleoffsetX:(float)minorRippleoffsetX rippleSpeed:(float)rippleSpeed ripplePosition:(float)ripplePosition rippleAmplitude:(float)rippleAmplitude;

在view中需要繪制圖形時(shí),要在自帶的dramRect:方法中編寫相關(guān)代碼

- (void)drawRect:(CGRect)rect {
    /*
     *創(chuàng)建兩個(gè)layer
     */
    self.mainRippleLayer = [CAShapeLayer layer];
    self.mainRippleLayer.fillColor = self.mainRippleColor.CGColor;
    [self.layer addSublayer:self.mainRippleLayer];
    self.minorRippleLayer = [CAShapeLayer layer];
    self.minorRippleLayer.fillColor = self.minorRippleColor.CGColor;
    [self.layer addSublayer:self.minorRippleLayer];
    self.rippleDisplayLink = [CADisplayLink displayLinkWithTarget:self
                                                         selector:@selector(getCurrentRipple)];
    [self.rippleDisplayLink addToRunLoop:[NSRunLoop mainRunLoop]
                                 forMode:NSRunLoopCommonModes];
}

下面是繪制代碼:
主波

- (void)drawMainRipple{
    self.mainRippleoffsetX += self.rippleSpeed;
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathMoveToPoint(path, nil, 0, self.ripplePosition);
    CGFloat y = 0.f;
    for (float x = 0.f; x <= self.rippleWidth ; x++) {
        y = self.rippleAmplitude * sin(1.2 *  M_PI/ self.rippleWidth  * x   - self.mainRippleoffsetX *M_PI/180) + self.ripplePosition;
        CGPathAddLineToPoint(path, nil, x, y);
    }
    CGPathAddLineToPoint(path, nil, self.rippleWidth, self.frame.size.height);
    CGPathAddLineToPoint(path, nil, 0, self.frame.size.height);
    CGPathCloseSubpath(path);
    self.mainRippleLayer.path = path;
    CGPathRelease(path);
}

次波

- (void)drawMinorRipple{
    self.minorRippleoffsetX += self.rippleSpeed+0.1f;
    CGMutablePathRef minorRipple = CGPathCreateMutable();
    CGPathMoveToPoint(minorRipple, nil, 0, self.ripplePosition);
    CGFloat y = 0.f;
    for (float x = 0.f; x <= self.rippleWidth ; x++) {
        y = self.rippleAmplitude * sin(1.2 *  M_PI/ self.rippleWidth  * x   - self.minorRippleoffsetX*M_PI/360 ) + self.ripplePosition;
        CGPathAddLineToPoint(minorRipple, nil, x, y);
    }
    CGPathAddLineToPoint(minorRipple, nil, self.rippleWidth, self.frame.size.height);
    CGPathAddLineToPoint(minorRipple, nil, 0, self.frame.size.height);
    CGPathCloseSubpath(minorRipple);
    self.minorRippleLayer.path = minorRipple;
    CGPathRelease(minorRipple);
}

實(shí)現(xiàn)效果

水波紋Gif

最后

本Demo的git庫(kù)地址:https://gitee.com/LiynXu/waterripple
歡迎訪問

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容