首页 文章

动画CAShapeLayer / CAGradientLayer

提问于
浏览
2

这是我昨天问过的一个问题的补充 . 结果很完美,但我想修改一下 . Using drawRect to draw & animate two graphs. A background graph, and a foreground graph

以下代码基于上面的线程生成一个CABasicAnimation,它会生成深蓝色的“三角形” . 而不是深蓝色的纯色,我希望这是一个3站的CAGradientLayer:红色/绿色/蓝色 .

我尝试添加CAGradientLayer来配置渐变,然后使用addSubLayer将渐变添加到动画的CAShapeLayer中 . 我在下面发布的结果不是动画 . 颜色和形状保持不变 . 渐变看起来很棒,只需要它来制作动画:

enter image description here

import UIKit
import QuartzCore
import XCPlayground

let view = UIView(frame: CGRect(x: 0, y: 0, width: 521, height: 40))
view.backgroundColor = UIColor.whiteColor()
XCPlaygroundPage.currentPage.liveView = view

let maskPath = UIBezierPath()

maskPath.moveToPoint(CGPoint(x: 0, y: 30))
maskPath.addLineToPoint(CGPoint(x: 0, y: 25))
maskPath.addLineToPoint(CGPoint(x: 300, y: 10))
maskPath.addLineToPoint(CGPoint(x: 300, y: 30))
maskPath.closePath()

let maskLayer = CAShapeLayer()
maskLayer.path = maskPath.CGPath
maskLayer.fillColor = UIColor.whiteColor().CGColor

let rectToAnimateFrom = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 0, height: 40))
let rectToAnimateTo = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 97, height: 40))

let backgroundGray = CAShapeLayer()
backgroundGray.path = maskPath.CGPath
backgroundGray.fillColor = UIColor.grayColor().CGColor

let foregroundGradient = CAShapeLayer()
foregroundGradient.mask = maskLayer
foregroundGradient.backgroundColor = UIColor.clearColor().CGColor


let gradientLayer = CAGradientLayer()
gradientLayer.startPoint = CGPointMake(0, 0)
gradientLayer.endPoint = CGPointMake(1, 0)
gradientLayer.frame = maskPath.bounds

let colors = [UIColor.redColor().CGColor, UIColor.greenColor().CGColor, UIColor.blueColor().CGColor]
gradientLayer.colors = colors


foregroundGradient.addSublayer(gradientLayer)


view.layer.addSublayer(backgroundGray)
view.layer.addSublayer(foregroundGradient)


let animation = CABasicAnimation(keyPath: "path")
animation.fromValue = rectToAnimateFrom.CGPath
animation.toValue = rectToAnimateTo.CGPath
animation.duration = 2
animation.removedOnCompletion = false
animation.fillMode = kCAFillModeForwards


foregroundGradient.addAnimation(animation, forKey: nil)

I need the foregroundGradient object (with the gradientLayer sublayer!) to animate from left to right.

如果从我上面的代码中删除渐变,并将foregroundGradient保持为纯色,您将看到动画 .

1 回答

  • 2

    我认为你必须在你的视图中使用 mask ,如下所述 .

    //Remove below line
    view.layer.addSublayer(backgroundGray)
    
    //Add your mask to view
    view.layer.mask = backgroundGray
    

    the whole function looks like this:

    func getGradientView() {
        let view = UIView(frame: CGRect(x: 0, y: 50, width: 521, height: 40))
        view.backgroundColor = UIColor.grayColor()
        self.view.addSubview(view)
    
        let maskPath = UIBezierPath()
    
        maskPath.moveToPoint(CGPoint(x: 0, y: 30))
        maskPath.addLineToPoint(CGPoint(x: 0, y: 25))
        maskPath.addLineToPoint(CGPoint(x: 300, y: 10))
        maskPath.addLineToPoint(CGPoint(x: 300, y: 30))
        maskPath.closePath()
    
        let maskLayer = CAShapeLayer()
        maskLayer.path = maskPath.CGPath
        maskLayer.fillColor = UIColor.whiteColor().CGColor
    
        let rectToAnimateFrom = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 0, height: 40))
        let rectToAnimateTo = UIBezierPath(rect: CGRect(x: 0, y: 0, width: 300, height: 40))
    
        let backgroundGray = CAShapeLayer()
        backgroundGray.path = maskPath.CGPath
        backgroundGray.fillColor = UIColor.grayColor().CGColor
    
        let foregroundGradient = CAShapeLayer()
        foregroundGradient.mask = maskLayer
        foregroundGradient.backgroundColor = UIColor.clearColor().CGColor
    
    
        let gradientLayer = CAGradientLayer()
        gradientLayer.startPoint = CGPointMake(0, 0)
        gradientLayer.endPoint = CGPointMake(1, 0)
        gradientLayer.frame = maskPath.bounds
    
        let colors = [UIColor.redColor().CGColor, UIColor.greenColor().CGColor, UIColor.blueColor().CGColor]
        gradientLayer.colors = colors
    
        foregroundGradient.addSublayer(gradientLayer)
    
        //Remove below line
        //view.layer.addSublayer(backgroundGray)
    
        view.layer.addSublayer(foregroundGradient)
    
        //Add you mask to view
        view.layer.mask = backgroundGray
    
        let animation = CABasicAnimation(keyPath: "path")
        animation.fromValue = rectToAnimateFrom.CGPath
        animation.toValue = rectToAnimateTo.CGPath
        animation.duration = 1
        animation.repeatCount = 1000
        animation.removedOnCompletion = false
        animation.fillMode = kCAFillModeForwards
    
    
        maskLayer.addAnimation(animation, forKey: "fill animation")
    }
    

    如果它按照您的例外情况工作,请告诉我 .

相关问题