国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > iOS > 正文

iOS動畫案例(1) 類似于qq賬號信息里的一個(gè)動畫效果

2019-10-21 18:48:48
字體:
供稿:網(wǎng)友

受人所托,做一個(gè)類似于qq賬號信息里的一個(gè)動畫,感覺挺有意思,也沒感覺有多難,就開始做了,結(jié)果才發(fā)現(xiàn)學(xué)的數(shù)學(xué)知識都還給體育老師了,研究了大半天才做出來。

 先看一下動畫效果:

ios動畫效果

用到的知識點(diǎn):

(1)三角函數(shù)
(2)CALayer
(3)CATransaction
(4)UIBezierPath
(5)CAKeyframeAnimation
(6)CAAnimationGroup

ios動畫效果

 如圖,這明顯是一段圓弧,那么要確定這段一段圓弧的位置,就得確定這段圓弧的圓心和圓心角。我規(guī)定圓心在手機(jī)屏幕的左頂點(diǎn),也就是(0,0),圓心角為60°。別問我為什么這么確定,我也是一點(diǎn)點(diǎn)嘗試的。我們先設(shè)手機(jī)屏幕的寬度為 ScreenWidth,圓弧半徑為R;那么R = ScreenWidth/cos(60°);知道了這些開始畫圓弧。

// 屏幕的寬度 CGFloat width = [UIScreen mainScreen].bounds.size.width; // 圓半徑  float r = 2 * width / sqrt(3); // 畫曲線 UIColor *color = [UIColor redColor]; [color set]; UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(0, 0) radius:r startAngle:M_PI / 2 endAngle:M_PI / 6 clockwise:NO]; path.lineWidth = 1.0; path.lineCapStyle = kCGLineCapRound; path.lineJoinStyle = kCGLineJoinRound; [path stroke];

 確定了圓心角和半徑就要確定ABCD四個(gè)點(diǎn)的坐標(biāo)了,分別作為四張圖片的圓心。圓弧SA和圓弧DE的圓心角一樣,設(shè)定為7.5°,那么弧AB、弧BC、弧CD的圓心角設(shè)定為相等,分別為(60 - 7.5 * 2)/ 3 = 15°。那么A點(diǎn)的坐標(biāo)就等于(R * sin7.5,R * cos7.5°);B,C,D點(diǎn)的坐標(biāo)一樣用三角函數(shù)求,分別為(R * sin22.5,R * cos22.5°),(R * sin37.5,R * cos37.5°),(R * sin52.5,R * cos52.5°)。ABCD其實(shí)都是一個(gè)按鈕,下面開始放按鈕。

// 放圖片 for (int i = 0; i < 4; i++) {  // 一共四個(gè)按鈕 從左到右index分別為0,1,2,3  UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];  button.frame = [self getButtonFrame:i];  button.tag = i + 1;  [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];  [button setImage:[UIImage imageNamed:[NSString stringWithFormat:@"%d",i + 1]] forState:UIControlStateNormal];  // 設(shè)置按鈕為圓  button.layer.cornerRadius = 25;  button.layer.borderColor = [UIColor greenColor].CGColor;  button.layer.masksToBounds = YES;  button.layer.borderWidth = 2.0f;  [self addSubview:button]; } // 根據(jù)Index確定按鈕的坐標(biāo) - (CGRect)getButtonFrame: (int) index { float radians = M_PI * (7.5 + 15 * index) / 180; CGFloat width = [UIScreen mainScreen].bounds.size.width; float r = 2 * width / sqrt(3); CGRect frame = CGRectMake(sin(radians) * r, cos(radians) * r, 50, 50); frame.origin.x = frame.origin.x - 25; frame.origin.y = frame.origin.y - 25; return frame; }

 頭像默認(rèn)放第一個(gè)。

 self.head = [[UIImageView alloc] initWithFrame:[self getButtonFrame:0]]; self.head.image = [UIImage imageNamed:@"myHead"]; self.head.layer.borderColor = [UIColor greenColor].CGColor; self.head.layer.masksToBounds = YES; self.head.layer.cornerRadius = 25; self.head.layer.borderWidth = 2.0f; [self addSubview:self.head];

之后按鈕點(diǎn)擊之后,頭像移動到按鈕點(diǎn)擊的地方。

