Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CGAffineTransform 実践入門

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

CGAffineTransform 実践入門

Avatar for Elvis Shi

Elvis Shi

May 15, 2017
Tweet

More Decks by Elvis Shi

Other Decks in Programming

Transcript

  1. override init() { super.init() emplyedBy = "MAGES. 5pb. Game div"

    job = "iOS Developer" twitter = "@lovee" Qiita = "@lovee" github = "el-hoshino" additionalInfo = "HITMAN͸ΑϓϨΠ͍ͨ͠" class Speaker: Developer { } }
  2. ਺ֶλΠϜ y z 0 D 6?C 8 0 ) 5

    = 0 1 7? 0 ' 0 ' 7?
  3. ਺ֶλΠϜ y z 0 D 6?C 8 0 ) 5

    = 0 ' 7? 7? 0 ' 0 ' x 5 0 ' 0 ' ' ' 0 ' 7? ೘࢘倔ඔƂ✣Ƒź✣ ţƄŘ₍₍ ง盲ȼ盲 ว⁾⁾ţƄŘ
  4. ਺ֶλΠϜ y z 0 D 6?C 8 0 ) 5

    = 0 ' 7? 7? 0 ' 0 ' x 5 0 '   
  5. ਺ֶλΠϜ y z 0 D 6?C 8 0 ) 5

    = 0 ' 7? 7? 0 ' 0 ' x 5 0 ' C r 0 +-( 2 0 2 0 0 0 +-( 0 3 58 5
  6. ਺ֶλΠϜ y z 0 D 6?C 8 0 ) 5

    = 0 ' 7? 7? 0 ' 0 ' x 5 0 ' +-( 0 ) 0 ' )
  7. ਺ֶλΠϜ y z 0 D 6?C 8 0 ) 0

    ' ) 5 = 0 ' 7? 7? 0 ' 0 ' x 5 0 ' +-( 0 มܗઃఆ쏤쏎쏧ɿ  มܗج४఺쏕Ұ൪Լ  ௕쎻쏕ݩ쏔   DPT К   ഒ쏑쏐쏱  ճస֯౓쏕 К  
  8. ίʔσΟϯάλΠϜ มܗઃఆ쏤쏎쏧ɿ มܗج४఺쏕Ұ൪Լ ௕쎻쏕ݩ쏔 DPT К ഒ쏑쏐쏱 ճస֯౓쏕К // ϕʔεϏϡʔΛ࡞Δ

    let view = UIView(frame: CGRect(x: 0, y: 0, width: 480, height: 640)) view.backgroundColor = .white // ը૾Λදࣔ͢ΔϏϡʔΛ࡞Δ let image = #imageLiteral(resourceName: "girl.png") let imageView = UIImageView(image: image) // ը૾ϏϡʔΛઃఆ͢Δ imageView.layer.anchorPoint.y = 1 imageView.center = CGPoint(x: 240, y: 640) view.addSubview(imageView) // ը૾ϏϡʔΛมܗͤ͞Δ imageView.transform = imageView.transform.rotated(by: .pi / -12) imageView.transform = imageView.transform.scaledBy(x: 1, y: 1 / cos(.pi / -12)) 5*14transform쏸ઃఆ쎽쏅UIView쏕௚઀frame쏸ઃఆ쎿쏱쏔쏍쏕쏐쎵ɺ ୅쏵쏰쏑center쏎bounds.size쏸ઃఆ쎿쏱쎹쏎ɻ
  9. .transform.rotated(by: .pi / -3) .transform.scaledBy(x: 1, y: 1 / cos(.pi

    / -3)) .transform.scaledBy(x: 1, y: 1 / cos(.pi / -3)) .transform.rotated(by: .pi / -3)
  10. extension UIView { //... open var transform: CGAffineTransform // default

    is CGAffineTransformIdentity. animatable } ͦ΋ͦ΋ΞϑΟϯม׵ͬͯԿ"
  11. public struct CGAffineTransform { public var a: CGFloat public var

    b: CGFloat public var c: CGFloat public var d: CGFloat public var tx: CGFloat public var ty: CGFloat public init() public init(a: CGFloat, b: CGFloat, c: CGFloat, d: CGFloat, tx: CGFloat, ty: CGFloat) } ͳΔ΄ͲɺΘ͔ΒΜ! શͬવΘ͔Μͳ͍ΑʂabcdͬͯͳΜͳͷʁͳΜͰ͍͖ͳΓtxty͕ग़ͯ͘ΔΜͩΑʂ scaleͱ͔rotateͱ͔Ͳ͜ߦͬͨΜͩΑʂ͜Ε͡ΌͲ͏΍ͬͯมܗͤͯ͞Δ͔Θ͔Μ ͳ͍ΑʂΞϑΟϯม׵ͷ͜ͱ͸ੲ͔ΒԿҰͭɺ͜ΕͬΆͬͪ΋ɺΘ͔Μͳ͍ͷΑʔʂ
  12. ղઆλΠϜ 쏻쐮쏼쑌ม׵쏕࠲ඪม׵ɻ O P(x, y) x y ΞϑΟϯม׵ O P'(x,

    y) x y 5 0 ) 6 0 ( 0 ( 7 0 ( 8 0 ) 0 ( 0 ) ( ( 0 ( ) ( 0 0 CGAffineTransform.identity 0 5 6 0 7 8
  13. ղઆλΠϜ 쏻쐮쏼쑌ม׵쏕࠲ඪม׵ɻ O P(x, y) x y ΞϑΟϯม׵ 5 0

    ) 6 0 ( 0 ) 7 0 ( 8 0 ) 0 0 ) ( ) 0 ( ) 0 ) 0 CGAffineTransform(translationX: t1, y: t2) 0 5 6 0 7 8 O P'(x+t1, y+t2 ) x y t1 t2
  14. ղઆλΠϜ 쏻쐮쏼쑌ม׵쏕࠲ඪม׵ɻ O P(x, y) x y ΞϑΟϯม׵ 5 0

    ) 6 0 ( 0 ( 7 0 ( 8 0 0 ( 0 ) ( ( 0 ( ( 0 ) 0 CGAffineTransform(scaleX: s1, y: s2) 0 5 6 0 7 8 O P'(s1x, s2y) x y s1x s2y
  15. ղઆλΠϜ 쏻쐮쏼쑌ม׵쏕࠲ඪม׵ɻ O P(x, y) x y ΞϑΟϯม׵ 5 0

    7? 6 0 0 ( 7 0 8 0 7? 0 ( 0 7? ( 0 7? ( CGAffineTransform(rotationAngle: theta) 0 5 6 0 7 8 O P'(x', y') x y x' y' φ 0 ' 7? 0 ' θ 0 7? 0 7? 7? 0 7? 7? 0 7? ⃪岳梃㡑؊▁㾶⹻䛧 0 0 7? 7? 0 7? 7? 0 7? ⃪岳梃㡑؊▁㾶⹻䛧
  16. ղઆλΠϜ 쏻쐮쏼쑌ม׵쏕࠲ඪม׵ɻ O P(x, y) x y ΞϑΟϯม׵ O P'(x',

    y') x' y' 0 5 6 0 7 8 &(')#  $   % !
  17. ղઆλΠϜ 쏻쐮쏼쑌ม׵쏕࠲ඪม׵ɻ O P(x, y) x y ΞϑΟϯม׵ O P'(x',

    y') x' y' 0 5 6 0 7 8 (scaleX: 1, y: 2) (rotationAngle: .pi / 3) 5 0 ) 6 0 ( 0 ( 7 0 ( 8 0 0 ( 5 0 ( 6 0 ( /-- 0 ( 7 0 ( /-- 8 0 ( 0 ( 0 ) 0 ) 0 ) 0 0 ) + 0 ) /--
  18. ղઆλΠϜ 쏻쐮쏼쑌ม׵쏕࠲ඪม׵ɻ O P(x, y) x y ΞϑΟϯม׵ O P'(x',

    y') x' y' 0 5 6 0 7 8 (scaleX: 1, y: 2) (rotationAngle: .pi / 3) 5 0 ) 6 0 ( 0 ( 7 0 ( 8 0 0 ( 5 0 ( 6 0 ( /-- 0 ( 7 0 ( /-- 8 0 ( 0 ( 0 ( +-- 0 ) +-- 0 ) + 0 ) /-- 0 ( +-- 0 .+ 0 ) 0 )
  19. ղઆλΠϜ 쏻쐮쏼쑌ม׵쏕࠲ඪม׵ɻ O P(x, y) x y ΞϑΟϯม׵ O P'(x',

    y') x' y' 0 5 6 0 7 8 scale ͱ rotate ͷॱ൪ަ׵ͨ͠Β
 ҧ͏݁Ռʹͳͬͨ! 0 ) + 0 ) /-- 0 ( +-- 0 .+
  20. ղઆλΠϜ 쏻쐮쏼쑌ม׵쏕࠲ඪม׵ɻ 0 5 6 0 7 8 5 6

    7 8 0 ) ( ( ) ) 5 6 7 8 ( ( ) ߦྻͷֻ͚ࢉ͕࢖͑Δ ߦྻͷֻ͚ࢉ΋ަ׵ଇ͕ޮ͔ͳ͍ ※ৄ͘͠͸ https://ja.wikipedia.org/wiki/ߦྻͷ৐๏ Λ͝ΒΜ͍ͩ͘͞ɻ
  21. ղઆλΠϜ 쏻쐮쏼쑌ม׵쏕࠲ඪม׵ɻ 0 5 6 0 7 8 // false

    transform.rotated(by: .pi) == transform * CGAffineTransform(rotationAngle: .pi) // true transform.rotated(by: .pi) == CGAffineTransform(rotationAngle: .pi) * transform CGAffineTransform ͷ xxedBy(_:) ܥ໋ྩͷ ॱ൪ʹ͸ཁ஫ҙ!
  22. .transform.rotated(by: .pi / -3) .transform.scaledBy(x: 1, y: 1 / cos(.pi

    / -3)) .transform.scaledBy(x: 1, y: 1 / cos(.pi / -3)) .transform.rotated(by: .pi / -3)
  23. ίʔσΟϯάλΠϜ 쏻쐤쐺쎦쐐쑀쑌ઃఆ쏤쏎쏧ɿ Bࠨ쏑౗쎿 Cݩ쏑໭쏱 Dӈ쏑౗쎿 EDdCdB쏑쑃쐩쎦쐒 FCdDdE쏸쑄쎦쐰 let rotation: Rotation

    = .degree(15) let duration: TimeInterval = 0.5 func rotate(_ view: UIView, onGroundBy rotation: Rotation) { view.danbo.transform { $0 .reset() .scaleBy(dy: 1 / cos(rotation)) .rotate(by: rotation) .commit() } } func reset(_ view: UIView) { view.danbo.transform { $0 .reset() .commit() } } func loop() { UIView.animateKeyframes(withDuration: duration * 2, delay: 0, options: [.calculationModeLinear, .autoreverse, .repeat], animations: { UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.5, animations: { reset(imageView) }) UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5, animations: { rotate(imageView, onGroundBy: rotation) }) }, completion: nil) } func animate() { UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: { rotate(imageView, onGroundBy: -rotation) }) { (_) in loop() } } animate()