Swift 3中的动画曲线 [英] Animated curve line in Swift 3
问题描述
我想画一些贝塞尔曲线,并用波浪效果为其设置动画,
I want to draw some bezier lines and I want to animate them with a wave effect,
示例
您对我该怎么做有一些想法?贝塞尔曲线是最好的方法吗? 我为此只找到了2个库,但是它们对我所需的库并不是真正有用,不幸的是,我尝试修改一个库的代码,但没有成功 https://github.com/yourtion/YXWaveView
Do you have some ideas about how I can do this ? Bezier line is it the best method to do it ? I found only 2 libs for this, but they are not really useful for what I need, I try to modify the code of one lib, unfortunately without success https://github.com/yourtion/YXWaveView
我找到了这个库 https://antiguab.github.io/bafluidview/可以完成工作,但是它是用obj-c编写的,也许您很快就知道了类似的内容
I found this lib, https://antiguab.github.io/bafluidview/ which does the work, but it written in obj-c, maybe you know something like this in swift
推荐答案
您可以使用显示链接,这是一种针对屏幕刷新率进行了优化的特殊计时器,用于更改要呈现的path
.显示链接的处理程序应计算已过去的时间,并相应地修改要渲染的路径.您可以使用CAShapeLayer
呈现路径,也可以使用自定义的UIView
子类.形状层可能更容易:
You can use a display link, a special kind of timer optimized for screen refresh rates, to change the path
that is being rendered. The handler for the display link should calculate the amount of time that has elapsed and modify the path to be rendered accordingly. You can either use a CAShapeLayer
to render the path, or you can use a custom UIView
subclass. The shape layer is probably easier:
class ViewController: UIViewController {
private weak var displayLink: CADisplayLink?
private var startTime: CFTimeInterval = 0
/// The `CAShapeLayer` that will contain the animated path
private let shapeLayer: CAShapeLayer = {
let shapeLayer = CAShapeLayer()
shapeLayer.strokeColor = UIColor.white.cgColor
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.lineWidth = 3
return shapeLayer
}()
// start the display link when the view appears
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
view.layer.addSublayer(shapeLayer)
startDisplayLink()
}
// Stop it when it disappears. Make sure to do this because the
// display link maintains strong reference to its `target` and
// we don't want strong reference cycle.
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
stopDisplayLink()
}
/// Start the display link
private func startDisplayLink() {
startTime = CACurrentMediaTime()
self.displayLink?.invalidate()
let displayLink = CADisplayLink(target: self, selector:#selector(handleDisplayLink(_:)))
displayLink.add(to: .main, forMode: .common)
self.displayLink = displayLink
}
/// Stop the display link
private func stopDisplayLink() {
displayLink?.invalidate()
}
/// Handle the display link timer.
///
/// - Parameter displayLink: The display link.
@objc func handleDisplayLink(_ displayLink: CADisplayLink) {
let elapsed = CACurrentMediaTime() - startTime
shapeLayer.path = wave(at: elapsed).cgPath
}
/// Create the wave at a given elapsed time.
///
/// You should customize this as you see fit.
///
/// - Parameter elapsed: How many seconds have elapsed.
/// - Returns: The `UIBezierPath` for a particular point of time.
private func wave(at elapsed: Double) -> UIBezierPath {
let elapsed = CGFloat(elapsed)
let centerY = view.bounds.midY
let amplitude = 50 - abs(elapsed.remainder(dividingBy: 3)) * 40
func f(_ x: CGFloat) -> CGFloat {
return sin((x + elapsed) * 4 * .pi) * amplitude + centerY
}
let path = UIBezierPath()
let steps = Int(view.bounds.width / 10)
path.move(to: CGPoint(x: 0, y: f(0)))
for step in 1 ... steps {
let x = CGFloat(step) / CGFloat(steps)
path.addLine(to: CGPoint(x: x * view.bounds.width, y: f(x)))
}
return path
}
}
唯一棘手的部分是编写一个wave
函数,该函数在特定时间产生UIBezierPath
,并随着时间的流逝而反复调用时产生期望的效果.在此示例中,我正在绘制一个正弦曲线,其中的振幅和偏移量会根据生成路径时所经过的时间而有所不同,但是您可以在渲染中做任何您想做的事情.希望这可以说明基本思想.
The only tricky part is writing a wave
function that yields a UIBezierPath
for a particular time and yields the desired effect when you call it repeatedly as time passes. In this one, I'm rendering a sine curve, where the amplitude and the offset vary based upon the time that has elapsed at the point that the path is generated, but you can do whatever you want in your rendition. Hopefully this illustrates the basic idea.
上面的代码产生:
这篇关于Swift 3中的动画曲线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!