【IOS】动画-会动的翅膀

1.新建一个View当做画布;

FlyView *flyView = [[FlyView alloc]initWithFrame:CGRectMake(0, 0, 200, 200)];

flyView.backgroundColor = [UIColor groupTableViewBackgroundColor];


2.在View上添加两个View当做左右翅膀;

UIView *leftWing;

UIView *rightWing;

leftWing  = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.frame.size.width/2.0, self.frame.size.width/2.0)];

rightWing = [[UIView alloc]initWithFrame:CGRectMake(self.frame.size.width/2.0, 0, self.frame.size.width/2.0, self.frame.size.width/2.0)];

leftWing.center  = CGPointMake(leftWing.center.x, self.frame.size.height/2.0);

rightWing.center = CGPointMake(rightWing.center.x, self.frame.size.height/2.0);

rightWing.backgroundColor = [UIColor blackColor];

leftWing.backgroundColor = [UIColor blackColor];

[self addSubview:leftWing];

[self addSubview:rightWing];


3.先绘制左边的翅膀,要改变形状,必须先画出翅膀的大致形状;

//把画好的Layer加载view的Layer上便于观看;


CGSize size = view.frame.size;

[view.layer addSublayer:[self handleWingWithSize:size isleft:isleft]];

//开始画

CAShapeLayer *shapeLayer = [CAShapeLayer layer];

[shapeLayer setStrokeColor:[[UIColor redColor] CGColor]];

[shapeLayer setLineWidth:2.0];

CGMutablePathRef path = CGPathCreateMutable();

CGFloat jd = 0;

CGFloat scaleX = size.width/600.0f;

CGFloat scaleY = size.height/600.0f;

CGAffineTransform transform = CGAffineTransformMake(scaleX*cosf(jd), scaleY*sinf(jd), scaleX*sinf(jd), scaleY*cosf(jd), 0, 0);

//从右下角开始画 我这里使用600*600的像素画的

CGPathMoveToPoint(path, &transform, 600.0f, 600.0f);

CGPathAddQuadCurveToPoint(path, &transform, 585.0f, 200.0f, 400.0f, 185.0f);

CGPathAddQuadCurveToPoint(path, &transform, 30.0f, 150.0f, 0.0f, 0.0f);

CGPathAddQuadCurveToPoint(path, &transform, 0.0f, 194.0f, 120.0f, 200.0f);

CGPathAddQuadCurveToPoint(path, &transform, 100.0f, 394.0f, 240.0f, 400.0f);

CGPathAddQuadCurveToPoint(path, &transform, 200.0f, 594.0f, 600.0f, 600.0f);//回到起点

CGPathMoveToPoint(path, &transform, 545.0f, 372.0f);

CGPathAddArc(path, &transform, 525, 372, 20, 0, 2*M_PI,  NO);//增加一个圆

CGPathCloseSubpath(path);

[shapeLayer setPath:path];

CFRelease(path);

//加上一个动画便于观看画的过程

CABasicAnimation *pathAnima = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];

pathAnima.duration = 2.0f;

pathAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

pathAnima.fromValue = [NSNumber numberWithFloat:0.0f];

pathAnima.toValue = [NSNumber numberWithFloat:1.0f];

pathAnima.fillMode = kCAFillModeForwards;

pathAnima.removedOnCompletion = NO;

[shapeLayer addAnimation:pathAnima forKey:@"strokeEndAnimation"];


4.画好后开始改变View的形状,只改变一个方法就好了;这时候也不需要画笔和填充的颜色了;

[view.layer addSublayer:[self handleWingWithSize:size isleft:isleft]];

改成view.layer.mask = [self handleWingWithSize:size isleft:isleft];


5.右边的翅膀相当于左边的镜像

改变一下算法,翻转X轴;

transform = CGAffineTransformMake(-scaleX*cosf(jd), scaleY*sinf(jd), -scaleX*sinf(jd), scaleY*cosf(jd),size.width, 0);

这样两边就都弄好了;


6.让翅膀动起来,现加一个定时器当做动画的时间轴

count = 90;//默认90,会从原大小开始运动,因为是正弦运动90度的时候是最大值;

flyTime = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(changeCodeBtn:) userInfo:nil repeats:YES];

[[NSRunLoop currentRunLoop] addTimer:flyTime forMode:NSRunLoopCommonModes];

CATransform3D doctorTran = CATransform3DIdentity;

doctorTran.m11 = sinf(2.0*M_PI*(count/360.0f));

rightWing.layer.transform = doctorTran;

leftWing.layer.transform = doctorTran;

7.这样转起来会原地转,因为默认的锚点值是(0.5,0.5);改成

rightWing.layer.anchorPoint = CGPointMake(0, 0.5);

rightWing.center = CGPointMake(rightWing.center.x - rightWing.frame.size.width/2.0f, rightWing.center.y);

leftWing.layer.anchorPoint = CGPointMake(1.0, 0.5);

leftWing.center = CGPointMake(leftWing.center.x + leftWing.frame.size.width/2.0f, leftWing.center.y);

8.不让翅膀360度转,加个范围

if (count > 360) {

count = 0;}

if (count >= 90) {

if (!flyFlag) {

count = 97;}

flyFlag = YES;}

if (count <= 0) {

if (flyFlag) {

count = -10;}

flyFlag = NO;}

if (count < 90&&count > 0) {

CATransform3D doctorTran = CATransform3DIdentity;

doctorTran.m11 = sinf(2.0*M_PI*(count/360.0f));

rightWing.layer.transform = doctorTran;

leftWing.layer.transform = doctorTran;}

if (flyFlag) {

count--;}else{

count++;}


9.在加个侧移让3D效果看起来更逼真;也可以换个背景;

CGFloat jd = -0.5*M_PI_4;

self.transform = CGAffineTransformMake(0.5*cosf(jd), 0.8*sinf(jd), 0.5*-sinf(jd), 0.8*cosf(jd), 0, 0);








最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容