Как я могу сделать цепную анимацию, используя Core Animation в Swift? - PullRequest
0 голосов
/ 18 октября 2019

Сначала я хотел бы сделать анимацию1, а затем анимацию2. Я также хотел бы повторить их навсегда.

let animation1 = CAKeyframeAnimation(keyPath: #keyPath(CALayer.position))
animation1.path = circularFirstPath.cgPath

let animation2 = CAKeyframeAnimation(keyPath: #keyPath(CALayer.position))
animation2.path = circularSecondPath.cgPath

circleView3.layer.add(animation1, forKey: nil)
circleView3.layer.add(animation2, forKey: nil)

1 Ответ

0 голосов
/ 18 октября 2019

Если вы хотите провести слой вдоль пути:

    let segmentDuration: CFTimeInterval = 2.0

    let rect = CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0)

    let path = UIBezierPath(rect: rect)

    let posAnimation = CAKeyframeAnimation(keyPath: "position")
    posAnimation.duration = segmentDuration
    posAnimation.path = path.cgPath
    posAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
    posAnimation.calculationMode = .paced
    posAnimation.repeatCount = .infinity

    anyLayer.add(posAnimation, forKey: "position")

Если вы хотите изменить положение, попробуйте что-то вроде этого:

    let segmentDuration: CFTimeInterval = 2.0

    let points = [CGPoint(x: 0, y: 0), CGPoint(x: 400.0, y: 0.0), CGPoint(x: 200.0, y: 200.0)]

    let posAnimation = CABasicAnimation(keyPath: "position")
    posAnimation.duration = segmentDuration
    posAnimation.fromValue = points[0]
    posAnimation.toValue = points[1]

    let posAnimation1 = CABasicAnimation(keyPath: "position")
    posAnimation1.beginTime = posAnimation.duration
    posAnimation1.duration = segmentDuration
    posAnimation1.fromValue = points[1]
    posAnimation1.toValue = points[2]

    let posAnimation2 = CABasicAnimation(keyPath: "position")
    posAnimation2.beginTime = posAnimation.duration + posAnimation1.duration
    posAnimation2.duration = segmentDuration
    posAnimation2.fromValue = points[2]
    posAnimation2.toValue = points[0]

    let positionChain: CAAnimationGroup = CAAnimationGroup()
    positionChain.animations = [posAnimation, posAnimation1, posAnimation2]
    positionChain.duration = posAnimation.duration + posAnimation1.duration + posAnimation2.duration
    positionChain.fillMode = CAMediaTimingFillMode.forwards
    positionChain.repeatCount = .infinity
    anySubLayer.add(positionChain, forKey: "positionChain")

Если вы хотите изменить форму основного слояпросто создайте CAShapeLayer с нужной вам формой, замаскируйте слой и запустите анимацию:

    let segmentDuration: CFTimeInterval = 2.0

    let rect = CGRect(x: 0.0, y: 0.0, width: 100.0, height: 100.0)

    let shapeLayer = CAShapeLayer()
    shapeLayer.path = UIBezierPath(rect: rect).cgPath
    shapeLayer.frame = CGRect(x: 0, y: 0, width: 10, height: 10)
    layer.mask = shapeLayer

    let paths = [UIBezierPath(rect: rect), UIBezierPath(roundedRect: rect, cornerRadius: 25), UIBezierPath(ovalIn: rect)]

    let pathAnimation = CABasicAnimation(keyPath: "path")
    pathAnimation.duration = segmentDuration
    pathAnimation.fromValue = paths[0].cgPath
    pathAnimation.toValue = paths[1].cgPath

    let pathAnimation1 = CABasicAnimation(keyPath: "path")
    pathAnimation1.beginTime = pathAnimation.duration
    pathAnimation1.duration = segmentDuration
    pathAnimation1.fromValue = paths[1].cgPath
    pathAnimation1.toValue = paths[2].cgPath

    let pathAnimation2 = CABasicAnimation(keyPath: "path")
    pathAnimation2.beginTime = pathAnimation.duration + pathAnimation1.duration
    pathAnimation2.duration = segmentDuration
    pathAnimation2.fromValue = paths[2].cgPath
    pathAnimation2.toValue = paths[0].cgPath

    let pathChain: CAAnimationGroup = CAAnimationGroup()
    pathChain.animations = [pathAnimation, pathAnimation1, pathAnimation2]
    pathChain.duration = pathAnimation.duration + pathAnimation1.duration + pathAnimation2.duration
    pathChain.fillMode = CAMediaTimingFillMode.forwards
    pathChain.repeatCount = .infinity

    shapeLayer.add(pathChain, forKey: "positionChain")
...