-
Notifications
You must be signed in to change notification settings - Fork 38
/
EllipseViewController.swift
executable file
·82 lines (67 loc) · 2.98 KB
/
EllipseViewController.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//
// EllipseViewController.swift
// ShapeAnimation
//
// Created by Zhang Yungui on 15/1/30.
// Copyright (c) 2015 github.com/rhcad. All rights reserved.
//
import SwiftGraphics
import ShapeAnimation
import SwiftUtilities
class EllipseViewController: DetailViewController {
@IBOutlet weak var rxSlider: UISlider!
@IBOutlet weak var rySlider: UISlider!
@IBOutlet weak var angleSlider: UISlider!
var animationLayer:AnimationLayer!
var ballLayer:CAShapeLayer?
override func viewDidLoad() {
super.viewDidLoad()
animationLayer = animationView.addAnimationLayer(frame:animationView.bounds,
properties:[("rx", 20), ("ry", 20), ("angle", 0)]) { (layer, ctx) -> Void in
let ellipse = self.makeEllipse(layer)
ctx.strokePath(ellipse.cgpath)
self.drawLabelText(ctx, ellipse.a, ellipse.b, ellipse.rotation)
}
animationLayer.didStart = { self.ballLayer?.removeLayer(); return }
animationLayer.didStop = { self.addBallLayer() }
radiusXChanged(rxSlider)
radiusYChanged(rySlider)
angleChanged(angleSlider)
}
@IBAction func radiusXChanged(sender: UISlider) {
animationLayer.setProperty(sender.value, key:"rx")
}
@IBAction func radiusYChanged(sender: UISlider) {
animationLayer.setProperty(sender.value, key:"ry")
}
@IBAction func angleChanged(sender: UISlider) {
animationLayer.setProperty(DegreesToRadians(CGFloat(-sender.value)), key:"angle")
}
private func makeEllipse(layer:AnimationLayer) -> Ellipse {
let rx = layer.getProperty("rx")
let ry = layer.getProperty("ry")
let angle = layer.getProperty("angle")
return Ellipse(center:self.animationView.bounds.mid,
semiMajorAxis:max(rx, ry),
semiMinorAxis:min(rx, ry),
rotation:angle + (rx < ry ? CGFloat(M_PI_2) : 0))
}
private func drawLabelText(ctx:CGContext, _ rx:CGFloat, _ ry:CGFloat, _ angle:CGFloat) {
func round1(x:CGFloat) -> CGFloat { return round(x * 10) / 10 }
let deg = round1(RadiansToDegrees(angle))
let text:NSString = "rx=\(round1(rx))\nry=\(round1(ry))\nangle=\(deg)"
let attr = [NSFontAttributeName: UIFont.systemFontOfSize(17)]
UIGraphicsPushContext(ctx)
text.drawAtPoint(CGPoint(x:10, y:10), withAttributes:attr)
UIGraphicsPopContext()
}
private func addBallLayer() {
var gradient = Gradient(colors:[(1.0,0.0,0.0), (0.1,0.0,0.0)], axial:true)
gradient.orientation = (CGPoint(x:0.3, y:-0.3), CGPoint(x:0, y:1.4))
ballLayer = animationView.addCircleLayer(center:CGPoint.zeroPoint, radius:5)
ballLayer?.apply(gradient)
let ellipse = self.makeEllipse(animationLayer)
ballLayer!.moveOnPathAnimation(ellipse.cgpath).forever()
.set(CAMediaTimingFunction(name:kCAMediaTimingFunctionLinear)).apply()
}
}