使用CGAffineTransforms

时间:2019-01-08 16:34:38

标签: swift animation cgaffinetransform

我正在尝试为我的应用创建背景动画。我想要实现的部分目标是:

1)图像(从阵列中选择的随机颜色/形状)随机出现在视图上。 2)然后大小迅速增加(从不可见到可见)。 3)然后将在旋转的同时沿给定方向缓慢移动10秒钟。 4)然后,它将缩小到不可见的大小,并从视图中删除。

我发现的是,形状将在步骤1和2中正确显示。然后,形状将在动画/步骤3开始时跳到屏幕上的随机位置(以下代码中的transition3)。当它移动时,它的大小也会减小。然后,对于第4步,它会跳回到第1步和第2步的原始位置,然后按预期缩小屏幕。

我无法为自己的生活弄清楚这里发生的事情。我希望我没有错过令人尴尬的显而易见的事情。

在此先感谢您的帮助!

class BackgroundAnimation {

func animation(animationView: UIView) {

    let colourArray = [
    UIColor(red:0.99, green:0.80, blue:0.05, alpha:1.0),
    UIColor(red:0.06, green:0.22, blue:0.29, alpha:1.0),
    UIColor(red:0.95, green:0.18, blue:0.30, alpha:1.0),
    UIColor(red:0.35, green:0.77, blue:0.92, alpha:1.0),
    UIColor(red:0.95, green:0.61, blue:0.19, alpha:1.0)
    ]

    let imageArray = [
    "Cross",
    "Circle",
    "Halfmoon",
    "Square",
    "Triangle"
    ]

    //Animation constants
    let initialDimensions = 10
    let pathLength: CGFloat = 100
    let pathDuration = 10
    let scaleFactor: CGFloat = 5
    let scaleDuration = 1

    //Select the random image and random colour that is to be animated.
    let image = UIImage(named: imageArray[Int.random(in: 0...imageArray.count - 1)])
    let imageView = UIImageView(image: image)


    imageView.image = imageView.image?.withRenderingMode(.alwaysTemplate)
    imageView.tintColor = colourArray[Int.random(in: 0...colourArray.count - 1)]
    imageView.contentMode = .scaleAspectFit
    imageView.frame = CGRect(x: 0, y: 0, width: initialDimensions, height: initialDimensions)
    animationView.insertSubview(imageView, at: 0)

    //create a random start location and angle of direction
    let startPointX = CGFloat.random(in: 0...animationView.frame.width)
    let startPointY = CGFloat.random(in: 0...animationView.frame.height)
    let pathAngle = CGFloat.random(in: 0...(CGFloat.pi * 2))
    imageView.center = CGPoint(x: startPointX, y: startPointY)

    //Calculate the endpoint from path angle and length
    let translationX = pathLength * sin(pathAngle)
    let tanslationY = -(pathLength * cos(pathAngle))


    //Define the transitions for the aniamtion
    var transition1 = CGAffineTransform.identity
    transition1 = transition1.scaledBy(x: scaleFactor, y: scaleFactor)


    var transition2 = CGAffineTransform.identity
    transition2 = transition2.translatedBy(x: translationX, y: tanslationY)
    transition2 = transition2.rotated(by: CGFloat.random(in: CGFloat.pi * 1/4 ... CGFloat.pi * 3/4))


    var transition3 = CGAffineTransform.identity
    transition3 = transition3.scaledBy(x: 0.001, y: 0.001)




    UIView.animate(withDuration: TimeInterval(scaleDuration), delay: 0, options: .beginFromCurrentState, animations: {

        imageView.transform = transition1

    }, completion: {finished in

        UIView.animate(withDuration: TimeInterval(pathDuration), delay: 0, options: .beginFromCurrentState, animations: {

            imageView.transform = transition2

        }, completion: { finished in

            UIView.animate(withDuration: TimeInterval(scaleDuration), delay: 0, options: .beginFromCurrentState, animations: {

                imageView.transform = transition3

            }, completion: { finished in

                imageView.removeFromSuperview()

            })

        })

    })

}

}

