圆形比例动画有点奇怪

时间:2017-05-23 13:49:17

标签: swift cabasicanimation

我正在为我的GMSMarker制作动画,以便它在几秒钟内发出一次脉冲。

func addWave()
    {
//        circleView.layer.cornerRadius = size / 2

        //Scale
        let scaleAnimation = CABasicAnimation(keyPath: "transform.scale")
        scaleAnimation.fromValue = 1
        scaleAnimation.toValue = zoom

        //Opacity
        let alphaAnimation = CABasicAnimation(keyPath: "opacity")
        alphaAnimation.toValue = 0.0

        //Corner radius
//        let cornerRadiusAnimation = CABasicAnimation(keyPath: "cornerRadius")
//        cornerRadiusAnimation.fromValue = size / 2
//        cornerRadiusAnimation.toValue = (size * zoom)/2

        //Animation Group
        let animations: [CAAnimation] = [scaleAnimation, alphaAnimation]

        let animationGroup = CAAnimationGroup()
        animationGroup.duration = duration
        animationGroup.animations = animations
        animationGroup.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
        animationGroup.repeatCount = 1
        animationGroup.fillMode = kCAFillModeForwards
        animationGroup.isRemovedOnCompletion = false
        circleView.layer.add(animationGroup, forKey: "group")
    }

结果如下:

enter image description here enter image description here

如果我取消注释Corner radius部分,它看起来像这样:

enter image description here

所以我需要一个建议。

2 个答案:

答案 0 :(得分:5)

根据我的观察,我认为它必定是你的CAShapeLayer错误路径的问题因此掩盖了圆圈。

我刚刚写了一个雷达动画,我希望它可以帮到你。

    let scaleAnimation = CABasicAnimation(keyPath: "transform.scale")
    scaleAnimation.fromValue = 0
    scaleAnimation.toValue = 1

    let alphaAnimation = CABasicAnimation(keyPath: "opacity")
    alphaAnimation.fromValue = 1
    alphaAnimation.toValue = 0

    let animations = CAAnimationGroup()
    animations.duration = 0.8
    animations.repeatCount = Float.infinity
    animations.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
    animations.animations = [scaleAnimation, alphaAnimation]

    circleView.layer.add(animations, forKey: "animations")

我做的是,我使用了两个CAShapeLayer(一个是橙色标记,另一个是标记背面的rader层)。动画应用于雷达层。

    radarLayer = CAShapeLayer()
    radarLayer.frame = CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height);
    radarLayer.path = UIBezierPath(rect: radarLayer.frame).cgPath
    radarLayer.fillColor = UIColor.orange.cgColor
    radarLayer.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height/2)
    radarLayer.cornerRadius = radarLayer.frame.size.width/2
    radarLayer.masksToBounds = true
    radarLayer.opacity = 0
    self.layer.addSublayer(radarLayer)

    circleLayer = CAShapeLayer()
    circleLayer.frame = CGRect(x: 0, y: 0, width: 16, height: 16);
    circleLayer.path = UIBezierPath(rect: circleLayer.frame).cgPath
    circleLayer.fillColor = UIColor.orange.cgColor
    circleLayer.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height/2)
    circleLayer.cornerRadius = circleLayer.frame.size.width/2
    circleLayer.masksToBounds = true
    self.layer.addSublayer(circleLayer)

PS。我是Swift的新手,如果我在某处错了,请启发我:)

示例:http://i.imgur.com/v2jFWgw.jpg

答案 1 :(得分:0)

以下摘自Google关于Markers文档的摘录:

无论其实际值如何,该视图的行为就像 clipsToBounds设置为YES 一样。您可以应用在边界之外起作用的变换,但是绘制的对象必须在对象的边界内。所有转换/移位都受到监视和应用。简而言之:子视图必须包含在视图中。

至少对于我来说,其结果就是问题中提到的行为:方形动画。我想在动画末尾添加到标记内的图像大于容器,因此一旦添加到标记,它就会被裁剪到其边界。

以下是我所做的:

public var pulseImageView: UIImageView = {
    let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
    imageView.image = PaletteElements.pulseLocation.value
    imageView.contentMode = .center

    let pulseAnimation = CABasicAnimation(keyPath: "transform.scale.xy")
    pulseAnimation.repeatCount = Float.infinity
    pulseAnimation.fromValue = 0
    pulseAnimation.toValue = 2.0
    pulseAnimation.isRemovedOnCompletion = false

    let fadeOutAnimation = CABasicAnimation(keyPath: "opacity")
    fadeOutAnimation.duration = 2.5
    fadeOutAnimation.fromValue = 1.0
    fadeOutAnimation.toValue = 0
    fadeOutAnimation.repeatCount = Float.infinity

    let animationGroup = CAAnimationGroup()
    animationGroup.duration = 2.5
    animationGroup.animations = [pulseAnimation, fadeOutAnimation]
    animationGroup.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut)
    animationGroup.repeatCount = .greatestFiniteMagnitude
    animationGroup.fillMode = CAMediaTimingFillMode.forwards
    animationGroup.isRemovedOnCompletion = false
    imageView.layer.add(animationGroup, forKey: "pulse")

    return imageView
}()

我在助手类中定义了一个var,因此我可以在需要时检索图像。我的原始图像(脉冲图像)为116x116,因此我将contentView = .center创建为300x300的imageView,因此小图像位于中心且未拉伸。我之所以选择300x300,是因为我的动画按比例放大了脉冲图像,直到其原始值(116x2)的2倍,所以我为整个动画的执行留出了空间。

最后,我将其添加为地图的标记:

let pulseMarker = GMSMarker(position: userLocation.coordinate)
pulseMarker.iconView = pulseImageView
pulseMarker.groundAnchor = CGPoint(x: 0.5, y: 0.5)
pulseMarker.map = googleMapView

希望它可以提供帮助。