Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
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.4k
サーバーレスで構築するBreaking Down LIVE
touyu
2
110
スタートアップにおける TiDB Serverless の導入
touyu
1
53
Other Decks in Programming
See All in Programming
属人化した知識を、 AIが辿れる地図にする
pkshadeck
PRO
1
140
そこに3びきプロダクトがいるじゃろう——生成AI時代における“価値が届かない理由”の構造
kosuket
0
410
今さら聞けない .NET CLI
htkym
0
180
PHP初心者セッション2026 〜生成AIでは見えない裏側を知る:今だからLAMPを通して仕組みを学ぶ〜
kashioka
0
830
「人を評価する AI」の設計と実装
ryoyanara
0
160
霧の中の代数的エフェクト
funnyycat
1
460
仕様駆動開発の消費期限
watany
8
4.4k
FDEが実現するAI駆動経営の現在地
gonta
2
260
freee が目指す データ マネジメント戦略 AI-Ready 時代を支える 攻めのガバナンスとは
freee
PRO
0
260
Claude Code全社展開のためにやったことn選~プラグイン302個・コミッター271人を支えるために~
kenchan
4
1.3k
メールのエイリアス機能を履き違えない
isshinfunada
0
220
Foundation Models frameworkで画像分析
ryodeveloper
1
540
Featured
See All Featured
Ruling the World: When Life Gets Gamed
codingconduct
0
290
エンジニアに許された特別な時間の終わり
watany
108
250k
Marketing to machines
jonoalderson
1
5.6k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
330
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
280
A Tale of Four Properties
chriscoyier
163
24k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.2k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
260
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
330
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.1k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.2k
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ΛҠಈͤͯ͞૬ࡴ
·ͱΊ
ͪΐͬͱ͍͚͜͠Ͳ ϦονͳΞχϝʔγϣϯ͕ ࡞Εָ͍ͯ͠
͋Γ͕ͱ͏͍͟͝·ͨ͠