Skip to content

Instantly share code, notes, and snippets.

@ivanseidel
Last active May 7, 2017 03:05
Show Gist options
  • Save ivanseidel/47ecd5e4874b9707fca8135966797618 to your computer and use it in GitHub Desktop.
Save ivanseidel/47ecd5e4874b9707fca8135966797618 to your computer and use it in GitHub Desktop.
TDC Florianopolis 2017 - Demos
import UIKit
import XCPlayground
import CoreGraphics
import PlaygroundSupport
/*
* Demo
*/
func applyPerspective(_ view: UIView, distance: CGFloat) {
view.layer.transform.m34 = 1.0 / distance
}
let root = initPlayground(w: 400, h: 400)
root.backgroundColor = UIColor.white
let front = UIView(frame: CGRect(x: 100, y: 100, width: 200, height: 200))
front.layer.isDoubleSided = false
front.backgroundColor = cuteColor()
let back = UIView(frame: CGRect(x: 100, y: 100, width: 200, height: 200))
back.layer.isDoubleSided = false
back.layer.transform =
CATransform3DRotate(front.layer.transform, -CGFloat.pi, 0, 1, 0)
back.backgroundColor = cuteColor()
applyPerspective(front, distance: 500)
applyPerspective(back, distance: 500)
root.addSubview(front)
root.addSubview(back)
Timer.schedule(repeatInterval: 2.0) { timer in
UIView.animate(withDuration: 1.0, animations: {
back.layer.transform =
CATransform3DRotate(back.layer.transform, CGFloat.pi, 0, 1, 0)
front.layer.transform =
CATransform3DRotate(front.layer.transform, CGFloat.pi, 0, 1, 0)
//frontTransform.m34 = 1.0 / -500.0;
//backTransform.m34 = 1.0 / -500.0;
})
}

Going Raw with Animations

Conteudo dos DEMOS da apresentação sobre Animações e iOS

Quer os Slides? Acesse aqui.

Apresentado em: TDC Florianópolis - Maio/2017

Links Uteis (Bookmarked Links)

