【问题标题】:animate fill color of a curve made with a bezier?用贝塞尔曲线制作曲线的动画填充颜色?
【发布时间】:2018-11-02 09:21:35
【问题描述】:

我可以在时间序列上为曲线的笔划设置动画,但是这条曲线用颜色填充,颜色不会动画,我会看到笔划移动并且填充颜色已经存在。

let shapeLayer = CAShapeLayer()
shapeLayer.fillColor =  curveFillColor!.cgColor
shapeLayer.strokeColor = curveLineColor!.cgColor
shapeLayer.lineWidth = 3.0
shapeLayer.lineJoin = CAShapeLayerLineJoin.round
shapeLayer.lineCap = CAShapeLayerLineCap.round
shapeLayer.strokeStart = 0
shapeLayer.path = path.cgPath
self.layer.addSublayer(shapeLayer)


let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.fromValue = 0
animation.toValue = 1
animation.duration = 4
shapeLayer.add(animation, forKey: "MyAnimation")

我想同时为这条路径制作动画,所以我得到了一条慢慢被颜色填充的曲线。

路径

  let path = UIBezierPath()
         var point1:CGPoint!
         var point2:CGPoint!
         //var smoothData = self.smooth(alpha: 0.1)



         for i in 0..<curvePoints.count-1
         {
                point1 =  curvePoints[i]
                point2 = curvePoints[i+1]
                point1.y=size!.height-point1.y
                point2.y=size!.height-point2.y

                if( i == 0 ) {path.move(to: point1)}

                path.addLine(to: point2)

          }

编辑: 如果我使用此代码进行动画处理,它不会使用笔划从左到右进行动画处理,只需用颜色填充即可:

   let animation = CABasicAnimation(keyPath: "fillColor")
    animation.fromValue = UIColor.white.cgColor
    animation.toValue = curveFillColor!.cgColor
    animation.duration = 4
    animation.fillMode = .forwards
    animation.isRemovedOnCompletion=false
    shapeLayer.add(animation, forKey: "fillColor")

【问题讨论】:

  • 我认为您将需要随着时间的推移更改“曲线”的形状来为填充设置动画。由于您的曲线似乎是一系列直线,假设它们从左到右映射,您可以更改路径以对其进行动画处理。
  • 调查 developer.apple.com/documentation/quartzcore/cadisplaylink 以帮助随着时间的推移制作动画。

标签: swift uibezierpath cashapelayer


【解决方案1】:

此代码将允许您随着时间的推移制作动画。在每次调用updatePathsWithAnimation 时更改贝塞尔路径。

weak var displayLink: CADisplayLink?
var startTime: CFTimeInterval!

var shape = CAShapeLayer()

func setup() {
    layer.addSublayer(shape)
    startTime = CACurrentMediaTime()
    displayLink = {
        let _displayLink = CADisplayLink(target: self, selector: #selector(handleDisplayLink(_:)))
        _displayLink.add(to: .current, forMode: .common)
        return _displayLink
    }()
    updatePathsWithAnimation(percentageComplete: 0)
}

@objc func handleDisplayLink(_ displayLink: CADisplayLink) {
    let percent = CGFloat(CACurrentMediaTime() - startTime)
    updatePathsWithAnimation(percentageComplete: percent)
    if percent > 1.0 {
        displayLink.invalidate()
    }
}

func updatePathsWithAnimation(percentageComplete: CGFloat) {
    // Animate the curve
}

因此,例如,如果贝塞尔路径由近似曲线的 50 个点组成,您的 updatePathsWithAnimation 函数将是:

func updatePathsWithAnimation(percentageComplete: CGFloat) {
    var point1 = CGPoint.zero
    var point2 = CGPoint.zero

    // Calculate the number of points to draw, assuming that
    // the points go from left to right.
    // You can also animate scale for a bar chart,
    // the arc of a circle for a pie or donut chart, etc
    // by multiplying the appropriate values by
    // percentageComplete.

    let pointTotal = percentageComplete > 0 ? round(Double(curvePoints.count) / (100.0 - Double(percentageComplete) * 100)) : 0

    // Existing drawing code, but only draws
    // the first percentageComplete % of it...
    // (might need adjusted!)

    for i in for i in 0..< (pointTotal - 1) {
            point1 =  curvePoints[i]
            point2 = curvePoints[i+1]
            point1.y=size!.height-point1.y
            point2.y=size!.height-point2.y

            if( i == 0 ) {path.move(to: point1)}

            // Close the current shape. Need to set height
            // and the original x value
            path.addLine(to: point2)
            path.addLine(to: CGPoint(point2.x, height)
            path.addLine(to: CGPoint(0.0, height)
            path.close()

      }
      // Update the shape
      shape.path = path.cgPath
}

【讨论】:

  • 这可以让您随着时间的推移制作动画,与 iOS 设备的屏幕刷新同步。例如,如果您正在绘制条形图,您可以让条形垂直动画到它们的正确位置。您在每次更新时更改贝塞尔路径的形状以对其进行动画处理。使用percentageComplete var 以某种方式计算新形状。
  • 谢谢,你能解释(编辑)它如何适合我的代码吗?我会很感激的。
  • 我已经用一个例子更新了代码。 可能需要调整。
  • 所以每次更新我都会画一条线?还是全部?我不确定我明白了
  • 看起来我每次更新都重复循环相同的点,并根据完成百分比上升,为什么循环?为什么不每次更新绘制下一个点并在数组中没有点时停止??
猜你喜欢
  • 2017-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-01
  • 1970-01-01
相关资源
最近更新 更多