Nasıl özel hareket hızı oluşturma Temel Animasyon ile işlevi?
İOS oldukça güzel CGPath
(QuadCurve) boyunca CALayer
bir animasyon yapıyorum. Ama Apple tarafından provided birkaç (Easeİn/EaseOut vb.) daha ilginç hareket hızı işlevi kullanmak istiyorum. Örneğin, sıçrama ya da bir elastik fonksiyonu.
Bunları MediaTimingFunction ile yapmak mümkündür (bezier):
Ama yaratmak istiyorumzamanlama fonksiyonlarıbu daha karmaşıktır. Sorun zamanlama bu etkiler yaratacak kadar güçlü değil: kübik bezier gerektirecek gibi görünüyor ortam
Yukarıdaki oluşturmak için code Bu çok sinir bozucu kılan diğer çerçeveler, yeteri kadar basit. Eğrileri çıkış süresi (T-t eğrisi) ve zaman-pozisyon eğrileri değil giriş saati eşleme olduğunu unutmayın. Örneğin,(T) = t easeOutBouncedöndürür bir yenit. O zamanthareketi (animasyon etmeliyiz ne olursa olsun) çizmek için kullanılır.
Yani, 5* *karmaşık bir özel oluşturmak istiyorum ama bunu nasıl, ya da eğer mümkün mü onu bile bilmiyorum? Başka alternatif var mı?
DÜZENLEME:
İşte adımlar için somut bir örnek. Çok eğitici :)
Noktasından bir hat boyunca bir nesneye animasyon eklemek istiyorumbiriçinb"hat boyunca hareketini yukarıda easeOutBounce eğrisini kullanarak." sıçrama etmek istiyorum ama ... Bu tam çizgi takip ederbiriçinbama ne mümkün olandan daha karmaşık bir şekilde hızlandırmak yavaşlayacaktır bezier tabanlı geçerli CAMediaTimingFunction kullanarak.
Bu hat herhangi bir keyfi eğri hareketi yapmak CGPath ile belirtilen sağlar. Hala bu eğri boyunca hareket etmelidir, ama hızlandırmak ve çizgi örnekte olduğu gibi aynı şekilde yavaşlatmak gerekir.
Teoride böyle çalışması gerektiğini düşünüyorum
Sağlar hareketi kareyi bir animasyon eğri tanımlar(t) = p taşıyınneredettime [0..1]ppozisyon anında hesaplanırt. Bu yüzdenhareket(0)pozisyon eğrisi başlangıcında verirhareket(0.5)tam ortataşı(1)sonunda. Bir zamanlama fonksiyonuzaman(T) = tbu sağlamak içintdeğerler içinhareket ettirinbana istediğimi ver. Sıçrayan bir etki için, zamanlama işlevi aynı dönmelidirtdeğerler içinzaman(0.8)vezaman(0.8)(sadece bir örnek). Sadece zamanlama işlevi farklı bir etki elde etmek için değiştirin.
(Evet, mümkün ve ileri geri giden dört çizgi parçaları oluşturma katılarak line-sıçrayan, ama buna gerek yok. Sonuçta, bu sadece haritalar basit doğrusal bir fonksiyonzamanpozisyonlar için değerler.)
Burada mantıklı olduğumu umuyorum.
CEVAP
Bunu buldum:
Cocoa with Love - Parametric acceleration curves in Core Animation
Ama biraz daha basit ve daha okunabilir kullanarak blokları ile yapılabilir sanırım. Bu gibi bir şey görünüyor CAKeyframeAnimation bir kategori tanımlayabiliriz:
Parametrik CAKeyframeAnimation.h:
// this should be a function that takes a time value between
// 0.0 and 1.0 (where 0.0 is the beginning of the animation
// and 1.0 is the end) and returns a scale factor where 0.0
// would produce the starting value and 1.0 would produce the
// ending value
typedef double (^KeyframeParametricBlock)(double);
@interface CAKeyframeAnimation (Parametric)
(id)animationWithKeyPath:(NSString *)path
function:(KeyframeParametricBlock)block
fromValue:(double)fromValue
toValue:(double)toValue;
Parametrik CAKeyframeAnimation.m:
@implementation CAKeyframeAnimation (Parametric)
(id)animationWithKeyPath:(NSString *)path
function:(KeyframeParametricBlock)block
fromValue:(double)fromValue
toValue:(double)toValue {
// get a keyframe animation to set up
CAKeyframeAnimation *animation =
[CAKeyframeAnimation animationWithKeyPath:path];
// break the time into steps
// (the more steps, the smoother the animation)
NSUInteger steps = 100;
NSMutableArray *values = [NSMutableArray arrayWithCapacity:steps];
double time = 0.0;
double timeStep = 1.0 / (double)(steps - 1);
for(NSUInteger i = 0; i < steps; i ) {
double value = fromValue (block(time) * (toValue - fromValue));
[values addObject:[NSNumber numberWithDouble:value]];
time = timeStep;
}
// we want linear animation between keyframes, with equal time steps
animation.calculationMode = kCAAnimationLinear;
// set keyframes and we're done
[animation setValues:values];
return(animation);
}
@end
Şimdi kullanımı bu gibi bir şey olacaktır:
// define a parametric function
KeyframeParametricBlock function = ^double(double time) {
return(1.0 - pow((1.0 - time), 2.0));
};
if (layer) {
[CATransaction begin];
[CATransaction
setValue:[NSNumber numberWithFloat:2.5]
forKey:kCATransactionAnimationDuration];
// make an animation
CAAnimation *drop = [CAKeyframeAnimation
animationWithKeyPath:@"position.y"
function:function fromValue:30.0 toValue:450.0];
// use it
[layer addAnimation:drop forKey:@"position"];
[CATransaction commit];
}
İstediğin kadar basit olmayabilir biliyorum, ama bu bir başlangıç.
Nasıl bu C programı iki temel işlevi i...
bir eklenti kullanmadan jQuery hareket...
Nasıl bir CALayer anında (G/Ç animasyo...
Nasıl özel EL bir işlevi oluşturmak iç...
Nasıl özel yöntemleri, alanları veya i...