加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 业界 > 正文

在 iOS 中实现谷歌灭霸彩蛋

发布时间:2019-05-17 05:39:49 所属栏目:业界 来源:potato04
导读:示例代码下载 最近上映的复仇者联盟4据说没有片尾彩蛋,不过谷歌帮我们做了。只要在谷歌搜索灭霸,在结果的右侧点击无限手套,你将化身为灭霸,其中一半的搜索结果会化为灰烬消失...那么这么酷的动画在iOS中可以实现吗?答案是肯定的。整个动画主要包含以下

第一个rotate和translate决定了最终的位置和运动轨迹,至于第二个rotate作用,只是叠加第一个rotate的值作为最终的旋转弧度,这里刚好为0也就是不旋转。那么在iOS中该如何实现相似的运动轨迹呢?可以利用UIBezierPath, CAKeyframeAnimation的属性path可以指定这个UIBezierPath为动画的运动轨迹。确定起点和实际终点作为贝塞尔曲线的起始点和终止点,那么如何确定控制点?好像可以将“预想”的终点(下图中的(0,-1))作为控制点。

在 iOS 中实现谷歌灭霸彩蛋
图6 将“预想”的终点作为控制点的贝塞尔曲线,看起来和CSS中的运动轨迹差不多

扩展问题

通过文章中描述的方式生成的贝塞尔曲线是否与CSS中的动画轨迹完全一致呢?

现在可以给视图添加动画了:

  1. let layer = CALayer() 
  2.     layer.frame = bounds 
  3.     layer.contents = image.cgImage 
  4.     self.layer.addSublayer(layer) 
  5.     let centerX = Double(layer.position.x) 
  6.     let centerY = Double(layer.position.y) 
  7.     let radian1 = Double.pi / 12 * Double.random(in: -0.5..<0.5) 
  8.     let radian2 = Double.pi / 12 * Double.random(in: -0.5..<0.5) 
  9.     let random = Double.pi * 2 * Double.random(in: -0.5..<0.5) 
  10.     let transX = 60 * cos(random) 
  11.     let transY = 30 * sin(random) 
  12.     //1:  
  13.     // x' = x*cos(rad) - y*sin(rad) 
  14.     // y' = y*cos(rad) + x*sin(rad) 
  15.     let realTransX = transX * cos(radian1) - transY * sin(radian1) 
  16.     let realTransY = transY * cos(radian1) + transX * sin(radian1) 
  17.     let realEndPoint = CGPoint(x: centerX + realTransX, y: centerY + realTransY) 
  18.     let controlPoint = CGPoint(x: centerX + transX, y: centerY + transY) 
  19.     //2: 
  20.     let movePath = UIBezierPath() 
  21.     movePath.move(to: layer.position) 
  22.     movePath.addQuadCurve(to: realEndPoint, controlPoint: controlPoint) 
  23.     let moveAnimation = CAKeyframeAnimation(keyPath: "position") 
  24.     moveAnimation.path = movePath.cgPath 
  25.     moveAnimation.calculationMode = .paced 
  26.     //3:                  
  27.     let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation") 
  28.     rotateAnimation.toValue = radian1 + radian2 
  29.     let fadeOutAnimation = CABasicAnimation(keyPath: "opacity") 
  30.     fadeOutAnimation.toValue = 0.0 
  31.     let animationGroup = CAAnimationGroup() 
  32.     animationGroup.animations = [moveAnimation, rotateAnimation, fadeOutAnimation] 
  33.     animationGroup.duration = 1 
  34.     //4: 
  35.     animationGroup.beginTime = CACurrentMediaTime() + 1.35 * Double(i) / Double(imagesCount) 
  36.     animationGroup.isRemovedOnCompletion = false 
  37.     animationGroup.fillMode = .forwards 
  38.     layer.add(animationGroup, forKey: nil) 
  • //1: 实际的偏移量旋转了radian1弧度,这个可以通过公式x' = x*cos(rad) - y*sin(rad), y' = y*cos(rad) + x*sin(rad)算出
  • //2: 创建UIBezierPath并关联到CAKeyframeAnimation中
  • //3: 两个弧度叠加作为最终的旋转弧度
  • //4: 设置CAAnimationGroup的开始时间,让每层Layer的动画延迟开始

结尾

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读