// 按鈕點(diǎn)擊事件- (void)buttonClick:(UIButton *)button { // 原來圖片所在按鈕的index int preIndex = [self getPreviousIndexByFrame:self.head.frame]; int buttonIndex = (int)button.tag - 1; // 點(diǎn)擊圖片所在按鈕 不做任何操作 if (preIndex == buttonIndex) {  return; } CGFloat width = [UIScreen mainScreen].bounds.size.width; float r = 2 * width / sqrt(3); //加入動畫效果 CALayer *transitionLayer = [[CALayer alloc] init]; //顯式事務(wù)默認(rèn)開啟動畫效果,kCFBooleanTrue關(guān)閉 保證begin和commit 之間的屬性修改同時(shí)進(jìn)行 transitionLayer.contents = self.head.layer.contents; transitionLayer.borderColor = [UIColor greenColor].CGColor; transitionLayer.masksToBounds = YES; transitionLayer.cornerRadius = 25; transitionLayer.borderWidth = 2.0f; transitionLayer.frame = self.head.frame; transitionLayer.backgroundColor=[UIColor blueColor].CGColor; [self.layer addSublayer:transitionLayer]; self.head.hidden = YES; UIBezierPath *movePath; //路徑曲線 貝塞爾曲線 if (buttonIndex > preIndex) {  // 向上滑 逆時(shí)針  movePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(0, 0) radius:r startAngle:[self getAnticlockwiseByIndex:preIndex] endAngle:[self getAnticlockwiseByIndex:buttonIndex] clockwise:NO];  [movePath moveToPoint:transitionLayer.position]; }else {  // 向下滑 順時(shí)針  movePath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(0, 0) radius:r startAngle:[self getClockwiseAngleByIndex:preIndex] endAngle:[self getClockwiseAngleByIndex:buttonIndex] clockwise:YES];  [movePath moveToPoint:transitionLayer.position]; } //關(guān)鍵幀動畫效果 CAKeyframeAnimation *positionAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; // 動畫軌跡 positionAnimation.path = movePath.CGPath; // 動畫完成之后是否刪除動畫效果 positionAnimation.removedOnCompletion = NO; // 設(shè)置開始的時(shí)間 positionAnimation.beginTime = CACurrentMediaTime(); CGFloat time = 0.7; if (labs(buttonIndex - preIndex) > 1) {  time = 0.4 * labs(buttonIndex - preIndex); } //動畫總時(shí)間 positionAnimation.duration = time; // 動畫的方式 淡入淡出 positionAnimation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; // 執(zhí)行完之后保存最新的狀態(tài) positionAnimation.fillMode = kCAFillModeForwards; // 動畫完成之后,是否回到原來的地方 positionAnimation.autoreverses= NO; [transitionLayer addAnimation:positionAnimation forKey:@"opacity"]; [CATransaction setCompletionBlock:^{  [NSThread sleepForTimeInterval:time];  self.head.hidden = NO;  self.head.frame = button.frame;  [transitionLayer removeFromSuperlayer]; }];}// 根據(jù)Index獲得順時(shí)針的弧度- (float)getAnticlockwiseByIndex: (NSInteger)index { return M_PI * (0.5 - (7.5 + 15 * index) / 180);}// 根據(jù)Index獲得逆時(shí)針的弧度- (float)getClockwiseAngleByIndex: (NSInteger)index { index = 3 - index; return M_PI * (30 + 7.5 + 15 * index) / 180;}

 這個(gè)動畫的難點(diǎn)其實(shí)是確定四個(gè)按鈕的坐標(biāo)以及圓弧的半徑,主要是學(xué)的數(shù)學(xué)都忘的差不多了,還好重新?lián)炱饋磉€算不難。

以上所述是小編給大家介紹的iOS動畫案例(1) 類似于qq賬號信息里的一個(gè)動畫效果,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時(shí)回復(fù)大家的。在此也非常感謝大家對VEVB武林網(wǎng)網(wǎng)站的支持!


注:相關(guān)教程知識閱讀請移步到IOS開發(fā)頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 平定县| 天镇县| 息烽县| 阿鲁科尔沁旗| 乌恰县| 甘洛县| 珠海市| 靖宇县| 灵宝市| 丹寨县| 得荣县| 济源市| 永顺县| 双流县| 怀集县| 梅河口市| 合山市| 蕉岭县| 承德县| 绿春县| 九江市| 东城区| 德庆县| 资中县| 塘沽区| 建宁县| 沧源| 常熟市| 大埔县| 赣州市| 巴彦县| 沙田区| 赫章县| 扎赉特旗| 柘城县| 长汀县| 平塘县| 安康市| 耒阳市| 墨竹工卡县| 喜德县|