nim_duilib/duilib/Animation/AnimationPlayer.cpp
jiajia_deng 4933d1f2bc Remove dependency on shared
Signed-off-by: jiajia_deng <2894220@gmail.com>
2019-09-20 16:27:58 +08:00

260 lines
6.5 KiB
C++

#include "StdAfx.h"
#include "AnimationPlayer.h"
namespace ui
{
AnimationPlayerBase::AnimationPlayerBase() : m_bFirstRun(true), m_animationType(0)
{
Init();
}
void AnimationPlayerBase::Reset()
{
m_weakFlagOwner.Cancel();
Init();
}
void AnimationPlayerBase::Init()
{
m_startValue = 0;
m_endValue = 0;
m_currentValue = 0;
m_totalMillSeconds = DUI_NOSET_VALUE;
m_palyedMillSeconds = 0;
m_elapseMillSeconds = 0;
m_currentTime.QuadPart = 0;
m_timeFrequency.QuadPart = 0;
m_reverseStart = false;
m_bPlaying = false;
}
void AnimationPlayerBase::Start()
{
m_weakFlagOwner.Cancel();
m_palyedMillSeconds = 0;
m_reverseStart = false;
StartTimer();
}
void AnimationPlayerBase::Stop()
{
m_weakFlagOwner.Cancel();
}
void AnimationPlayerBase::Continue()
{
m_weakFlagOwner.Cancel();
if (m_reverseStart == true)
ReverseAllValue();
m_reverseStart = false;
StartTimer();
m_bFirstRun = false;
}
void AnimationPlayerBase::ReverseContinue()
{
m_weakFlagOwner.Cancel();
if (m_reverseStart == false)
ReverseAllValue();
if (m_bFirstRun)
m_palyedMillSeconds = 0;
m_reverseStart = true;
StartTimer();
m_bFirstRun = false;
}
void AnimationPlayerBase::StartTimer()
{
QueryPerformanceFrequency(&m_timeFrequency);
QueryPerformanceCounter(&m_currentTime);
m_bPlaying = true;
if (m_endValue - m_startValue == 0) {
Complete();
return;
}
m_elapseMillSeconds = m_totalMillSeconds / abs(m_endValue - m_startValue);
if (m_elapseMillSeconds == 0) {
m_elapseMillSeconds = 1;
}
Play();
auto playCallback = nbase::Bind(&AnimationPlayerBase::Play, this);
TimerManager::GetInstance()->AddCancelableTimer(m_weakFlagOwner.GetWeakFlag(), playCallback, m_elapseMillSeconds, TimerManager::REPEAT_FOREVER);
}
void AnimationPlayerBase::Play()
{
LARGE_INTEGER newCurrentTime;
QueryPerformanceCounter(&newCurrentTime);
m_palyedMillSeconds += (double(newCurrentTime.QuadPart - m_currentTime.QuadPart) * 1000 )/m_timeFrequency.QuadPart;
QueryPerformanceCounter(&m_currentTime);
int newCurrentValue = GetCurrentValue();
if (m_playCallback) {
if (m_endValue > m_startValue && newCurrentValue >= m_endValue
|| m_endValue < m_startValue && newCurrentValue <= m_endValue) {
newCurrentValue = m_endValue;
m_playCallback(newCurrentValue);
Complete();
}
else {
if (newCurrentValue != m_currentValue) {
m_playCallback(newCurrentValue);
}
}
}
else {
ASSERT(FALSE);
}
m_currentValue = newCurrentValue;
}
void AnimationPlayerBase::ReverseAllValue()
{
std::swap(m_startValue, m_endValue);
m_currentValue = m_startValue;
m_palyedMillSeconds = m_totalMillSeconds - m_palyedMillSeconds;
if (m_palyedMillSeconds < 0)
m_palyedMillSeconds = 0;
}
void AnimationPlayerBase::Complete()
{
if (m_completeCallback)
m_completeCallback();
m_weakFlagOwner.Cancel();
m_bPlaying = false;
}
AnimationPlayer::AnimationPlayer()
{
Init();
}
void AnimationPlayer::Init()
{
__super::Init();
m_speedUpRatio = 0;
m_speedDownRatio = 0;
m_speedDownMillSeconds = 0;
m_linerMillSeconds = 0;
m_linearSpeed = 0;
m_speedUpfactorA = 0;
m_speedDownfactorA = 0;
m_speedDownfactorB = 0;
m_maxTotalMillSeconds = 1000000;
}
void AnimationPlayer::StartTimer()
{
InitFactor();
__super::StartTimer();
}
int AnimationPlayer::GetCurrentValue()
{
if (m_palyedMillSeconds >= m_totalMillSeconds) {
return m_endValue;
}
int detaValue = 0;
if (m_palyedMillSeconds <= m_speedUpMillSeconds) {
detaValue = int(m_speedUpfactorA * m_palyedMillSeconds * m_palyedMillSeconds);
}
else if (m_palyedMillSeconds <= (m_speedUpMillSeconds + m_linerMillSeconds)) {
double linerTime = m_palyedMillSeconds - m_speedUpMillSeconds;
detaValue = int(m_speedUpfactorA * m_speedUpMillSeconds * m_speedUpMillSeconds + m_linearSpeed * linerTime);
}
else if (m_palyedMillSeconds <= m_totalMillSeconds) {
double speedDownTime = m_palyedMillSeconds - m_speedUpMillSeconds - m_linerMillSeconds;
detaValue = int(m_speedUpfactorA * m_speedUpMillSeconds * m_speedUpMillSeconds + m_linearSpeed * m_linerMillSeconds
+ m_speedDownfactorA * speedDownTime * speedDownTime + m_speedDownfactorB * speedDownTime);
}
else {
ASSERT(FALSE);
}
int currentValue = 0;
if (m_endValue > m_startValue) {
currentValue = m_startValue + detaValue;
}
else {
currentValue = m_startValue - detaValue;
}
return currentValue;
}
void AnimationPlayer::InitFactor()
{
double s = abs(m_endValue - m_startValue);
if (m_speedUpRatio == 0 && m_speedDownRatio == 0) { //liner
ASSERT(m_totalMillSeconds == DUI_NOSET_VALUE && m_linearSpeed != 0 || m_totalMillSeconds != DUI_NOSET_VALUE && m_linearSpeed == 0);
if (m_totalMillSeconds == DUI_NOSET_VALUE) {
m_totalMillSeconds = int(s / m_linearSpeed);
}
else {
m_linearSpeed = s / m_totalMillSeconds;
}
m_linerMillSeconds = m_totalMillSeconds;
}
else {
if (m_totalMillSeconds != DUI_NOSET_VALUE) {
if (m_speedUpRatio != 0) {
m_speedUpfactorA = s / ((m_speedUpRatio*m_speedUpRatio + (1 - m_speedUpRatio - m_speedDownRatio)*2*m_speedUpRatio + m_speedUpRatio*m_speedDownRatio)
*m_totalMillSeconds*m_totalMillSeconds);
}
else if (m_speedDownRatio != 0) {
m_speedDownfactorA = -s / ((m_speedDownRatio*m_speedDownRatio + (1 - m_speedUpRatio - m_speedDownRatio)*2*m_speedDownRatio + m_speedUpRatio*m_speedDownRatio)
*m_totalMillSeconds*m_totalMillSeconds);
}
else {
ASSERT(FALSE);
}
}
double tmpValue = 0;
if (m_speedUpfactorA != 0 && m_speedUpRatio != 0) {
tmpValue = m_speedUpfactorA * m_speedUpRatio;
if (m_speedDownRatio != 0) {
m_speedDownfactorA = -m_speedUpfactorA * m_speedUpRatio / m_speedDownRatio;
}
}
else if (m_speedDownfactorA != 0 && m_speedDownRatio != 0) {
tmpValue = -m_speedDownfactorA * m_speedDownRatio;
if (m_speedUpRatio != 0) {
m_speedUpfactorA = -m_speedDownfactorA * m_speedDownRatio / m_speedUpRatio;
}
}
else {
ASSERT(FALSE);
}
if (m_totalMillSeconds == DUI_NOSET_VALUE) {
m_totalMillSeconds = int(sqrt(s / (m_speedUpfactorA*m_speedUpRatio*m_speedUpRatio + (1 - m_speedUpRatio - m_speedDownRatio) * 2 * tmpValue
- m_speedDownfactorA*m_speedDownRatio*m_speedDownRatio) ));
if (m_totalMillSeconds > m_maxTotalMillSeconds) {
m_totalMillSeconds = m_maxTotalMillSeconds;
InitFactor();
return;
}
}
m_linearSpeed = 2 * tmpValue * m_totalMillSeconds;
m_speedDownfactorB = m_linearSpeed;
m_speedUpMillSeconds = m_totalMillSeconds * m_speedUpRatio;
m_speedDownMillSeconds = m_totalMillSeconds * m_speedDownRatio;
m_linerMillSeconds = m_totalMillSeconds - m_speedUpMillSeconds - m_speedDownMillSeconds;
}
}
}