簡體   English   中英

動畫 CAShapeLayer / CAGradientLayer

[英]Animating a CAShapeLayer / CAGradientLayer

這是我昨天問的一個問題的補充。 結果很完美,但我想要修改。 使用 drawRect 繪制和動畫兩個圖形。 一個背景圖和一個前景圖

下面的代碼基於上面的線程,生成一個 CABasicAnimation,它增長了深藍色的“三角形”。 我希望它不是深藍色純色,而是具有 3 個停靠點的 CAGradientLayer:紅色/綠色/藍色。

我嘗試添加一個 CAGradientLayer 來配置漸變,然后使用 addSubLayer 將漸變添加到動畫出來的 CAShapeLayer。 我在下面發布的結果沒有動畫。 顏色和形狀只是保持靜態。 漸變看起來很棒,只需要讓它動畫出來:

在此處輸入圖片說明

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)

我需要foregroundGradient 對象(帶有gradientLayer 子層!)從左到右設置動畫。

如果您從我上面的代碼中刪除漸變,並將 foregroundGradient 保留為純色,您將看到動畫。

我認為你必須在你的觀點中使用你的mask ,如下所述。

//Remove below line
view.layer.addSublayer(backgroundGray)

//Add your mask to view
view.layer.mask = backgroundGray

整個函數如下所示:

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")
}

讓我知道它是否按照您的例外工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM