Instantly share code, notes, and snippets.
C4Framework/MenuIcons.swift
Last active Mar 16, 2016
Chapter 7.3 of the Cosmos tutorial
// Copyright © 2016 C4 | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to | |
// deal in the Software without restriction, including without limitation the | |
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | |
// sell copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: The above copyright | |
// notice and this permission notice shall be included in all copies or | |
// substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | |
// IN THE SOFTWARE. | |
import UIKit | |
public class MenuIcons : CanvasController { | |
//A dictionary to store references to functions | |
var signIcons : [String:Shape]! | |
//An array of targets for the closed state | |
var innerTargets : [Point]! | |
//An array of targets for the open state | |
var outerTargets : [Point]! | |
//Animations | |
var signIconsOut : ViewAnimation! | |
var signIconsIn : ViewAnimation! | |
var revealSignIcons : ViewAnimation! | |
var hideSignIcons : ViewAnimation! | |
public override func setup() { | |
canvas.frame = Rect(0,0,80,80) | |
canvas.backgroundColor = clear | |
createSignIcons() | |
createSignIconAnimations() | |
} | |
//MARK: - | |
//MARK: Animations | |
func createSignIconAnimations() { | |
//animates strokeEnd so the icons are revealed | |
revealSignIcons = ViewAnimation(duration: 0.5) { | |
for sign in [Shape](self.signIcons.values) { | |
sign.strokeEnd = 1.0 | |
} | |
} | |
revealSignIcons?.curve = .EaseOut | |
//animates strokeEnd so the shapes are only dots | |
hideSignIcons = ViewAnimation(duration: 0.5) { | |
for sign in [Shape](self.signIcons.values) { | |
sign.strokeEnd = 0.001 | |
} | |
} | |
hideSignIcons?.curve = .EaseOut | |
//moves icons to open position | |
signIconsOut = ViewAnimation(duration: 0.33) { | |
for i in 0..<AstrologicalSignProvider.sharedInstance.order.count { | |
let name = AstrologicalSignProvider.sharedInstance.order[i] | |
if let sign = self.signIcons[name] { | |
sign.center = self.outerTargets[i] | |
} | |
} | |
} | |
signIconsOut?.curve = .EaseOut | |
//moves icons to closed position | |
signIconsIn = ViewAnimation(duration: 0.33) { | |
for i in 0..<AstrologicalSignProvider.sharedInstance.order.count { | |
let name = AstrologicalSignProvider.sharedInstance.order[i] | |
if let sign = self.signIcons[name] { | |
sign.center = self.innerTargets[i] | |
} | |
} | |
} | |
signIconsIn?.curve = .EaseOut | |
} | |
//MARK: - | |
//MARK: Sign Icons | |
func createSignIcons() { | |
//Associate all the names of signs with the products of their methods | |
signIcons = [String:Shape]() | |
signIcons["aries"] = aries() | |
signIcons["taurus"] = taurus() | |
signIcons["gemini"] = gemini() | |
signIcons["cancer"] = cancer() | |
signIcons["leo"] = leo() | |
signIcons["virgo"] = virgo() | |
signIcons["libra"] = libra() | |
signIcons["scorpio"] = scorpio() | |
signIcons["sagittarius"] = sagittarius() | |
signIcons["capricorn"] = capricorn() | |
signIcons["aquarius"] = aquarius() | |
signIcons["pisces"] = pisces() | |
//style all the signs | |
for shape in [Shape](self.signIcons.values) { | |
shape.strokeEnd = 0.001 //in combination with the next two settings | |
shape.lineCap = .Round //strokeEnd 0.001 makes a round dot at | |
shape.lineJoin = .Round //the beginning of the shape's path | |
shape.transform = Transform.makeScale(0.64, 0.64, 1.0) | |
shape.lineWidth = 2 | |
shape.strokeColor = white | |
shape.fillColor = clear | |
} | |
positionSignIcons() | |
} | |
func positionSignIcons() { | |
innerTargets = [Point]() | |
let provider = AstrologicalSignProvider.sharedInstance | |
//inner radius for the dots in the closed state menu | |
let r = 10.5 | |
let dx = canvas.center.x | |
let dy = canvas.center.y | |
//loop through each sign in order | |
for i in 0..<provider.order.count { | |
//calculate the angle to the current sign | |
let ϴ = M_PI/6 * Double(i) | |
//grab the name of the current sign | |
let name = provider.order[i] | |
//grab the shape from our local signIcons dictionary | |
if let sign = signIcons[name] { | |
//set the center point (remember we've already adjusted the anchorPoint) | |
sign.center = Point(r * cos(ϴ) + dx, r * sin(ϴ) + dy) | |
//add the sign to the canvas | |
canvas.add(sign) | |
//reset the anchorPoint to the center of the sign's view | |
sign.anchorPoint = Point(0.5,0.5) | |
//set the actual center of the sign as the target for the closed state of the menu | |
innerTargets.append(sign.center) | |
} | |
} | |
outerTargets = [Point]() | |
for i in 0..<provider.order.count { | |
//outer radius for the signs | |
let r = 129.0 | |
//calculate the angle for the current sign | |
let ϴ = M_PI/6 * Double(i) + M_PI/12.0 | |
//append the target point to the outer array | |
outerTargets.append(Point(r * cos(ϴ) + dx, r * sin(ϴ) + dy)) | |
} | |
} | |
//MARK: - | |
//MARK: Signs | |
//These intermediate methods take the raw sign struct from the provider | |
//Then, they extract the shape and offset each to the origin point | |
//of the shape's path, this allows us to anchor the "dots" precisely | |
//for the closed state of the menu | |
func taurus() -> Shape { | |
let shape = AstrologicalSignProvider.sharedInstance.taurus().shape | |
shape.anchorPoint = Point() | |
return shape | |
} | |
func aries() -> Shape { | |
let shape = AstrologicalSignProvider.sharedInstance.aries().shape | |
shape.anchorPoint = Point(0.0777,0.536) | |
return shape | |
} | |
func gemini() -> Shape { | |
let shape = AstrologicalSignProvider.sharedInstance.gemini().shape | |
shape.anchorPoint = Point(0.996,0.0) | |
return shape | |
} | |
func cancer() -> Shape { | |
let shape = AstrologicalSignProvider.sharedInstance.cancer().shape | |
shape.anchorPoint = Point(0.0,0.275) | |
return shape | |
} | |
func leo() -> Shape { | |
let shape = AstrologicalSignProvider.sharedInstance.leo().shape | |
shape.anchorPoint = Point(0.379,0.636) | |
return shape | |
} | |
func virgo() -> Shape { | |
let shape = AstrologicalSignProvider.sharedInstance.virgo().shape | |
shape.anchorPoint = Point(0.750,0.387) | |
return shape | |
} | |
func libra() -> Shape { | |
let shape = AstrologicalSignProvider.sharedInstance.libra().shape | |
shape.anchorPoint = Point(1.00,0.559) | |
return shape | |
} | |
func pisces() -> Shape { | |
let shape = AstrologicalSignProvider.sharedInstance.pisces().shape | |
shape.anchorPoint = Point(0.099,0.004) | |
return shape | |
} | |
func aquarius() -> Shape { | |
let shape = AstrologicalSignProvider.sharedInstance.aquarius().shape | |
shape.anchorPoint = Point(0.0,0.263) | |
return shape | |
} | |
func sagittarius() -> Shape { | |
let shape = AstrologicalSignProvider.sharedInstance.sagittarius().shape | |
shape.anchorPoint = Point(1.0,0.349) | |
return shape | |
} | |
func capricorn() -> Shape { | |
let shape = AstrologicalSignProvider.sharedInstance.capricorn().shape | |
shape.anchorPoint = Point(0.288,0.663) | |
return shape | |
} | |
func scorpio() -> Shape { | |
let shape = AstrologicalSignProvider.sharedInstance.scorpio().shape | |
shape.anchorPoint = Point(0.255,0.775) | |
return shape | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment