美文网首页iOS开发
iOS 动画十一:Shapes and Masks

iOS 动画十一:Shapes and Masks

作者: _浅墨_ | 来源:发表于2018-07-22 16:52 被阅读83次

在我们创建想要的形状之后,我们可以将这些属性设置为 stroke color, fill color 和stroke dash pattern。

我们可以对这些属性进行动画:
• path: 渐变 layer 的形状为其它样子。
• fillColor: 将 shape 的填充色改为不同的颜色。
• lineDashPhase: 在你的形状周围创建一个 marquee 或 “marching ants” 效果
• lineWidth: 增加或缩小你的线条的线条尺寸。

现在我们实现一个小例子,例子最后效果是这样的:

代码实现
avatar view

• photoLayer: avatar image layer
• circleLayer: 画圆 layer
• maskLayer: mask layer
• label: player’s name label

bounce-off animation
bounce-off animation
func searchForOpponent() {
    let avatarSize = myAvatar.frame.size
    let bounceXOffset: CGFloat = avatarSize.width/1.9
    let morphSize = CGSize(
      width: avatarSize.width * 0.85,
      height: avatarSize.height * 1.1)

    let rightBouncePoint = CGPoint(
      x: view.frame.size.width/2.0 + bounceXOffset,
      y: myAvatar.center.y)

    let leftBouncePoint = CGPoint(
      x: view.frame.size.width/2.0 - bounceXOffset,
      y: myAvatar.center.y)

    myAvatar.bounceOff(point: rightBouncePoint, morphSize: morphSize)
    opponentAvatar.bounceOff(point: leftBouncePoint, morphSize: morphSize)

    delay(seconds: 4.0, completion: foundOpponent)
  }

  func foundOpponent() {
    status.text = "Connecting..."

    opponentAvatar.image = UIImage(named: "avatar-2")
    opponentAvatar.name = "Ray"

    delay(seconds: 4.0, completion: connectedToOpponent)
  }

  func connectedToOpponent() {
    myAvatar.shouldTransitionToFinishedState = true
    opponentAvatar.shouldTransitionToFinishedState = true

    delay(seconds: 1.0, completion: completed)
  }

  func completed() {
    status.text = "Ready to play"
    UIView.animate(withDuration: 0.2) {
      self.vs.alpha = 1.0
      self.searchAgain.alpha = 1.0
    }
  }
Morphing shapes 形状渐变

当两个 avatars 相撞时,它们应该在这个完全弹性碰撞中稍微挤压一下。视图控制器将通过一个 morph size,使头像形状变得稍高和稍窄的效果,如图所示:

Morphing shapes

这样,当他们在屏幕中间相遇时,看起来头像互相挤压。

核心代码:

 func bounceOff(point: CGPoint, morphSize: CGSize) {
    let originalCenter = center

    UIView.animate(withDuration: animationDuration, delay: 0.0,
                   usingSpringWithDamping: 0.8, initialSpringVelocity: 0.0,
                   animations: {
                    self.center = point
    }, completion: { _ in
      //complete bounce to
      if self.shouldTransitionToFinishedState {
        self.animateToSquare()
      }
    })

    UIView.animate(withDuration: animationDuration,
                   delay: animationDuration,
                  usingSpringWithDamping: 0.7,
                   initialSpringVelocity: 1.0,
                   animations: {
        self.center = originalCenter
    }, completion: { _ in
      delay(seconds: 0.1) {
        if !self.isSquare {
          self.bounceOff(point: point, morphSize: morphSize)
        }
      }
    })

    let morphedFrame = (originalCenter.x > point.x) ?

      CGRect(x: 0.0, y: bounds.height - morphSize.height,
             width: morphSize.width, height: morphSize.height):

      CGRect(x: bounds.width - morphSize.width,
             y: bounds.height - morphSize.height,
             width: morphSize.width, height: morphSize.height)

    let morphAnimation = CABasicAnimation(keyPath: "path")
    morphAnimation.duration = animationDuration
    morphAnimation.toValue = UIBezierPath(ovalIn: morphedFrame).cgPath

    morphAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)

    circleLayer.add(morphAnimation, forKey: nil)
    maskLayer.add(morphAnimation, forKey: nil)
  }

demo下载

相关文章

网友评论

    本文标题:iOS 动画十一:Shapes and Masks

    本文链接:https://www.haomeiwen.com/subject/dsolmftx.html