Estou animando um CALayer
along a CGPath
(QuadCurve) muito bem no iOS. Mas eu gostaria de usar uma função de atenuação mais interessante do que as poucas fornecidas pela Apple (EaseIn / EaseOut etc). Por exemplo, um salto ou função elástica.
Essas coisas são possíveis de fazer com MediaTimingFunction (bezier):
Mas eu gostaria de criar funções de temporização mais complexas. O problema é que o sincronismo da mídia parece exigir um Bezier cúbico que não é poderoso o suficiente para criar estes efeitos:
(fonte: sparrow-framework.org )
O código para criar o código acima é simples o suficiente em outras estruturas, o que torna isso muito frustrante. Observe que as curvas estão mapeando o tempo de entrada para o tempo de saída (curva Tt) e não as curvas de posição de tempo. Por exemplo, facilidadeOutBounce (T) = t retorna um novo t . Então esse t é usado para plotar o movimento (ou qualquer propriedade que devemos animar).
Então, eu gostaria de criar um personalizado complexo, CAMediaTimingFunction
mas não tenho ideia de como fazer isso, ou se é possível? Existem alternativas?
EDITAR:
Aqui está um exemplo concreto em etapas. Muito educacional :)
Quero animar um objeto ao longo de uma linha do ponto a ao b , mas quero que ele "salte" seu movimento ao longo da linha usando a curva facilidadeOutBounce acima. Isso significa que ele seguirá a linha exata de a até b , mas irá acelerar e desacelerar de uma forma mais complexa do que seria possível usando o CAMediaTimingFunction atual baseado em bezier.
Vamos fazer dessa linha qualquer movimento de curva arbitrário especificado com CGPath. Ele ainda deve se mover ao longo dessa curva, mas deve acelerar e desacelerar da mesma forma que no exemplo da linha.
Em teoria, acho que deveria funcionar assim:
Vamos descrever a curva de movimento como um movimento de animação de quadro-chave (t) = p , onde t é o tempo [0..1], p é a posição calculada no tempo t . Assim movimento (0) retorna a posição no início da curva, movimento (0,5), o meio exacto e movimento (1) na extremidade. Usar uma função de tempo (T) = t para fornecer os valores de t para mover deve me dar o que eu quero. Para um efeito de salto, a função de tempo deve retornar os mesmos valores t para tempo (0,8) e tempo (0,8)(apenas um exemplo). Basta substituir a função de tempo para obter um efeito diferente.
(Sim, é possível fazer salto de linha criando e juntando quatro segmentos de linha que vão e voltam, mas isso não deve ser necessário. Afinal, é apenas uma função linear simples que mapeia valores de tempo para posições.)
Espero estar fazendo sentido aqui.
fonte
Respostas:
Eu achei isto:
Cocoa with Love - curvas de aceleração paramétrica no Core Animation
Mas acho que pode ser um pouco mais simples e mais legível usando blocos. Portanto, podemos definir uma categoria em CAKeyframeAnimation que se parece com isto:
CAKeyframeAnimation + Parametric.h:
CAKeyframeAnimation + Parametric.m:
Agora o uso será parecido com isto:
Eu sei que pode não ser tão simples quanto o que você queria, mas é um começo.
fonte
A partir do iOS 10, tornou-se possível criar uma função de temporização personalizada mais fácil usando dois novos objetos de temporização.
1) UICubicTimingParameters permite definir a curva de Bézier cúbica como uma função de atenuação.
ou simplesmente usando pontos de controle na inicialização do animador
Este serviço incrível vai ajudar a escolher pontos de controle para suas curvas.
2) UISpringTimingParameters permite que os desenvolvedores manipulem a taxa de amortecimento , massa , rigidez e velocidade inicial para criar o comportamento de mola desejado.
O parâmetro de duração ainda é apresentado no Animator, mas será ignorado para o tempo da mola.
Se essas duas opções não forem suficientes, você também pode implementar sua própria curva de tempo, confirmando com o protocolo UITimingCurveProvider .
Mais detalhes sobre como criar animações com diferentes parâmetros de tempo, você pode encontrar na documentação .
Além disso, consulte a apresentação Advances in UIKit Animations and Transitions da WWDC 2016.
fonte
CoreAnimation
versão deUISpringTimingParameters
(CASpringAnimation
) é compatível com iOS 9!UITimingCurveProvider
a não apenas representar uma animação cúbica ou de mola, mas também de representar uma animação que combina ambas as vias cúbica e elásticaUITimingCurveType.composed
.Uma maneira de criar uma função de temporização personalizada é usando o método de fábrica functionWithControlPoints :::: em CAMediaTimingFunction (há um método initWithControlPoints :::: init correspondente também). O que isso faz é criar uma curva de Bézier para sua função de tempo. Não é uma curva arbitrária, mas as curvas de Bézier são muito poderosas e flexíveis. É preciso um pouco de prática para pegar o jeito dos pontos de controle. Uma dica: a maioria dos programas de desenho pode criar curvas de Bézier. Jogar com eles lhe dará um feedback visual sobre a curva que você está representando com os pontos de controle.
Os esta ligação aponta para a documentação da Apple. Há uma seção curta, mas útil, sobre como as funções de pré-construção são construídas a partir de curvas.
Editar: O código a seguir mostra uma animação de salto simples. Para fazer isso, criei uma função de tempo composta ( propriedades NSArray de valores e tempo ) e dei a cada segmento da animação uma duração de tempo diferente ( propriedade de tempos-chave ). Desta forma, você pode compor curvas de Bézier para compor um tempo mais sofisticado para animações. Este é um bom artigo sobre este tipo de animações com um bom código de exemplo.
fonte
Não tenho certeza se você ainda está procurando, mas o PRTween parece bastante impressionante em termos de sua capacidade de ir além do que o Core Animation oferece fora da caixa, mais notavelmente, funções de temporização personalizadas. Ele também vem embalado com muitas - senão todas - as curvas de atenuação populares que várias estruturas da web fornecem.
fonte
Uma implementação de versão rápida é TFAnimation . A demonstração é uma animação de curva de pecado . Use
TFBasicAnimation
apenas como,CABasicAnimation
exceto atribuirtimeFunction
a um bloco diferente detimingFunction
.O ponto-chave é a subclasse
CAKeyframeAnimation
e calcula a posição dos quadros portimeFunction
no1 / 60fps
intervalo s. Depois disso, adicione todos os valores calculados avalues
deCAKeyframeAnimation
e os tempos por intervalokeyTimes
também.fonte
Criei uma abordagem baseada em blocos, que gera um grupo de animação, com várias animações.
Cada animação, por propriedade, pode usar 1 de 33 curvas paramétricas diferentes, uma função de temporização de diminuição com velocidade inicial ou uma mola personalizada configurada de acordo com suas necessidades.
Uma vez que o grupo é gerado, ele é armazenado em cache na Visualização e pode ser disparado usando uma AnimationKey, com ou sem a animação. Uma vez acionada, a animação é sincronizada de acordo com os valores da camada de apresentação e aplicada de acordo.
O framework pode ser encontrado aqui FlightAnimator
Aqui está um exemplo abaixo:
Para acionar a animação
fonte