gpt4 book ai didi

swift - NSBezierPath 绘制方向错误

转载 作者:可可西里 更新时间:2023-11-01 00:55:08 29 4
gpt4 key购买 nike

我第一次在 macOS 应用程序中使用 NSBezierPathCAShapeLayerCABasicAnimation。我关注了this tutorial作为起点(它与 UIBezierPath 一起)。

我想,在我遇到这个奇怪的问题之前,我真的知道它是如何工作的。无论我在做什么,动画总是从底部到顶部填充容器。

我的动画层看起来像这样:

import Cocoa

class ArcLayer: CAShapeLayer {
var animationDuration: CFTimeInterval = 1.0

init(fillColor: CGColor = Constants.Colors.DARK_THEME_MAIN_DARK.cgColor, animationDuration: CFTimeInterval = 1.0) {
super.init()

self.fillColor = fillColor
self.animationDuration = animationDuration
path = arcPathPre.cgPath
}

required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

var arcPathPre: NSBezierPath {
let arcPath = NSBezierPath()
arcPath.move(to: CGPoint(x: 0.0, y: 0.0))
arcPath.line(to: CGPoint(x: 0.0, y: 1.0))
arcPath.line(to: CGPoint(x: 171.0, y: 1.0))
arcPath.line(to: CGPoint(x: 171.0, y: 0.0))
arcPath.line(to: CGPoint(x: 0.0, y: 0.0))
arcPath.close()
return arcPath
}

var arcPathStarting: NSBezierPath {
let arcPath = NSBezierPath()
arcPath.move(to: CGPoint(x: 0.0, y: 0.0))
arcPath.line(to: CGPoint(x: 0.0, y: 0.2 * 171.0))
arcPath.line(to: CGPoint(x: 171.0, y: 0.2 * 171.0))
arcPath.line(to: CGPoint(x: 171.0, y: 0.0))
arcPath.line(to: CGPoint(x: 0.0, y: 0.0))
arcPath.close()
return arcPath
}

var arcPathLow: NSBezierPath {
let arcPath = NSBezierPath()
arcPath.move(to: CGPoint(x: 0.0, y: 0.0))
arcPath.line(to: CGPoint(x: 0.0, y: 0.4 * 171.0))
arcPath.line(to: CGPoint(x: 171.0, y: 0.4 * 171.0))
arcPath.line(to: CGPoint(x: 171.0, y: 0.0))
arcPath.line(to: CGPoint(x: 0.0, y: 0.0))
arcPath.close()
return arcPath
}

var arcPathMid: NSBezierPath {
let arcPath = NSBezierPath()
arcPath.move(to: CGPoint(x: 0.0, y: 0.0))
arcPath.line(to: CGPoint(x: 0.0, y: 0.6 * 171.0))
arcPath.line(to: CGPoint(x: 171.0, y: 0.6 * 171.0))
arcPath.line(to: CGPoint(x: 171.0, y: 0.0))
arcPath.line(to: CGPoint(x: 0.0, y: 0.0))
arcPath.close()
return arcPath
}

var arcPathHigh: NSBezierPath {
let arcPath = NSBezierPath()
arcPath.move(to: CGPoint(x: 0.0, y: 0.0))
arcPath.line(to: CGPoint(x: 0.0, y: 0.8 * 171.0))
arcPath.line(to: CGPoint(x: 171.0, y: 0.8 * 171.0))
arcPath.line(to: CGPoint(x: 171.0, y: 0.0))
arcPath.line(to: CGPoint(x: 0.0, y: 0.0))
arcPath.close()
return arcPath
}

var arcPathComplete: NSBezierPath {
let arcPath = NSBezierPath()
arcPath.move(to: CGPoint(x: 0.0, y: 0.0))
arcPath.line(to: CGPoint(x: 0.0, y: 171.0))
arcPath.line(to: CGPoint(x: 171.0, y: 171.0))
arcPath.line(to: CGPoint(x: 171.0, y: 0))
arcPath.line(to: CGPoint(x: 0.0, y: 0.0))
arcPath.close()
return arcPath
}

func animate() {
let arcAnimationPre: CABasicAnimation = CABasicAnimation(keyPath: "path")
arcAnimationPre.fromValue = arcPathPre.cgPath
arcAnimationPre.toValue = arcPathStarting.cgPath
arcAnimationPre.beginTime = 0.0
arcAnimationPre.duration = animationDuration

let arcAnimationLow: CABasicAnimation = CABasicAnimation(keyPath: "path")
arcAnimationLow.fromValue = arcPathStarting.cgPath
arcAnimationLow.toValue = arcPathLow.cgPath
arcAnimationLow.beginTime = arcAnimationPre.beginTime + arcAnimationPre.duration
arcAnimationLow.duration = animationDuration

let arcAnimationMid: CABasicAnimation = CABasicAnimation(keyPath: "path")
arcAnimationMid.fromValue = arcPathLow.cgPath
arcAnimationMid.toValue = arcPathMid.cgPath
arcAnimationMid.beginTime = arcAnimationLow.beginTime + arcAnimationLow.duration
arcAnimationMid.duration = animationDuration

let arcAnimationHigh: CABasicAnimation = CABasicAnimation(keyPath: "path")
arcAnimationHigh.fromValue = arcPathMid.cgPath
arcAnimationHigh.toValue = arcPathHigh.cgPath
arcAnimationHigh.beginTime = arcAnimationMid.beginTime + arcAnimationMid.duration
arcAnimationHigh.duration = animationDuration

let arcAnimationComplete: CABasicAnimation = CABasicAnimation(keyPath: "path")
arcAnimationComplete.fromValue = arcPathHigh.cgPath
arcAnimationComplete.toValue = arcPathComplete.cgPath
arcAnimationComplete.beginTime = arcAnimationHigh.beginTime + arcAnimationHigh.duration
arcAnimationComplete.duration = animationDuration

let arcAnimationGroup: CAAnimationGroup = CAAnimationGroup()
arcAnimationGroup.animations = [arcAnimationPre, arcAnimationLow, arcAnimationMid, arcAnimationHigh, arcAnimationComplete]
arcAnimationGroup.duration = arcAnimationComplete.beginTime + arcAnimationComplete.duration
arcAnimationGroup.fillMode = kCAFillModeForwards
arcAnimationGroup.isRemovedOnCompletion = false
add(arcAnimationGroup, forKey: nil)
}
}

