什么是创建循环动画的正确方法吗? [英] What is the right way of creating circle animation?

查看:258
本文介绍了什么是创建循环动画的正确方法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚看到这个形象,也同样吸引了我,如何在斯威夫特创造这种类型的动画:

I just saw this image and it's interesting to me, how to create such type of animation in Swift:

在这里输入的形象描述

所以,我在圈内很多灰色的牙齿,当我设置的角度,例如45度,将0..45度以内填补这些灰色的牙齿变成蓝色。

So, I have many gray teeth in circle and when I set the angle, for example 45degree it will fill these gray teeth into blue within 0..45 degree.

您可以只解释我做的正确的方式,也可以显示不同的片段(这将是伟大的)。后来我将搜索或阅读它。

You can just explain me the right way of doing it or you can show different snippets(it would be great). And later I will search or read about it.

在此先感谢!

推荐答案

如果您只需要单个的牙齿来改变,而不是用牙齿掩码实心填充颜色,你可以使用核芯显卡,而不是核心动画(虽然核心动画一般是preferred)。因此,为了做到这一点,我们应该做以下几点:

If you only need the individual 'teeth' to change color, instead of using the teeth as masks for a solid fill, you can use Core Graphics instead of Core Animation (although Core Animation is generally preferred). So in order to do this, we should be doing the following:


  1. 子类的UIView 来插入我们的绘图code

  2. 创建路径对象的数组,包裹在 UIBezierPath

  3. 设置更新进度值定时器和 setNeedsDisplay

  4. 的drawRect:,绘制的路径和填充每个取决于进度
  5. 分配
  1. Subclass UIView to insert our drawing code
  2. Create an array of path objects, wrapped in UIBezierPath
  3. Setup a timer to update a progress value and setNeedsDisplay
  4. In drawRect:, draw the paths and assign a fill to each depending on the progress

首先,让我们定义打算在该的UIView 子类是工作中的变量。

First of all, lets define the variables we're going to be working with in this UIView subclass.

class TeethLoaderView : UIView {

    let numberOfTeeth = UInt(60) // Number of teeth to render
    let teethSize = CGSize(width:8, height:45) // The size of each individual tooth
    let animationDuration = NSTimeInterval(5.0) // The duration of the animation

    let highlightColor = UIColor(red: 29.0/255.0, green: 175.0/255.0, blue: 255.0/255.0, alpha: 1) // The color of a tooth when it's 'highlighted'
    let inactiveColor = UIColor(red: 233.0/255.0, green: 235.0/255.0, blue: 236.0/255.0, alpha: 1) // The color of a tooth when it isn't 'hightlighted'

    var progress = NSTimeInterval(0.0) // The progress of the loader
    var paths = [UIBezierPath]() // The array containing the UIBezier paths
    var displayLink = CADisplayLink() // The display link to update the progress
    var teethHighlighted = UInt(0) // Number of teeth highlighted

    ...

现在让我们添加一个函数来创建我们的路。

Now let's add a function to create our paths.

func getPaths(size:CGSize, teethCount:UInt, teethSize:CGSize, radius:CGFloat) -> [UIBezierPath] {

    let halfHeight = size.height*0.5;
    let halfWidth = size.width*0.5;
    let deltaAngle = CGFloat(2*M_PI)/CGFloat(teethCount); // The change in angle between paths

    // Create the template path of a single shape.
    let p = CGPathCreateWithRect(CGRectMake(-teethSize.width*0.5, radius, teethSize.width, teethSize.height), nil);

    var pathArray = [UIBezierPath]()
    for i in 0..<teethCount { // Copy, translate and rotate shapes around

        let translate = CGAffineTransformMakeTranslation(halfWidth, halfHeight);
        var rotate = CGAffineTransformRotate(translate, deltaAngle*CGFloat(i))
        let pathCopy = CGPathCreateCopyByTransformingPath(p, &rotate)!

        pathArray.append(UIBezierPath(CGPath: pathCopy)) // Populate the array
    }

    return pathArray
}

这是相当简单的。我们只需要创建一个路径为一个单一的'牙齿',然后复制,因为我们有多少牙齿需要,翻译和为每一个旋转的路径这个路径。

This is fairly simple. We just create a path for a single 'tooth' and then copy this path for how many teeth we need, translating and rotating the path for each one.

接下来我们要建立我们的观点。我要去一个 CADisplayLink 的定时器,使得动画在执行上的所有设备相同的速度。

Next we want to setup our view. I'm going to a CADisplayLink for the timer so that the animation performs at the same speed on all devices.

override init(frame: CGRect) {
    super.init(frame: frame)
    commonSetup()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    commonSetup()
}

private func commonSetup() {
    self.backgroundColor = UIColor.whiteColor()
    paths = getPaths(frame.size, teethCount: numberOfTeeth, teethSize: teethSize, radius: ((frame.width*0.5)-teethSize.height))

    displayLink = CADisplayLink(target: self, selector: #selector(displayLinkDidFire));
    displayLink.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes)
}

下面我们就设置背景颜色,以及设置计时器我们并初始化我们将要使用的路径。接下来我们要建立一个函数来改变视图的进展情况时, CADisplayLink 火灾。

Here we just set the background color, as well as setup our timer and initialise the paths we're going to be using. Next we want to setup a function to change the progress of the view when the CADisplayLink fires.

func displayLinkDidFire() {

    progress += displayLink.duration/animationDuration

    if (progress > 1) {
        progress -= 1
    }

    let t = teethHighlighted

    teethHighlighted = UInt(round(progress*NSTimeInterval(numberOfTeeth))) // Calculate the number of teeth to highlight

    if (t != teethHighlighted) { // Only call setNeedsDisplay if the teethHighlighted changed
        setNeedsDisplay()
    }
}

这里没有什么复杂的,我们只是更新进度和 teethHighlighted 和呼叫 setNeedsDisplay()重绘的观点,如果 teethHighlighted 改变。

Nothing complicated here, we just update the progress and teethHighlighted and call setNeedsDisplay() to redraw the view, if teethHighlighted changed.

最后,我们要画的看法。

Finally, we want to draw the view.

override func drawRect(rect: CGRect) {

    let ctx = UIGraphicsGetCurrentContext()

    CGContextScaleCTM(ctx, -1, -1) // Flip the context to the correct orientation
    CGContextTranslateCTM(ctx, -rect.size.width, -rect.size.height)

    for (index, path) in paths.enumerate() { // Draw each 'tooth'

        CGContextAddPath(ctx, path.CGPath);

        let fillColor = (UInt(index) <= teethHighlighted) ? highlightColor:inactiveColor;

        CGContextSetFillColorWithColor(ctx, fillColor.CGColor)
        CGContextFillPath(ctx)
    }
}

如果你想往下走的Core Animation路径,我适应这个code到核心动画层

If you wanted to go down the Core Animation path, I adapted this code into a Core Animation layer

在这里输入的形象描述

完整的项目: https://github.com/originaluser2/Circle-Loader

Full project: https://github.com/originaluser2/Circle-Loader

这篇关于什么是创建循环动画的正确方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