首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSBezierPath画错了方向

NSBezierPath画错了方向
EN

Stack Overflow用户
提问于 2018-07-23 22:26:52
回答 1查看 101关注 0票数 2

我第一次在NSBezierPath应用程序中使用macOS、CAShapeLayerCABasicAnimation。我以本教程作为起点(使用UIBezierPath)。

我想,直到我面对这个奇怪的问题,我才知道它是如何运作的。不管我在做什么,动画总是从底部到顶部填充容器。

我的一层动画如下所示:

代码语言:javascript
复制
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)
    }
}

我称它为这个函数:

代码语言:javascript
复制
func drawArc() {
    let arcLayer = ArcLayer(fillColor: fluidColor.cgColor, animationDuration: 0.75)
    self.layer?.addSublayer(arcLayer)
    arcLayer.animate()
}

视野的宽度和高度正好是171.0。

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

当前行为:黑暗区域(填充颜色)从底部到顶部绘制。

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

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

代码语言:javascript
复制
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
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-23 23:48:06

听起来可能是个坐标问题,NS原点是左上角,CG原点在左下角,或者检查那个?

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51487979

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档