我在这个函数中调用它:

func drawArc() {
let arcLayer = ArcLayer(fillColor: fluidColor.cgColor, animationDuration: 0.75)
self.layer?.addSublayer(arcLayer)
arcLayer.animate()
}

View 的宽度和高度正好是 171.0。

预期行为:深色区域(填充颜色)从上到下绘制。

当前行为:深色区域(填充颜色)从底部绘制到顶部。 The dark area (fill color) comes from the bottom and goes to the top

我很确定这只是一个非常合乎逻辑的问题,但是,我真的找不到它。

我不认为这是问题所在,但这是我从 NSBezierPath 获取 CGPath 的扩展:

import Cocoa

extension NSBezierPath {

public var cgPath: CGPath {
let path = CGMutablePath()
var points = [CGPoint](repeating: .zero, count: 3)
for i in 0 ..< self.elementCount {
let type = self.element(at: i, associatedPoints: &points)
switch type {
case .moveToBezierPathElement: path.move(to: CGPoint(x: points[0].x, y: points[0].y))
case .lineToBezierPathElement: path.addLine(to: CGPoint(x: points[0].x, y: points[0].y))
case .curveToBezierPathElement: path.addCurve(to: CGPoint(x: points[0].x, y: points[0].y), control1: CGPoint(x: points[1].x, y: points[1].y), control2: CGPoint(x: points[2].x, y: points[2].y))
case .closePathBezierPathElement: path.closeSubpath()
}
}
return path
}
}

最佳答案

在我看来这可能是一个坐标问题,NS 原点在左上角,CG 原点在左下角,也许检查一下?

关于swift - NSBezierPath 绘制方向错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51487979/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com