簡體   English   中英

CATransform3DRotate應用於圖層不起作用

[英]CATransform3DRotate applied to layer doesnt work

您能否提出建議,為什么CATransform3DRotate在我的情況下不適用於圖層,即圖像上的藍色圖層。

在此處輸入圖片說明

我有自定義視圖,在這里繪制自然視圖,我想動畫化更改將在白色圓圈圖層內作為其蒙版的月相。 我想在這里應用3DRotation是個好主意,但是由於某種原因,即使沒有動畫也無法使用,請告訴我我做錯了什么嗎?

    func drawMoonPhase(inRect rect:CGRect, inContext context: CGContext) {

    let moonShape = UIBezierPath(ovalIn: rect)
    moonShape.lineWidth = 4.0
    UIColor.white.setStroke()
    moonShape.stroke()
    moonShape.close()

    let moonLayer = CAShapeLayer()
    moonLayer.path = moonShape.cgPath
    moonLayer.opacity = 0
    self.layer.addSublayer(moonLayer)

    let circlePath = UIBezierPath(ovalIn: rect)
    UIColor.blue.setFill()
    circlePath.fill()
    circlePath.close()

    let circleShape = CAShapeLayer()
    circleShape.path = circlePath.cgPath
    circleShape.opacity = 0

    var transform = CATransform3DIdentity
    transform.m34 = -1 / 500.0

    transform = CATransform3DRotate(transform, (CGFloat(Double.pi * 0.3)), 0, 1, 0)
    circleShape.transform = transform

    moonLayer.mask = circleShape

}

提前致謝

編輯:也許我想清除,我想要的效果如下: 在此處輸入圖片說明

轉換發生在默認情況下位於中心的圖層錨點周圍。 因此,所發生的是形狀圍繞自身旋轉,沒有可見的結果。 :)

在這種層布局中,您應該使用cos和sin數學函數來確定衛星的x和y位置。

讓我知道您是否需要更多見解,我們將竭誠為您服務。

另外,請注意,您不需要2個shapeLayers即可獲得帶有白色描邊的藍色月亮。 CAShapeLayer具有填充和筆觸屬性,因此您可以簡化代碼。

根據新信息,這是我的新答案:

我無法通過使用轉換獲得很好的效果,因此我決定手動編寫蒙版。 結果是:

/**
 Draw a mask based on the moon phase progress.

 - parameter rect: The rect where the mon will be drawn
 - parameter progress: The progress of the moon phase. This value must be between 0 and 1
 */
func moonMask(in rect: CGRect, forProgress progress: CGFloat)->CALayer {
    let path = CGMutablePath()
    let center = CGPoint(x: rect.midX, y: rect.midY)
    path.move(to: CGPoint(x: rect.midX, y: 0))

    let relativeProgress = (max(min(progress, 1), 0) - 0.5) * 2
    let radius = rect.width/2

    let tgX = rect.midX+(relativeProgress * (radius*4/3))
    path.addCurve(to: CGPoint(x: rect.midX, y: rect.maxY), control1: CGPoint(x: tgX, y: 0), control2: CGPoint(x: tgX, y: rect.maxY))
    path.addArc(center: center, radius: rect.width/2, startAngle: .pi/2, endAngle: .pi*3/2, clockwise: false)
    //path.closeSubpath()

    let mask = CAShapeLayer()
    mask.path = path
    mask.fillColor = UIColor.black.cgColor

    return mask
}

上面的函數繪制了一個可以用作moonLayer蒙版的形狀整形器。 該圖層將與您將在其中1是滿月而0是新月的函數中傳遞的進度參數有關。

您可以將所有內容放在一起以獲得所需的效果,並且可以提取路徑創建代碼來制作漂亮的動畫。

我希望這可以回答您的問題。 為了快速測試,我寫了這個操場:

import UIKit

let rect = CGRect(origin: .zero, size: CGSize(width: 200, height: 200))

let view = UIView(frame: rect)
view.backgroundColor = .black
let layer = view.layer

/**
 Draw a mask based on the moon phase progress.

 - parameter rect: The rect where the mon will be drawn
 - parameter progress: The progress of the moon phase. This value must be between 0 and 1
 */
func moonMask(in rect: CGRect, forProgress progress: CGFloat)->CALayer {
    let path = CGMutablePath()
    let center = CGPoint(x: rect.midX, y: rect.midY)
    path.move(to: CGPoint(x: rect.midX, y: 0))

    let relativeProgress = (max(min(progress, 1), 0) - 0.5) * 2
    let radius = rect.width/2

    let tgX = rect.midX+(relativeProgress * (radius*4/3))
    path.addCurve(to: CGPoint(x: rect.midX, y: rect.maxY), control1: CGPoint(x: tgX, y: 0), control2: CGPoint(x: tgX, y: rect.maxY))
    path.addArc(center: center, radius: rect.width/2, startAngle: .pi/2, endAngle: .pi*3/2, clockwise: false)
    //path.closeSubpath()

    let mask = CAShapeLayer()
    mask.path = path
    mask.fillColor = UIColor.white.cgColor

    return mask
}

let moonLayer = CAShapeLayer()
moonLayer.path = UIBezierPath(ovalIn: rect).cgPath
moonLayer.fillColor = UIColor.clear.cgColor
moonLayer.strokeColor = UIColor.white.cgColor
moonLayer.lineWidth = 2
moonLayer.shadowColor = UIColor.white.cgColor
moonLayer.shadowOpacity = 1
moonLayer.shadowRadius = 10
moonLayer.shadowPath = moonLayer.path
moonLayer.shadowOffset = .zero

layer.addSublayer(moonLayer)

let moonPhase = moonMask(in: rect, forProgress: 0.3)
moonPhase.shadowColor = UIColor.white.cgColor
moonPhase.shadowOpacity = 1
moonPhase.shadowRadius = 10
moonPhase.shadowPath = moonLayer.path
moonPhase.shadowOffset = .zero

layer.addSublayer(moonPhase)

view

在此處輸入圖片說明

暫無
暫無

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

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