2 个答案:

答案 0 :(得分:0)

使用imageView.center或imageView.frame.origin更改位置

imageView.frame.origin = CGPoint(x: translationX, y: tanslationY)

但是您应该计算目的地,然后将frame.origin设置为目的地

答案 1 :(得分:0)

参考Ehsan的有帮助的答复:

这已解决了移动问题,但是当我尝试在第二个动画块中应用旋转时,imageView变得越来越小。下面更新了代码:

class BackgroundAnimation {

func animation(animationView: UIView) {

    let colourArray = [
    UIColor(red:0.99, green:0.80, blue:0.05, alpha:1.0),
    UIColor(red:0.06, green:0.22, blue:0.29, alpha:1.0),
    UIColor(red:0.95, green:0.18, blue:0.30, alpha:1.0),
    UIColor(red:0.35, green:0.77, blue:0.92, alpha:1.0),
    UIColor(red:0.95, green:0.61, blue:0.19, alpha:1.0)
    ]

    let imageArray = [
    "Cross",
    "Circle",
    "Halfmoon",
    "Square",
    "Triangle"
    ]

    //Animation constants
    let initialDimensions = 10
    let pathLength: CGFloat = 100
    let pathDuration = 10
    let scaleFactor: CGFloat = 3
    let scaleDuration = 1

    //Select the random image and random colour that is to be animated.
    let image = UIImage(named: imageArray[Int.random(in: 0...imageArray.count - 1)])
    let imageView = UIImageView(image: image)


    imageView.image = imageView.image?.withRenderingMode(.alwaysTemplate)
    imageView.tintColor = colourArray[Int.random(in: 0...colourArray.count - 1)]
    imageView.contentMode = .scaleAspectFit
    imageView.frame = CGRect(x: 0, y: 0, width: initialDimensions, height: initialDimensions)
    animationView.insertSubview(imageView, at: 0)

    //create a random start location and angle of direction
    let startPointX = CGFloat.random(in: 0...animationView.frame.width * 0.9)
    let startPointY = CGFloat.random(in: 0...animationView.frame.height * 0.9)
    let pathAngle = CGFloat.random(in: 0...(CGFloat.pi * 2))
    imageView.center = CGPoint(x: startPointX, y: startPointY)

    //Calculate the endpoint from path angle and length
    let translationX = pathLength * sin(pathAngle)
    let translationY = (pathLength * cos(pathAngle))

    let endPointX = startPointX + translationX
    let endPointY = startPointY + translationY

    //Define the transitions for the aniamtion
    var transition1 = CGAffineTransform.identity
    transition1 = transition1.scaledBy(x: scaleFactor, y: scaleFactor)


    var transition2 = CGAffineTransform.identity
    transition2 = transition2.rotated(by: CGFloat.random(in: CGFloat.pi * 1/4 ... CGFloat.pi * 3/4))



    var transition3 = CGAffineTransform.identity
    transition3 = transition3.scaledBy(x: 0.001, y: 0.001)




    UIView.animate(withDuration: TimeInterval(scaleDuration), delay: 0, options: .beginFromCurrentState, animations: {

        imageView.transform = transition1

    }, completion: {finished in

        UIView.animate(withDuration: TimeInterval(pathDuration), delay: 0.5, options: [.beginFromCurrentState, .curveLinear], animations: {

            imageView.frame.origin = CGPoint(x: endPointX, y: endPointY)
            imageView.transform = transition2

        }, completion: { finished in

            UIView.animate(withDuration: TimeInterval(scaleDuration), delay: 0.5, options: .beginFromCurrentState, animations: {

                imageView.transform = transition3

            }, completion: { finished in

                imageView.removeFromSuperview()

            })

        })

    })

}

}