Ja animowania CALayer
wzdłuż CGPath
(QuadCurve) całkiem ładnie w iOS. Ale chciałbym użyć ciekawszej funkcji wygładzania niż kilka dostarczonych przez Apple (EaseIn / EaseOut itp.). Na przykład funkcja odbijania lub elastyczności.
Te rzeczy można zrobić z MediaTimingFunction (bezier):
Ale chciałbym stworzyć bardziej złożone funkcje czasowe . Problem polega na tym, że synchronizacja mediów wydaje się wymagać sześciennego beziera, który nie jest wystarczająco silny, aby stworzyć takie efekty:
(źródło: sparrow-framework.org )
Kod , aby utworzyć powyżej jest dość proste w innych ram, co sprawia, że to bardzo frustrujące. Należy zauważyć, że krzywe odwzorowują czas wejściowy do czasu wyjściowego (krzywa Tt), a nie krzywe czas-pozycja. Na przykład, easyOutBounce (T) = t zwraca nowe t . Następnie to t jest używane do wykreślenia ruchu (lub jakiejkolwiek właściwości, którą powinniśmy ożywić).
Chciałbym więc stworzyć złożony zwyczaj, CAMediaTimingFunction
ale nie mam pojęcia, jak to zrobić, a jeśli to w ogóle możliwe? Czy są jakieś alternatywy?
EDYTOWAĆ:
Oto konkretny przykład kroków. Bardzo pouczające :)
Chcę animować obiekt wzdłuż linii od punktu a do b , ale chcę, aby „odbijał” swój ruch wzdłuż linii, używając krzywej EasyOutBounce powyżej. Oznacza to, że będzie podążał dokładnie za linią od a do b , ale będzie przyspieszać i zwalniać w bardziej złożony sposób niż jest to możliwe przy użyciu obecnej funkcji CAMediaTimingFunction opartej na bezierze.
Zróbmy dla tej linii dowolny dowolny ruch krzywej określony przez CGPath. Powinien nadal poruszać się wzdłuż tej krzywej, ale powinien przyspieszać i zwalniać w taki sam sposób, jak na przykładzie linii.
Teoretycznie myślę, że powinno to działać tak:
Opiszmy krzywą ruchu jako animację ruchu klatki kluczowej (t) = p , gdzie t to czas [0..1], p to pozycja obliczona w czasie t . Zatem move (0) zwraca pozycję na początku krzywej, przesuwa (0,5) dokładnie w środku i przesuwa (1) na końcu. Użycie funkcji pomiaru czasu time (T) = t do podania wartości t dla ruchu powinno dać mi to, czego chcę. Aby uzyskać efekt odbijania, funkcja pomiaru czasu powinna zwracać te same wartości t dla czasu (0,8) i czasu (0,8)(tylko przykład). Wystarczy wymienić funkcję pomiaru czasu, aby uzyskać inny efekt.
(Tak, odbijanie linii można wykonać, tworząc i łącząc cztery segmenty linii, które poruszają się tam iz powrotem, ale nie powinno to być konieczne. W końcu jest to tylko prosta funkcja liniowa, która odwzorowuje wartości czasu na pozycje.)
Mam nadzieję, że mam tutaj sens.
źródło
Odpowiedzi:
Znalazłem to:
Cocoa with Love - parametryczne krzywe przyspieszenia w animacji podstawowej
Ale myślę, że można to trochę uprościć i uczynić bardziej czytelnym, używając bloków. Możemy więc zdefiniować kategorię w CAKeyframeAnimation, która wygląda mniej więcej tak:
CAKeyframeAnimation + Parametric.h:
CAKeyframeAnimation + Parametric. M:
Teraz użycie będzie wyglądać mniej więcej tak:
Wiem, że może to nie być tak proste, jak chciałeś, ale to początek.
źródło
Od iOS 10 stało się możliwe łatwiejsze tworzenie niestandardowych funkcji pomiaru czasu przy użyciu dwóch nowych obiektów czasowych.
1) UICubicTimingParameters pozwala zdefiniować sześcienną krzywą Béziera jako funkcję krzywej wygładzania .
lub po prostu używając punktów kontrolnych podczas inicjalizacji animatora
Ta niesamowita usługa pomoże wybrać punkty kontrolne dla twoich krzywych.
2) UISpringTimingParameters pozwala programistom manipulować współczynnikiem tłumienia , masą , sztywnością i prędkością początkową w celu uzyskania pożądanego zachowania sprężyny.
Parametr czasu trwania jest nadal wyświetlany w Animatorze, ale zostanie zignorowany w przypadku synchronizacji wiosennej.
Jeśli te dwie opcje nie są wystarczające, możesz również zaimplementować własną krzywą taktowania, potwierdzając protokół UITimingCurveProvider .
Więcej szczegółów, jak tworzyć animacje z różnymi parametrami czasowymi, można znaleźć w dokumentacji .
Także, proszę zobaczyć Advances in UIKit Animacje i przejścia prezentacji z WWDC 2016.
źródło
CoreAnimation
wersjaUISpringTimingParameters
(CASpringAnimation
) jest obsługiwana z powrotem do iOS 9!UITimingCurveProvider
do nie tylko reprezentowania animacji sześciennej lub sprężynowej, ale także do przedstawiania animacji, która łączy zarówno sześcienne, jak i sprężynoweUITimingCurveType.composed
.Sposobem na stworzenie niestandardowej funkcji pomiaru czasu jest użycie metody functionWithControlPoints :::: factory w CAMediaTimingFunction (istnieje również odpowiednia metoda initWithControlPoints :::: init). To, co to robi, to utworzenie krzywej Béziera dla funkcji pomiaru czasu. Nie jest to dowolna krzywa, ale krzywe Béziera są bardzo mocne i elastyczne. Potrzeba trochę praktyki, aby opanować punkty kontrolne. Wskazówka: większość programów do rysowania może tworzyć krzywe Béziera. Zabawa z nimi da ci wizualną informację zwrotną na temat krzywej, którą reprezentujesz za pomocą punktów kontrolnych.
To łącze prowadzi do dokumentacji firmy Apple. Istnieje krótka, ale przydatna sekcja dotycząca konstruowania funkcji przed kompilacją z krzywych.
Edycja: poniższy kod przedstawia prostą animację odbijania. Aby to zrobić, stworzyłem złożoną funkcję pomiaru czasu ( wartości i właściwości czasowe NSArray) i nadałem każdemu segmentowi animacji inną długość czasu ( właściwość keytimes ). W ten sposób można komponować krzywe Béziera, aby uzyskać bardziej wyrafinowane taktowanie animacji. To jest dobry artykuł na temat tego typu animacji z ładnym przykładowym kodem.
źródło
Nie jestem pewien, czy nadal szukasz, ale PRTween wygląda dość imponująco pod względem możliwości wykraczania poza to, co Core Animation daje ci po wyjęciu z pudełka, w szczególności niestandardowe funkcje czasowe. Zawiera również wiele - jeśli nie wszystkie - popularnych krzywych łagodzenia, które zapewniają różne frameworki internetowe.
źródło
Szybką implementacją jest TFAnimation . Demo to animacja krzywej grzechu . Używaj
TFBasicAnimation
tak samo, jakCABasicAnimation
z wyjątkiem przypisaniatimeFunction
z blokiem innym niżtimingFunction
.Kluczowym punktem jest podklasą
CAKeyframeAnimation
i ramek oblicz pozycja otimeFunction
w1 / 60fps
s przedział .Po wszystko dodać wszystkie obliczoną wartośćvalues
odCAKeyframeAnimation
i do przedziału czasu przezkeyTimes
zbyt.źródło
Stworzyłem podejście oparte na blokach, które generuje grupę animacji z wieloma animacjami.
Każda animacja, dla każdej właściwości, może wykorzystywać 1 z 33 różnych krzywych parametrycznych, funkcję pomiaru czasu rozpadu z prędkością początkową lub niestandardową sprężynę skonfigurowaną zgodnie z Twoimi potrzebami.
Po wygenerowaniu grupa jest zapisywana w pamięci podręcznej w widoku i może zostać wyzwolona za pomocą AnimationKey, z animacją lub bez. Po uruchomieniu animacja jest odpowiednio synchronizowana z wartościami warstwy prezentacji i odpowiednio stosowana.
Framework można znaleźć tutaj FlightAnimator
Oto przykład poniżej:
Aby uruchomić animację
źródło