Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Swift Animation
Search
Yuto Akiba
December 07, 2016
Programming
280
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Swift Animation
Yuto Akiba
December 07, 2016
More Decks by Yuto Akiba
See All by Yuto Akiba
実践 Dev Containers × Claude Code
touyu
1
1.6k
サーバーレスで構築するBreaking Down LIVE
touyu
2
120
スタートアップにおける TiDB Serverless の導入
touyu
1
58
Other Decks in Programming
See All in Programming
Vue Fes Japan の “作る側”に関わってみて
naokihaba
0
150
Kubernetes祭り #2 OP/ED
bells17
0
110
Workers Cache を知る
syumai
0
350
月間100万人のサービス刷新で、 技術選定をHonoに振り切った話
yutobara
8
6.3k
すこし踏み込む CancellationToken
htkym
2
1.7k
KiroのSpecで「五目並べ」を作ってみる
satoshi256kbyte
1
370
パーソナライズPodcastを作った話
repunit11
0
130
機械に任せるテスト、人が見るテスト ⽣成AIで引き直した、運⽤保守フェーズの線引き
dske104
0
180
JAWS-UG 東京支部が始める、JAWS-UG支部コラボ / JAWS-UG lunchtime LT Collaboration
y0hgi
0
220
ジョジョの世界をXRで再現する
mofurune
0
150
残高管理から台帳サービスへの進化
artoy
0
180
半永久的に提供し続けられるプライベートクラウドを目指して ― 利用者の認知負荷を抑えるAPI抽象化とハードウェア世代交代の基盤設計
tomokon
0
480
Featured
See All Featured
The Invisible Side of Design
smashingmag
301
52k
Fantastic passwords and where to find them - at NoRuKo
philnash
53
4k
The Pragmatic Product Professional
lauravandoore
37
7.5k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
580
Scaling GitHub
holman
464
140k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.9k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
590
A Tale of Four Properties
chriscoyier
163
24k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6.1k
The Cult of Friendly URLs
andyhume
79
7k
Transcript
Swift Animation Yuto Akiba (@akkey0222)
ࣗݾհ • ळ༿ ༞ਓ(Yuto Akiba) • @akkey0222 • ໋ཱؗେֶ ใཧֶ෦
2ճੜ • झຯΞϧόΠτͰiOSΞϓϦΛ։ൃ
ϦϦʔεதͷΞϓϦ R-Portable Librarian
Ξχϝʔγϣϯͱ͍͑ɺ
UIView.animateWithDuration UIView.animateWithDuration(1.0, animations: { })
UIView.animateWithDuration UIView.animateWithDuration(1.0, animations: { }) ͍·ͤΜʂʂ
͡Ό͋ɺͳʹΛ͏ʁ
Core Animation
ͲΜͳ͜ͱ͕Ͱ͖Δʁ
iOSͷϩοΫը໘෩ͷ จࣈͷΞχϝʔγϣϯ ϚςϦΞϧσβΠϯ෩ ϘλϯͷΞχϝʔγϣϯ 3D Ξχϝʔγϣϯ
͍ΖΜͳϦονͳ ΞχϝʔγϣϯΛ࡞ΕΔʂ
1.iOSͷϩοΫը໘෩ͷจࣈͷΞχϝʔγϣϯ 2.3D Ξχϝʔγϣϯ
iOSͷϩοΫը໘෩ͷ จࣈͷΞχϝʔγϣϯ
CALayerͱMask
+ → let blueLayer = CALayer() let blueImage = UIImage(named:
"blue") blueLayer.contents = blueImage?.CGImage let twitterMask = CALayer() let twitterImage = UIImage(named: "twitter") twitterMask.contents = twitterImage?.CGImage blueLayer.mask = twitterMask blueLayer twitterMask
CALayerΛ͏ͱ ؆୯ʹMaskͰ͖Δ
จࣈͷΞχϝʔγϣϯ ʹMaskΛར༻ʂ
slide to unlock CALayer CAGradientLayer
CALayerΛͬͯจࣈྻΛඳը // จࣈྻΛը૾ʹม let text = "slide to unlock" UIGraphicsBeginImageContextWithOptions(frame.size,
false, 0) text.drawInRect(bounds, withAttributes: textAttributes) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() // ը૾ΛCALayerʹม let maskLayer = CALayer() maskLayer.backgroundColor = UIColor.clearColor().CGColor maskLayer.frame = CGRectOffset(bounds, bounds.size.width, 0) maskLayer.contents = image.CGImage
CAGradientLayerͷੜ let gradientLayer = CAGradientLayer() // άϥσʔγϣϯͷઃఆ gradientLayer.startPoint = CGPoint(x:
0.0, y: 0.5) gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5) let colors = [UIColor(red: 0.1, green: 0.1, blue: 0.1, alpha: 1.0).CGColor, UIColor.whiteColor().CGColor, UIColor(red: 0.1, green: 0.1, blue: 0.1, alpha: 1.0).CGColor] gradientLayer.colors = colors let locations = [0.25, 0.5, 0.75] gradientLayer.locations = locations
CAGradientLayerͷΞχϝʔγϣϯ // Animationͷઃఆ let gradientAnimation = CABasicAnimation(keyPath: "locations") gradientAnimation.fromValue =
[-0.25, -0.25, 0.00] gradientAnimation.toValue = [1.00, 1.25, 1.25] gradientAnimation.duration = 2.0 gradientAnimation.repeatCount = Float.infinity gradientAnimation.removedOnCompletion = false gradientAnimation.fillMode = kCAFillModeForwards gradientLayer.addAnimation(gradientAnimation, forKey: nil)
ຊདྷͷߏͬͱෳࡶ (try! swiftͷTim Oliver͞ΜͷൃදΛࢀর)
1.iOSͷϩοΫը໘෩ͷจࣈͷΞχϝʔγϣϯ 2.3D Ξχϝʔγϣϯ
3DΞχϝʔγϣϯ
None
func tapedImageView() { var transform = CATransform3DIdentity // ԕۙײ transform.m34
= -1.0 / 500 // ֯ let angle = -15.0 / 180.0 * CGFloat(M_PI) transform = CATransform3DRotate(transform, angle, 1, 0, 0) // Ξχϝʔγϣϯͷઃఆ let animation = CABasicAnimation(keyPath: "transform") animation.toValue = NSValue(CATransform3D: transform) animation.duration = 0.2 animation.removedOnCompletion = false animation.fillMode = kCAFillModeForwards imageView.layer.addAnimation(animation, forKey: "transform") // Ξχϝʔγϣϯͷ։࢝ imageView.layer.setAnchorPoint(CGPoint(x: 0.5, y: 0) , forView: view) }
func tapedImageView() { var transform = CATransform3DIdentity // ԕۙײ transform.m34
= -1.0 / 500 // ֯ let angle = -15.0 / 180.0 * CGFloat(M_PI) transform = CATransform3DRotate(transform, angle, 1, 0, 0) // Ξχϝʔγϣϯͷઃఆ let animation = CABasicAnimation(keyPath: "transform") animation.toValue = NSValue(CATransform3D: transform) animation.duration = 0.2 animation.removedOnCompletion = false animation.fillMode = kCAFillModeForwards imageView.layer.addAnimation(animation, forKey: "transform") // Ξχϝʔγϣϯͷ։࢝ imageView.layer.setAnchorPoint(CGPoint(x: 0.5, y: 0) , forView: view) }
m34ͬͯԿʁ (ಡΈํΘ͔Βͳ͍…)
None
AppleͷυΩϡϝϯτΛ ݟΔͱ…
None
ߦྻͷΒ͍͠
ߦྻͱ࠲ඪͷม
͔͜͜Βͪΐͬͱ ֶతͳ
Ҡಈ มޙͷ࠲ඪ มલͷ࠲ඪ Ҡಈྔ xํʹtx, yํʹtyҠಈͤ͞Δ
֦େɺॖখ มޙͷ࠲ඪ มલͷ࠲ඪ ഒ xํʹsxഒ, yํʹsyഒ֦େ(ॖখ)
ճస A(x, y) α y x r rcosα rsinα
ճస A(1, 0), θ=90°ͷͱ͖ θճసͤ͞Δͱ
Ҏ্ͷ͜ͱ͔Β
ΞϑΟϯม
2࣍ݩͷͱ͖ಉ༷ʹ 3࣍ݩΛߟ͑Δͱ
ΞϑΟϯม
None
m34 = tz
m34z࣠ํͷ ҠಈྔΛࢦ͍ͯ͠ΔΒ͍͠
ҰൠతͳมͰm**Λ ૢ࡞͢Δඞཁͳ͍
func tapedImageView() { var transform = CATransform3DIdentity // ԕۙײ transform.m34
= -1.0 / 500 // ֯ let angle = -15.0 / 180.0 * CGFloat(M_PI) transform = CATransform3DRotate(transform, angle, 1, 0, 0) // Ξχϝʔγϣϯͷઃఆ let animation = CABasicAnimation(keyPath: "transform") animation.toValue = NSValue(CATransform3D: transform) animation.duration = 0.2 animation.removedOnCompletion = false animation.fillMode = kCAFillModeForwards imageView.layer.addAnimation(animation, forKey: "transform") // Ξχϝʔγϣϯͷ։࢝ imageView.layer.setAnchorPoint(CGPoint(x: 0.5, y: 0) , forView: imageView) }
func tapedImageView() { var transform = CATransform3DIdentity // ԕۙײ transform.m34
= -1.0 / 500 // ֯ let angle = -15.0 / 180.0 * CGFloat(M_PI) transform = CATransform3DRotate(transform, angle, 1, 0, 0) // Ξχϝʔγϣϯͷઃఆ let animation = CABasicAnimation(keyPath: "transform") animation.toValue = NSValue(CATransform3D: transform) animation.duration = 0.2 animation.removedOnCompletion = false animation.fillMode = kCAFillModeForwards imageView.layer.addAnimation(animation, forKey: "transform") // Ξχϝʔγϣϯͷ։࢝ imageView.layer.setAnchorPoint(CGPoint(x: 0.5, y: 0) , forView: imageView) }
extension CALayer { func setAnchorPoint(newAnchorPoint: CGPoint, forView view: UIView) {
var newPoint = CGPointMake(self.bounds.size.width * newAnchorPoint.x, self.bounds.size.height * newAnchorPoint.y) var oldPoint = CGPointMake(self.bounds.size.width * self.anchorPoint.x, self.bounds.size.height * self.anchorPoint.y) newPoint = CGPointApplyAffineTransform(newPoint, view.transform) oldPoint = CGPointApplyAffineTransform(oldPoint, view.transform) var position = self.position position.x -= oldPoint.x position.x += newPoint.x position.y -= oldPoint.y position.y += newPoint.y position.x = newPoint.x position.y = newPoint.y self.anchorPoint = newAnchorPoint self.position = position } }
AnchorPointͱ?
AnchorPoint = Ξχϝʔγϣϯͷத৺
None
func tapedImageView() { var transform = CATransform3DIdentity // ԕۙײ transform.m34
= -1.0 / 500 // ֯ let angle = -15.0 / 180.0 * CGFloat(M_PI) transform = CATransform3DRotate(transform, angle, 1, 0, 0) // Ξχϝʔγϣϯͷઃఆ let animation = CABasicAnimation(keyPath: "transform") animation.toValue = NSValue(CATransform3D: transform) animation.duration = 0.2 animation.removedOnCompletion = false animation.fillMode = kCAFillModeForwards imageView.layer.addAnimation(animation, forKey: "transform") // Ξχϝʔγϣϯͷ։࢝ imageView.layer.setAnchorPoint(CGPoint(x: 0.5, y: 0) , forView: imageView) }
(0.5, 0)
None
anchorPointͷ
imageView.layer.anchorPoint = CGPoint(x: 0.5, y: 0)
None
imageViewͷҐஔ มΘͬͯ͠·͏…
extension CALayer { func setAnchorPoint(newAnchorPoint: CGPoint, forView view: UIView) {
var newPoint = CGPointMake(self.bounds.size.width * newAnchorPoint.x, self.bounds.size.height * newAnchorPoint.y) var oldPoint = CGPointMake(self.bounds.size.width * self.anchorPoint.x, self.bounds.size.height * self.anchorPoint.y) newPoint = CGPointApplyAffineTransform(newPoint, view.transform) oldPoint = CGPointApplyAffineTransform(oldPoint, view.transform) var position = self.position position.x -= oldPoint.x position.x += newPoint.x position.y -= oldPoint.y position.y += newPoint.y position.x = newPoint.x position.y = newPoint.y self.anchorPoint = newAnchorPoint self.position = position } }
anchorPointͷҠಈʹ߹Θͤͯ positionΛҠಈͤͯ͞૬ࡴ
·ͱΊ
ͪΐͬͱ͍͚͜͠Ͳ ϦονͳΞχϝʔγϣϯ͕ ࡞Εָ͍ͯ͠
͋Γ͕ͱ͏͍͟͝·ͨ͠