近來看到QQ音樂里面有一些酷酷的禮物效果赚瘦,手癢,從網上找到一些素材枷邪,嘗試做一下,效果有點粗糙诺凡,但是還是學到了一些東西东揣,故和大家一起探討分析一下。
先上跑車效果:
然后是戰(zhàn)斗機效果:
先說說這個跑車效果怎么做腹泌。
第一步:分析
跑車圖片和輪子圖片是一個整體嘶卧,無論是放大還是移動,一定是同步的凉袱。
第二步:搭建
跑車圖片上芥吟,放置前后輪子侦铜,輪子需要滾動,這里使用序列幀動畫來無限循環(huán)播放輪子的圖片钟鸵,給用戶一種滾動的效果钉稍。
第三步:動畫
這里使用關鍵幀動畫來控制跑車的移動和大小。
我們需要注意的是跑車盡可能的在屏幕中間停留棺耍,所以要控制不同關鍵幀的動畫時間贡未。
動畫操作:
- (void)startAnimation
{
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
//大小動畫
CAKeyframeAnimation *scaleAnimation = [self scaleKeyAnimation];
//平移動畫
CAKeyframeAnimation *transAnmation = [self translationAnimation];
animationGroup.animations = @[scaleAnimation,transAnmation];
animationGroup.duration = self.animateDuration;
[self.layer addAnimation:animationGroup forKey:nil];
}
接下來是戰(zhàn)斗機的效果分析:
第一步:分析
等同于跑車的思路,戰(zhàn)斗機為整體蒙袍,平移操作即可俊卤。
第二步:搭建
戰(zhàn)斗機的五個螺旋槳需要不停地旋轉,所以這五個小部件都需要不停地做旋轉動畫害幅。
第三步:動畫
這里的動畫分為4個部分
1消恍、戰(zhàn)斗機出場動畫
2、投彈動畫
3矫限、戰(zhàn)斗機離場動畫
4哺哼、鉆石隱藏動畫
我們需要理清楚動畫的觸發(fā)時機:
1、戰(zhàn)斗機出場動畫叼风。
2取董、戰(zhàn)斗機出場動畫結束后,開始投彈動畫无宿。投彈動畫為序列幀動畫茵汰。
3、投彈動畫結束后孽鸡,戰(zhàn)斗機離場動畫與鉆石隱藏動畫同時開始蹂午。
動畫操作:
- (void)startAnimation
{
//如果正在爆炸,也就意味之前的動畫沒結束
if (self.isBooming) {
//把動畫移除了
[self.boomImageView.layer removeAnimationForKey:@"boomAnimation"];
[self.boomImageView.layer removeAnimationForKey:@"boomOpacityAnimation"];
//把爆炸視圖隱藏了
[self hideBoomImageView];
}
//不在爆炸狀態(tài)
self.isBooming = NO;
self.boomImageView.hidden = YES;
//把未完成的動畫移除掉
[self.planeImageView.layer removeAnimationForKey:@"planeAnimation"];
[self.boomImageView.layer removeAnimationForKey:@"boomOpacityAnimation"];
[self.planeShadowImageView.layer removeAnimationForKey:@"shadowAnimation"];
//構建新的動畫
CAKeyframeAnimation *transAnmation = [self planeTranslationAnimation];
CAKeyframeAnimation *shadowAnimation = [self shadowTranslationAnimation];
//配置動畫屬性
transAnmation.duration = self.showDuration;
transAnmation.delegate = self;
transAnmation.removedOnCompletion = NO;
transAnmation.fillMode = kCAFillModeForwards;
shadowAnimation.duration = self.showDuration;
shadowAnimation.delegate = self;
shadowAnimation.removedOnCompletion = NO;
shadowAnimation.fillMode = kCAFillModeForwards;
//添加動畫
[self.planeImageView.layer addAnimation:transAnmation forKey:@"planeAnimation"];
[self.planeShadowImageView.layer addAnimation:shadowAnimation forKey:@"shadowAnimation"];
}
額外的注意事項是:當我動畫未結束時彬碱,又重新開始了動畫豆胸,那么需要根據動畫的觸發(fā)時機來處理各個動畫。
該視圖很多屬性都公開了巷疼,為了保留足夠的外部定制晚胡,調用起來會稍微復雜一點,但這樣是值得的嚼沿。
調用跑車:
- (void)loadCustomCarImageView
{
//跑車位置
car = [[CarImageView alloc]initCarImageViewWithOriginCenter:CGPointMake(-240, 0)];
//跑車開始動畫的位置
car.startAnimatePoint = CGPointMake(0, 100);
//跑車結束動畫的位置
car.endAnimatePoint = CGPointMake(600, 500);
//跑車的尺寸大小
car.controlScaleArray = @[@"0.5",@"1",@"1.2"];
//跑車途徑的點
NSValue *onePoint = [NSValue valueWithCGPoint:CGPointMake(120, 150)];
NSValue *twoPoint = [NSValue valueWithCGPoint:CGPointMake(180, 210)];
NSValue *threePoint = [NSValue valueWithCGPoint:CGPointMake(240, 260)];
car.controlPointArray = @[onePoint,twoPoint,threePoint];
//移動時的幀動畫時間
car.pointTimeArray = @[@0,@0.15,@0.45,@0.7,@0.85,@1];
//尺寸的幀動畫時間
car.scaleTimeArray = @[@0,@0.15,@0.45,@1];
//整個動畫的時間
car.animateDuration = 5.0;
[self.view addSubview:car];
}
調用戰(zhàn)斗機:
- (void)loadPlaneView
{
//初始化
plane = [[PlaneView alloc]initPlaneView];
//開始位置
plane.startPoint = CGPointMake(PhoneScreen_WIDTH , 0);
//展示時的位置估盘,從右向屏幕中間飛,途徑的點
NSValue *onePoint = [NSValue valueWithCGPoint:CGPointMake(PhoneScreen_WIDTH-30, 50)];
NSValue *twoPoint = [NSValue valueWithCGPoint:CGPointMake(PhoneScreen_WIDTH/2+50, PhoneScreen_HEIGHT/2-90)];
//展示時的位置
plane.showPointArray = @[onePoint,twoPoint];
//展示時每一幀的時間骡尽,0-1之間
plane.showTimeArray = @[@0,@0.15,@0.5,@1.0];
//飛機離開時的遣妥,從屏幕中部向屏幕左側飛
NSValue *oneLeavePoint = [NSValue valueWithCGPoint:CGPointMake(PhoneScreen_WIDTH/2-150, PhoneScreen_HEIGHT/2)];
NSValue *twoLeavePoint =[NSValue valueWithCGPoint:CGPointMake(-200, PhoneScreen_HEIGHT/2+100)];
//飛機位置
plane.leavePointArray = @[oneLeavePoint,twoLeavePoint];
//每一幀的時間
plane.leaveTimeArray = @[@0,@0.5,@1.0];
//飛機的初始位置,屏幕右側
plane.startPoint = CGPointMake(PhoneScreen_WIDTH, 0);
//飛機
plane.stayPoint = CGPointMake(PhoneScreen_WIDTH/2, PhoneScreen_HEIGHT/2-70);
//飛機出場時間(從最右側到屏幕中央的時間)
plane.showDuration = 3.0;
//飛機里長時間(從屏幕中央到最左側的時間)
plane.leaveDuration = 2.0;
//爆炸的時間攀细,也是飛機在屏幕中央停留的時間
plane.boomDuration = 3.0;
[self.view addSubview:plane];
}
至此箫踩,戰(zhàn)斗機和跑車動畫都實現了~
拋磚引玉爱态,期待能讓小伙伴們有所收獲,更期待各位大神的指點和建議班套。
整個項目因為有不少圖片肢藐,所以有15M,需要的小伙伴請到這里下載項目代碼