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

CGAffineTransform 実践入門

CGAffineTransform 実践入門

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()