/*
* Created by koher: https://github.com/koher/CGPointVector
*/
import CoreGraphics
extension CGPoint {
public func nearlyEqual(to point: CGPoint, epsilon: CGFloat) -> Bool {
let difference = self - point
return fabs(difference.x) < epsilon && fabs(difference.y) < epsilon
}
public var length: CGFloat {
return sqrt(squareLength)
}
public var squareLength: CGFloat {
return x * x + y * y
}
public var unit: CGPoint {
return self * (1.0 / length)
}
public var phase: CGFloat {
return atan2(y, x)
}
public func distance(from point: CGPoint) -> CGFloat {
return (self - point).length
}
public func squareDistance(from point: CGPoint) -> CGFloat {
return (self - point).squareLength
}
public func angle(from point: CGPoint) -> CGFloat {
return acos(cos(angleFrom: point))
}
public func cos(angleFrom point: CGPoint) -> CGFloat {
return fmin(fmax(self * point / sqrt(self.squareLength * point.squareLength), -1.0), 1.0)
}
}
extension CGPoint: CustomStringConvertible {
public var description: String {
return "(\(x), \(y))"
}
}
public prefix func + (value: CGPoint) -> CGPoint {
return value
}
public prefix func - (value: CGPoint) -> CGPoint {
return CGPoint(x: -value.x, y: -value.y)
}
public func + (left: CGPoint, right: CGPoint) -> CGPoint {
return CGPoint(x: left.x + right.x, y: left.y + right.y)
}
public func - (left: CGPoint, right: CGPoint) -> CGPoint {
return CGPoint(x: left.x - right.x, y: left.y - right.y)
}
public func * (left: CGPoint, right: CGPoint) -> CGFloat {
return left.x * right.x + left.y * right.y
}
public func * (left: CGPoint, right: CGFloat) -> CGPoint {
return CGPoint(x: left.x * right, y: left.y * right)
}
public func * (left: CGFloat, right: CGPoint) -> CGPoint {
return CGPoint(x: right.x * left, y: right.y * left)
}
public func / (left: CGPoint, right: CGFloat) -> CGPoint {
return CGPoint(x: left.x / right, y: left.y / right)
}
public func += (left: inout CGPoint, right: CGPoint) {
left = left + right
}
public func -= (left: inout CGPoint, right: CGPoint) {
left = left - right
}
public func *= (left: inout CGPoint, right: CGFloat) {
left = left * right
}
public func /= (left: inout CGPoint, right: CGFloat) {
left = left / right
}
import UIKit
import XCPlayground
import CoreGraphics
import PlaygroundSupport
/*
* Demo
*/
let root = initPlayground(w: 400, h: 400)
root.backgroundColor = UIColor.white
let color = UIColor(red: 0.1, green: 0.6, blue: 0.7, alpha: 1.0)
let holder = UIView(frame: CGRect(
x: 0.0,
y: 0.0,
width: Double(200),
height: Double(30)
))
holder.center = CGPoint(x: 200, y: 200)
/*
Back Circle following main circle
*/
let backCircle = UIView(frame: CGRect(
x: 0.0,
y: 0.0,
width: Double(230),
height: Double(30)
))
backCircle.backgroundColor = UIColor(red: 0.2, green: 0.8, blue: 0.4, alpha: 1.0)
backCircle.layer.cornerRadius = 15
backCircle.center = CGPoint(x: 200, y: 200)
/*
Main Circle
*/
let sq = UIView(frame: CGRect(
x: 0.0,
y: 0.0,
width: Double(30),
height: Double(30)
))
sq.backgroundColor = color
sq.layer.cornerRadius = 15
sq.center = CGPoint(x: 200, y: 15)
root.addSubview(backCircle)
root.addSubview(holder)
holder.addSubview(sq)
let sqTransform = holder.layer.transform
func rotate() {
let initialMtx = sqTransform
//holder.layer.transform = initialMtx
UIView.animate(withDuration: 0.9, animations: { () -> Void in
holder.transform = holder.transform.rotated(by: CGFloat.pi / 2)
})
}
Timer.schedule(repeatInterval: 1.0) { timer in
rotate()
}
Timer.schedule(repeatInterval: 0.015) { timer in
var transfs: CATransform3D?
transfs = holder.layer.transform
//transfs = holder.layer.presentation()?.transform
if let _transfs = transfs {
backCircle.layer.transform = _transfs
backCircle.setNeedsDisplay()
}
}
import UIKit
import Darwin
import XCPlayground
import CoreGraphics
import PlaygroundSupport
/*
* Demo
*/
func makeCircle(_ origin: CGPoint, size: CGFloat) -> UIView {
let size = CGSize(width: size, height: size)
let circle = UIView(frame: CGRect(origin: origin, size: size))
circle.layer.cornerRadius = size.width / 2
circle.backgroundColor = cuteColor()
return circle
}
let root = initPlayground(w: 400, h: 400)
root.backgroundColor = UIColor.white
let v1 = makeCircle(CGPoint(x: 100, y: 200), size: 30)
root.addSubview(v1)
let v2 = makeCircle(CGPoint(x: 300, y: 200), size: 30)
root.addSubview(v2)
let follower = makeCircle(CGPoint(x: 200, y: 100), size: 50)
root.addSubview(follower)
// Returns a Force Vector from follower to the static point
func forceFromPoint(_ pos: CGPoint, radius: CGFloat) -> CGPoint{
let force = (pos - follower.center)
if (force.length > radius) {
return CGPoint()
}
return force / radius
}
// Returns a Force Vector horizontally to the wall
func forceToTheWall(_ wall: CGFloat) -> CGPoint{
let forceToWall = (wall - follower.center.x) / wall
return CGPoint(x: forceToWall, y: 0)
}
var pointer: CGPoint = CGPoint()
var touching: Bool = false
onTouch({ touch in
print("Touch: \(touch.x), \(touch.y), \(touch.phase.rawValue)")
if (touch.phase == UITouchPhase.ended) {
touching = false
}else {
touching = true
pointer.x = touch.x
pointer.y = touch.y
}
})
var accel: CGPoint = CGPoint()
var speed: CGPoint = CGPoint()
var lastTime: CGFloat = 0.0
onUpdate({ time in
let dt = time - lastTime
lastTime = time
if (dt > 0.1) {
return
}
var totalForce = CGPoint()
totalForce += forceFromPoint(v1.center, radius: 70.0)
totalForce += forceFromPoint(v2.center, radius: 70.0)
if (touching) {
totalForce += forceFromPoint(pointer, radius: 200.0) * 3
}
accel = totalForce * 10000
speed += accel * dt
// Atrito
speed -= speed * 0.1
follower.center += speed * dt
})
import Foundation
import UIKit
import XCPlayground
import CoreGraphics
import PlaygroundSupport
/*
* Easy to use functions
* Created by Ivan Seidel
* (Dont blame me, it was made in 10minutes)
*/
/*
* Custom Root view that listens for touches
*/
public struct TouchEvent {
init(_ touch: UITouch, view: UIView) {
let location = touch.location(in: view)
self.phase = touch.phase
self.x = location.x
self.y = location.y
}
public var phase: UITouchPhase
public var x: CGFloat
public var y: CGFloat
}
class TouchListenView: UIView {
public var completion: (TouchEvent) -> Void = {_ in }
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
completion(TouchEvent(touch, view: self))
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
completion(TouchEvent(touch, view: self))
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
completion(TouchEvent(touch, view: self))
}
}
}
/*
* Stores global TouchListenView
*/
var container: TouchListenView?
/*
* On Touch handler
* (This is the FUCKING SIMPLEST WAY to listen
* for touches and create a simple Demo)
*/
public func onTouch(_ cb: @escaping (TouchEvent) -> Void = {_ in }) {
container?.completion = cb
}
/*
* Init pattern
*/
public func initPlayground(w: Double, h: Double) -> UIView {
container = TouchListenView(frame: CGRect(x: 0.0, y: 0.0, width: w, height: h))
container?.isUserInteractionEnabled = true
PlaygroundPage.current.liveView = container
guard let _container = container else {
return TouchListenView()
}
return _container
}
/*
* Timer Extension
* Source: https://gist.github.com/natecook1000/b0285b518576b22c4dc8
*/
extension Timer {
public class func schedule(delay: TimeInterval, handler: @escaping (Timer?) -> Void) -> Timer {
let fireDate = delay + CFAbsoluteTimeGetCurrent()
let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, 0, 0, 0, handler)!
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes)
return timer
}
public class func schedule(repeatInterval interval: TimeInterval, handler: @escaping (Timer?) -> Void) -> Timer {
let fireDate = interval + CFAbsoluteTimeGetCurrent()
let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, interval, 0, 0, handler)!
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes)
return timer
}
}
/*
* DisplayLink callback
*/
var onUpdateDisplayLink: (CGFloat) -> Void = {_ in }
class DisplayLinkPlayground {
public func start() {
let displayLink = CADisplayLink(target: self,
selector: #selector(step))
displayLink.add(to: .current,
forMode: .defaultRunLoopMode)
}
@objc func step(displaylink: CADisplayLink) {
onUpdateDisplayLink(CGFloat(displaylink.timestamp))
}
}
public func onUpdate(_ cb: @escaping (CGFloat) -> Void = {_ in }){
DisplayLinkPlayground().start()
onUpdateDisplayLink = cb
}
/*
* Cool Colors for demos
*/
var colors = [
UIColor(red: 0.8, green: 0.2, blue: 0.0, alpha: 1.0),
UIColor(red: 0.1, green: 0.6, blue: 0.7, alpha: 1.0),
UIColor(red: 0.8, green: 0.6, blue: 0.1, alpha: 1.0)
]
public func cuteColor() -> UIColor {
colors.insert(colors.popLast()!, at: 0)
return colors.last!
}
/*
* Debug view rendering
*/
public class UIViewDebug: UIView {
override public func draw(_ rect: CGRect) {
super.draw(rect)
print("Rendered")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment