美文网首页
iOS动画之水波动画

iOS动画之水波动画

作者: nongjiazhen | 来源:发表于2018-11-09 09:37 被阅读0次
    • 前言:现在很多app为了提供好的交互效果给用户,通常都会通过添加动画效果来达到目的。一个好的动画效果往往会起到神来之笔的作用。而在IOS中动画效果也是丰富多彩的,我准备在后续的笔记中详细的记录那些动画。
    • 今天我们就来实现一下在IOS中的水波动画。先上效果图:
    • 最开始看到这个效果确实有点难的,不过如果对正弦公式比较了解的话实现起来也挺简单的。

      • 高中知识:y = Asin(wx + θ) + k;

      • 其中A:代表振幅; w:角频率,和周期的关系是:T = 2π/|w| ;θ:初相,相对于标准的正弦公式y = sin(x)而言,θ代表

      • 标准的正弦公式y = sin(x)在水平(x轴)方向上的整体移动,即左加右减;k:偏距,代表标准的正弦公式y = sin(x)在 垂直(y轴)方向上的整体移动,即上加下减。

      • 由表达式 y = sin(x)我们知道:在[0,2π]的区间上绘制一个完整的正弦波形,周期刚好是2π(T= 2π/|w|) 这里w = 1;绘制2个完整的正弦波形,周期为π。所以可以把w理解成完整波形的个数。由此可以得出:在区间[0,waveWidth]上绘制n个完整的波形,w = 2π * n / waveWidth。另外还要注意一点就是UIKit框架坐标轴是向下的。

      • 上面的知识也只是对正弦公式进行回顾。怎么样才能得到波形效果呢?关键点就在初相θ身上。

      • 下面这张图是正弦公式:y = sin(x)的图谱:


        我们把初相θ向左移动1个单位长度得到公式:y = sin(x + 1)的图谱:


        比较这两张图谱,我们可以从中发现:要想实现波形震荡效果,我们只需不断变化初相θ的值,然后不断刷新屏幕即可。

      • CADisplayLink:这个定时器的刷新频率是60HZ,即每秒可以对屏幕进行60次刷新,我们肉眼是感觉不出刷新间隔的时差的。
        整个实现过程的代码如下:

    @interface JGWaterWaveAnimation()
    {
        //振幅--这个决定波形的起伏高度
        CGFloat _waterAmplitude;
        //频率--这个决定波形的宽度
        CGFloat _waterFrequency;
        //初相:这个决定了波形水平移动的速度
        CGFloat _waterEpoch;
        //偏距--调节距离顶部的高度
        CGFloat _waterSetover;
        //定时器
        CADisplayLink *_timer;
        
        //波形整个的宽度
        CGFloat _waterWaveWidth;
        //波形的整个高度
        CGFloat _waterWaveHeight;
    }
    /**layer*/
    @property(strong,nonatomic)CAShapeLayer *waterShapeLayer;
    @end
    @implementation JGWaterWaveAnimation
    - (instancetype)initWithFrame:(CGRect)frame{
        if (self = [super initWithFrame:frame]) {
            
            //default
            _waterAmplitude = 15.0;
            //假设在frame的长度上出现3个完整的波形:注意这里乘以0.5出现震荡效果,如果不乘以0.5只会出现波形平移的效果。
            _waterFrequency = 2 *M_PI * 3 / frame.size.width *0.5;
            _waterEpoch = 0.0;
            _waterSetover = 20.0;
            
            _waterWaveWidth = CGRectGetWidth(self.frame);
            _waterWaveHeight = CGRectGetHeight(self.frame);
            
            [self.layer addSublayer:self.waterShapeLayer];
            //初始化定时器
            _timer = [CADisplayLink displayLinkWithTarget:[YYWeakProxy proxyWithTarget:self] selector:@selector(waterWaveAnimation)];
            [_timer addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
        }
        return self;
    }
    - (void)waterWaveAnimation{
        
        //核心代码:
        _waterEpoch += 0.08;
        //path
        UIBezierPath *waterWavePath = [UIBezierPath bezierPath];
        [waterWavePath moveToPoint:CGPointMake(0, 0)];
        for (CGFloat x = 0; x < _waterWaveWidth; x ++) {
            CGFloat y = _waterAmplitude * sinf(_waterFrequency * x + _waterEpoch) + _waterSetover;
            [waterWavePath addLineToPoint:CGPointMake(x, y)];
        }
        [waterWavePath addLineToPoint:CGPointMake(_waterWaveWidth, _waterWaveHeight)];
        [waterWavePath addLineToPoint:CGPointMake(0, _waterWaveHeight)];
        [waterWavePath closePath];
        
        self.waterShapeLayer.path = waterWavePath.CGPath;
    }
    - (CAShapeLayer *)waterShapeLayer{
        if (!_waterShapeLayer) {
            _waterShapeLayer = [CAShapeLayer layer];
            _waterShapeLayer.frame = self.bounds;
            _waterShapeLayer.fillColor = [UIColor colorWithRed:52/255.0 green:152/255.0 blue:219/255.0 alpha:1.0].CGColor;
            _waterShapeLayer.strokeColor = [UIColor clearColor].CGColor;
        }
        return _waterShapeLayer;
    }
    - (void)dealloc{
        
        [_timer invalidate];
        _timer = nil;
    }
    @end
    

    原文:https://blog.csdn.net/h2282802627/article/details/79116601

    相关文章

      网友评论

          本文标题:iOS动画之水波动画

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