260 lines
6.5 KiB
C++
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;
|
|
}
|
|
}
|
|
|
|
} |