Swift: 재생 속도를 변경할 수 있는 키프레임 애니메이션
소개
RunCat의 키 프레임 애니메이션의 핵심 부분 구현에 대해 공개.
속도가 바뀌는 키 프레임 애니메이션 (소위 파라 파라 만화 또는 프레임 촬영 애니메이션)의 구현 방법에 대한 문헌이 없어 매우 어색했다.
데모
이 데모의 녀석은 보통 NSView
의 layer
위에서 애니메이션하고 있기 때문에 간단하지만, 메뉴 바( NSStatusItem
)상에서 재생하면 실제로는 더 정교한 것이 필요하게 된다.
출처
duration
를 고정하고 부모 레이어의 speed
를 조정한다는 것이 키모
나머지는 timeOffset
와 beginTime
의 역할 파악이 중요
AnimationLayer.swiftimport Cocoa
class AnimationLayer: CALayer {
//キーフレームアニメーションをするやつ
private var keyFrameAnimation: CAKeyframeAnimation!
//何かしらの初期設定(実装によってはいらない)
public func initialize() {
self.masksToBounds = true
self.contentsScale = 2.0
}
//キーフレームアニメーションの用意
public func setSequence(_ sequence: [NSImage]) {
keyFrameAnimation = CAKeyframeAnimation(keyPath: "contents")
keyFrameAnimation.calculationMode = .discrete //パラパラ漫画形式にするために必須な設定
keyFrameAnimation.fillMode = .forwards
keyFrameAnimation.repeatCount = Float.infinity
keyFrameAnimation.autoreverses = false
keyFrameAnimation.isRemovedOnCompletion = false
keyFrameAnimation.beginTime = 0.0
keyFrameAnimation.values = sequence
keyFrameAnimation.duration = Double(sequence.count)
}
//アニメーション開始
public func startAnimate() {
if keyFrameAnimation == nil { return }
CATransaction.begin()
CATransaction.setDisableActions(true)
self.add(keyFrameAnimation, forKey: "running")
CATransaction.commit()
}
//アニメーションのスピード変更
public func updateSpeed(_ speed: Float) {
CATransaction.begin()
CATransaction.setDisableActions(true)
self.timeOffset = self.convertTime(CACurrentMediaTime(), from: nil)
self.beginTime = CACurrentMediaTime()
self.speed = speed
CATransaction.commit()
}
}
ViewController.swiftimport Cocoa
class ViewController: NSViewController {
let animationLayer = AnimationLayer()
var timer: Timer? = nil
override func viewDidLoad() {
super.viewDidLoad()
//アニメーションレイヤーを初期化して追加
self.view.wantsLayer = true
animationLayer.initialize()
self.view.layer!.addSublayer(animationLayer)
//アニメーションするためのコマ画像を用意する
var icons = [NSImage]()
for i in (1 ... 4) {
let icon = NSImage(imageLiteralResourceName: "page" + String(i))
icons.append(icon)
}
//フレームサイズと画像を設定してアニメーション開始
animationLayer.frame = NSRect(x: 40, y: 40, width: self.view.bounds.width - 80, height: self.view.bounds.height - 80)
animationLayer.setSequence(icons)
animationLayer.startAnimate()
//例として定期的にアニメーションをランダムなスピードに変更
timer = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: true) { (t) in
let speed = Float.random(in: 1 ... 5)
self.animationLayer.updateSpeed(speed)
}
}
override func viewWillDisappear() {
timer?.invalidate()
}
override var representedObject: Any? {
didSet {
}
}
}
비고
일단 이 방법을 베이스로 키프레임 애니메이션을 실시하는 것이 가능하지만, Core Animation
는 마음대로 GPU를 사용할 수 있는 경우는 사용해 버릴 것 같고, 발열 문제를 유저로부터 지적되었다. GPU를 사용하지 않고 CPU의 소모가 작은 실장 방법을 알고 싶다.
Reference
이 문제에 관하여(Swift: 재생 속도를 변경할 수 있는 키프레임 애니메이션), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Kyome/items/15eb1893c48a64900e12
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
이 데모의 녀석은 보통
NSView
의 layer
위에서 애니메이션하고 있기 때문에 간단하지만, 메뉴 바( NSStatusItem
)상에서 재생하면 실제로는 더 정교한 것이 필요하게 된다.출처
duration
를 고정하고 부모 레이어의 speed
를 조정한다는 것이 키모
나머지는 timeOffset
와 beginTime
의 역할 파악이 중요
AnimationLayer.swiftimport Cocoa
class AnimationLayer: CALayer {
//キーフレームアニメーションをするやつ
private var keyFrameAnimation: CAKeyframeAnimation!
//何かしらの初期設定(実装によってはいらない)
public func initialize() {
self.masksToBounds = true
self.contentsScale = 2.0
}
//キーフレームアニメーションの用意
public func setSequence(_ sequence: [NSImage]) {
keyFrameAnimation = CAKeyframeAnimation(keyPath: "contents")
keyFrameAnimation.calculationMode = .discrete //パラパラ漫画形式にするために必須な設定
keyFrameAnimation.fillMode = .forwards
keyFrameAnimation.repeatCount = Float.infinity
keyFrameAnimation.autoreverses = false
keyFrameAnimation.isRemovedOnCompletion = false
keyFrameAnimation.beginTime = 0.0
keyFrameAnimation.values = sequence
keyFrameAnimation.duration = Double(sequence.count)
}
//アニメーション開始
public func startAnimate() {
if keyFrameAnimation == nil { return }
CATransaction.begin()
CATransaction.setDisableActions(true)
self.add(keyFrameAnimation, forKey: "running")
CATransaction.commit()
}
//アニメーションのスピード変更
public func updateSpeed(_ speed: Float) {
CATransaction.begin()
CATransaction.setDisableActions(true)
self.timeOffset = self.convertTime(CACurrentMediaTime(), from: nil)
self.beginTime = CACurrentMediaTime()
self.speed = speed
CATransaction.commit()
}
}
ViewController.swiftimport Cocoa
class ViewController: NSViewController {
let animationLayer = AnimationLayer()
var timer: Timer? = nil
override func viewDidLoad() {
super.viewDidLoad()
//アニメーションレイヤーを初期化して追加
self.view.wantsLayer = true
animationLayer.initialize()
self.view.layer!.addSublayer(animationLayer)
//アニメーションするためのコマ画像を用意する
var icons = [NSImage]()
for i in (1 ... 4) {
let icon = NSImage(imageLiteralResourceName: "page" + String(i))
icons.append(icon)
}
//フレームサイズと画像を設定してアニメーション開始
animationLayer.frame = NSRect(x: 40, y: 40, width: self.view.bounds.width - 80, height: self.view.bounds.height - 80)
animationLayer.setSequence(icons)
animationLayer.startAnimate()
//例として定期的にアニメーションをランダムなスピードに変更
timer = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: true) { (t) in
let speed = Float.random(in: 1 ... 5)
self.animationLayer.updateSpeed(speed)
}
}
override func viewWillDisappear() {
timer?.invalidate()
}
override var representedObject: Any? {
didSet {
}
}
}
비고
일단 이 방법을 베이스로 키프레임 애니메이션을 실시하는 것이 가능하지만, Core Animation
는 마음대로 GPU를 사용할 수 있는 경우는 사용해 버릴 것 같고, 발열 문제를 유저로부터 지적되었다. GPU를 사용하지 않고 CPU의 소모가 작은 실장 방법을 알고 싶다.
Reference
이 문제에 관하여(Swift: 재생 속도를 변경할 수 있는 키프레임 애니메이션), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Kyome/items/15eb1893c48a64900e12
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
import Cocoa
class AnimationLayer: CALayer {
//キーフレームアニメーションをするやつ
private var keyFrameAnimation: CAKeyframeAnimation!
//何かしらの初期設定(実装によってはいらない)
public func initialize() {
self.masksToBounds = true
self.contentsScale = 2.0
}
//キーフレームアニメーションの用意
public func setSequence(_ sequence: [NSImage]) {
keyFrameAnimation = CAKeyframeAnimation(keyPath: "contents")
keyFrameAnimation.calculationMode = .discrete //パラパラ漫画形式にするために必須な設定
keyFrameAnimation.fillMode = .forwards
keyFrameAnimation.repeatCount = Float.infinity
keyFrameAnimation.autoreverses = false
keyFrameAnimation.isRemovedOnCompletion = false
keyFrameAnimation.beginTime = 0.0
keyFrameAnimation.values = sequence
keyFrameAnimation.duration = Double(sequence.count)
}
//アニメーション開始
public func startAnimate() {
if keyFrameAnimation == nil { return }
CATransaction.begin()
CATransaction.setDisableActions(true)
self.add(keyFrameAnimation, forKey: "running")
CATransaction.commit()
}
//アニメーションのスピード変更
public func updateSpeed(_ speed: Float) {
CATransaction.begin()
CATransaction.setDisableActions(true)
self.timeOffset = self.convertTime(CACurrentMediaTime(), from: nil)
self.beginTime = CACurrentMediaTime()
self.speed = speed
CATransaction.commit()
}
}
import Cocoa
class ViewController: NSViewController {
let animationLayer = AnimationLayer()
var timer: Timer? = nil
override func viewDidLoad() {
super.viewDidLoad()
//アニメーションレイヤーを初期化して追加
self.view.wantsLayer = true
animationLayer.initialize()
self.view.layer!.addSublayer(animationLayer)
//アニメーションするためのコマ画像を用意する
var icons = [NSImage]()
for i in (1 ... 4) {
let icon = NSImage(imageLiteralResourceName: "page" + String(i))
icons.append(icon)
}
//フレームサイズと画像を設定してアニメーション開始
animationLayer.frame = NSRect(x: 40, y: 40, width: self.view.bounds.width - 80, height: self.view.bounds.height - 80)
animationLayer.setSequence(icons)
animationLayer.startAnimate()
//例として定期的にアニメーションをランダムなスピードに変更
timer = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: true) { (t) in
let speed = Float.random(in: 1 ... 5)
self.animationLayer.updateSpeed(speed)
}
}
override func viewWillDisappear() {
timer?.invalidate()
}
override var representedObject: Any? {
didSet {
}
}
}
일단 이 방법을 베이스로 키프레임 애니메이션을 실시하는 것이 가능하지만,
Core Animation
는 마음대로 GPU를 사용할 수 있는 경우는 사용해 버릴 것 같고, 발열 문제를 유저로부터 지적되었다. GPU를 사용하지 않고 CPU의 소모가 작은 실장 방법을 알고 싶다.
Reference
이 문제에 관하여(Swift: 재생 속도를 변경할 수 있는 키프레임 애니메이션), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Kyome/items/15eb1893c48a64900e12텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)