当前位置: > > > Swift - 实现运动轨迹动画(线条的动态绘制)

Swift - 实现运动轨迹动画(线条的动态绘制)

    我之前写过一篇文章,介绍如何让一个视图对象沿着指定的路径进行移动:Swift - 沿路径运动的动画实现(圆形、曲线、直线等路径轨迹)
    有网友问如何在对象运动的过程中,把经过的轨迹也绘制出来?这个其实只要使用 CAShapeLayer 把路径显示出来,然后对其添加个 CABasicAnimation 动画,让动画改变 strokeEnd 就可以了。

1,效果图

(1)橙色方块沿着预先设置好的路线移动(先移动两段直线,再移动一段圆弧)
(2)在方块移动的过程中,其经过的轨迹也会实时显示出来。
           

2,样例代码

import UIKit

class ViewController: UIViewController {
    
    //动画播放时间
    var duration:CFTimeInterval = 3
    
    //运动的方块
    var square:UIView!
    
    //绘制路线的图层
    var pathLayer:CAShapeLayer!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //初始化方块
        square = UIView(frame:CGRect(x:0, y:0, width:20, height:20))
        square.backgroundColor = UIColor.orange
        
        //设置运动的路线
        let centerX = view.bounds.size.width/2
        //创建用于转移坐标的Transform,这样我们不用按照实际显示做坐标计算
        let transform = CGAffineTransform(translationX: centerX, y: 50)
        let path =  CGMutablePath()
        path.move(to: CGPoint(x:0 ,y:0), transform: transform)
        path.addLine(to: CGPoint(x:0 ,y:75), transform: transform)
        path.addLine(to: CGPoint(x:75 ,y:75), transform: transform)
        path.addArc(center: CGPoint(x:0 ,y:75), radius: 75, startAngle: 0,
                    endAngle: CGFloat(1.5 * .pi), clockwise: false, transform: transform)
        
        //给方块添加移动动画
        let orbit = CAKeyframeAnimation(keyPath:"position")
        orbit.duration = duration
        orbit.path = path
        orbit.calculationMode = kCAAnimationPaced
        orbit.isRemovedOnCompletion = false
        orbit.fillMode = kCAFillModeForwards
        square.layer.add(orbit,forKey:"Move")
        
        //绘制运动轨迹
        pathLayer = CAShapeLayer()
        pathLayer.frame = self.view.bounds
        //pathLayer.isGeometryFlipped = true
        pathLayer.path = path
        pathLayer.fillColor = nil
        pathLayer.lineWidth = 1
        pathLayer.strokeColor = UIColor.black.cgColor

        //给运动轨迹添加动画
        let pathAnimation = CABasicAnimation.init(keyPath: "strokeEnd")
        pathAnimation.duration = duration
        pathAnimation.fromValue = 0
        pathAnimation.toValue = 1
        //pathAnimation.delegate = (window as! CAAnimationDelegate)
        pathLayer.add(pathAnimation , forKey: "strokeEnd")

        //将轨道添加到视图层中
        self.view.layer.addSublayer(pathLayer)
        //将方块添加到视图中
        self.view.addSubview(square)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}
评论0