Oc Snow Animation(下雪动画)~demo

本文介绍了如何使用CGContext在iOS应用中绘制圆角矩形、多角星及花朵等自定义图形,并通过实例展示了雪花飘落动画的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

20170817101539544.gif

20170817101650157.png

控制器1: SHContext.h

#ifndef SHContext_h
#define SHContext_h

/*
 该方法负责绘制圆角矩形
 x1、y2:是圆角矩形左上角的座标。
 width、height:控制圆角举行的宽、高
 radius:控制圆角矩形的四个圆角的半径
 */

void CGContextAddRoundRect(CGContextRef c, CGFloat x1 , CGFloat y1
                           , CGFloat width , CGFloat height , CGFloat radius)
{
    // 移动到左上角
    CGContextMoveToPoint (c, x1 + radius , y1);
    // 添加一条连接到右上角的线段
    CGContextAddLineToPoint(c , x1 + width - radius, y1);
    // 添加一段圆弧
    CGContextAddArcToPoint(c , x1 + width , y1, x1 + width
                           , y1 + radius, radius);
    // 添加一条连接到右下角的线段
    CGContextAddLineToPoint(c , x1 + width, y1 + height - radius);
    // 添加一段圆弧
    CGContextAddArcToPoint(c , x1 + width, y1 + height
                           , x1 + width - radius , y1 + height , radius);
    // 添加一条连接到左下角的线段
    CGContextAddLineToPoint(c , x1 + radius, y1 + height);
    // 添加一段圆弧
    CGContextAddArcToPoint(c , x1, y1 + height , x1
                           , y1 + height - radius , radius);
    // 添加一条连接到左上角的线段
    CGContextAddLineToPoint(c , x1 , y1 + radius);
    // 添加一段圆弧
    CGContextAddArcToPoint(c , x1 , y1 , x1 + radius , y1 , radius);
}
/*
 该方法负责绘制多角星。
 n:该参数通常应设为奇数,控制绘制N角星。
 dx、dy:控制N角星的中心。
 size:控制N角星的大小
 */


void CGContextAddStar(CGContextRef c , NSInteger n
                      , CGFloat dx , CGFloat dy , NSInteger size)
{
    CGFloat dig = 4 * M_PI / n ;
    // 移动到指定点
    CGContextMoveToPoint(c , dx , dy + size);
    for(int i = 1 ; i <= n ; i++)
    {
        CGFloat x = sin(i * dig);
        CGFloat y = cos(i * dig);
        // 绘制从当前点连接到指定点的线条
        CGContextAddLineToPoint(c , x * size + dx ,y * size + dy);
    }
}
/*
 该方法负责绘制花朵。
 n:该参数控制花朵的花瓣数。
 dx、dy:控制花朵的位置。
 size:控制花朵的大小
 length:控制花瓣的长度
 */
void CGContextAddFlower(CGContextRef c , NSInteger n
     , CGFloat dx , CGFloat dy , CGFloat size , CGFloat length)
{
    // 移动到指定点
    CGContextMoveToPoint(c , dx , dy + size);
    CGFloat dig = 2 * M_PI / n;
    // 采用循环添加n段二次曲线路径
    for(int i = 1; i < n + 1 ; i++)
    {
        // 结算控制点坐标
        CGFloat ctrlX = sin((i - 0.5) * dig) * length + dx;
        CGFloat ctrlY= cos((i - 0.5 ) * dig) * length + dy;
        // 结算结束点的坐标
        CGFloat x = sin(i * dig) * size + dx;
        CGFloat y =cos(i * dig) * size + dy;
        // 添加二次曲线路径
        CGContextAddQuadCurveToPoint(c, ctrlX , ctrlY , x , y);
    }
}


#endif /* SHContext_h */

控制器2:SHSnowView.m


#import "SHSnowView.h"
#import "SHContext.h"

@implementation SHSnowView
// 定义雪花的初始化位置
static CGPoint snowPos[] = {
    {20, 4},
    {50, 4},
    {80, 4},
    {110, 4},
    {140, 4},
    {170, 4},
    {200, 4},
    {230, 4},
    {260, 4},
    {290, 4}
};

// 计算雪花的数量
static NSInteger snowCount = sizeof(snowPos)
/ sizeof(snowPos[0]);

-(id) initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if(self)
    {
        // 控制每隔0.2秒执行一次setNeedsDisplay方法刷新自己
        [NSTimer scheduledTimerWithTimeInterval:0.2 target:self
                                       selector:@selector(setNeedsDisplay) userInfo:nil repeats:YES];
    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    // 设置采用白色作为填充色
    CGContextSetRGBFillColor(ctx , 1, 1 , 1 , 1);

    for (int i = 0 ; i < snowCount ; i++ )
    {
        // 保存当前绘图状态
        CGContextSaveGState(ctx);

        // 平移坐标系统
        CGContextTranslateCTM(ctx , snowPos[i].x , snowPos[i].y);
        // 旋转坐标系统
        CGContextRotateCTM(ctx , (arc4random() % 6 - 3) * M_PI / 10);
        // 控制“雪花”下掉

        snowPos[i].y += arc4random() % 8;

        if (snowPos[i].y > 320)
        {
            snowPos[i].y = 4;
        }
        // 创建、并绘制“雪花”
        CGContextAddFlower(ctx , 6 , 0 , 0 , 4 , 8);
        CGContextFillPath(ctx);

        // 恢复绘图状态
        CGContextRestoreGState(ctx);
    }
}


@end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值