当前位置: 首页 > 工具软件 > Tween > 使用案例 >

Tween算法及缓动效果(JS,C++)

贲功
2023-12-01

原帖地址:http://www.cnblogs.com/cloudgamer/archive/2009/01/06/Tween.html


C++代码:


Tween.h

#pragma once

#include <math.h>

// Algorithm Reference:
//http://www.robertpenner.com/easing/
//http://www.cnblogs.com/cloudgamer/archive/2009/01/06/Tween.html

#ifndef PI
#define PI	3.1415926f
#endif

const float EPSINON = 0.000001f;
#define EQUAL_ZERO(x) ((x >= - EPSINON) && (x <= EPSINON)) ? TRUE : FALSE

class CTween
{
public:
	CTween(void);
	~CTween(void);

	// Linear
	float Linear_easeIn(float t, float b, float c, float d);
	float Linear_easeOut(float t, float b, float c, float d);
	float Linear_easeInOut(float t, float b, float c, float d);

	// Quadratic
	float Quad_easeIn(float t, float b, float c, float d);
	float Quad_easeOut(float t, float b, float c, float d);
	float Quad_easeInOut(float t, float b, float c, float d);

	// Cubic
	float Cubic_easeIn(float t, float b, float c, float d);
	float Cubic_easeOut(float t, float b, float c, float d);
	float Cubic_easeInOut(float t, float b, float c, float d);

	// Quartic
	float Quart_easeIn(float t, float b, float c, float d);
	float Quart_easeOut(float t, float b, float c, float d);
	float Quart_easeInOut(float t, float b, float c, float d);

	// Quintic
	float Quint_easeIn(float t, float b, float c, float d);
	float Quint_easeOut(float t, float b, float c, float d);
	float Quint_easeInOut(float t, float b, float c, float d);

	// Sinusoidal
	float Sine_easeIn(float t, float b, float c, float d);
	float Sine_easeOut(float t, float b, float c, float d);
	float Sine_easeInOut(float t, float b, float c, float d);

	// Exponential
	float Expo_easeIn(float t, float b, float c, float d);
	float Expo_easeOut(float t, float b, float c, float d);
	float Expo_easeInOut(float t, float b, float c, float d);

	// Circular
	float Circ_easeIn(float t, float b, float c, float d);
	float Circ_easeOut(float t, float b, float c, float d);
	float Circ_easeInOut(float t, float b, float c, float d);

	// Elastic
	float Elastic_easeIn(float t, float b, float c, float d, float a = 0.0f, float p = 0.0f);
	float Elastic_easeOut(float t, float b, float c, float d, float a = 0.0f, float p = 0.0f);
	float Elastic_easeInOut(float t, float b, float c, float d, float a = 0.0f, float p = 0.0f);

	// Back
	float Back_easeIn(float t, float b, float c, float d, float s = 0.0f);
	float Back_easeOut(float t, float b, float c, float d, float s = 0.0f);
	float Back_easeInOut(float t, float b, float c, float d, float s = 0.0f);

	// Bounce
	float Bounce_easeOut(float t, float b, float c, float d);
	float Bounce_easeIn(float t, float b, float c, float d);
	float Bounce_easeInOut(float t, float b, float c, float d);

public:
	float t, b, c, d, a, p;
};


Tween.cpp

#include "StdAfx.h"
#include "Tween.h"

CTween::CTween(void)
{
}

CTween::~CTween(void)
{
}

// Linear
float CTween::Linear_easeIn(float t, float b, float c, float d)
{
	return c * t / d + b;
}

float CTween::Linear_easeOut(float t, float b, float c, float d)
{
	return c * t / d + b;
}

float CTween::Linear_easeInOut(float t, float b, float c, float d)
{
	return c * t / d + b;
}

// Quadratic
float CTween::Quad_easeIn(float t, float b, float c, float d)
{
	return c * (t /= d) * t + b;
}

float CTween::Quad_easeOut(float t, float b, float c, float d)
{
	return -c * (t /= d) * (t - 2) + b;
}

float CTween::Quad_easeInOut(float t, float b, float c, float d)
{
	if ((t /= d / 2) < 1)
		return c / 2 * t * t + b;
	return -c / 2 * ((--t) * (t - 2) - 1) + b;
}

// Cubic
float CTween::Cubic_easeIn(float t, float b, float c, float d)
{
	return c * (t /= d) * t * t + b;
}

float CTween::Cubic_easeOut(float t, float b, float c, float d)
{
	return c * ((t = t / d - 1) * t * t + 1) + b;
}

float CTween::Cubic_easeInOut(float t, float b, float c, float d)
{
	if ((t /= d / 2) < 1)
		return c / 2 * t * t * t + b;
	return c / 2 * ((t -= 2) * t * t + 2) + b;
}

// Quartic
float CTween::Quart_easeIn(float t, float b, float c, float d)
{
	return c * (t /= d) * t * t * t + b;
}

float CTween::Quart_easeOut(float t, float b, float c, float d)
{
	return -c * ((t = t / d - 1) * t * t * t - 1) + b;
}

float CTween::Quart_easeInOut(float t, float b, float c, float d)
{
	if ((t /= d / 2) < 1)
		return c / 2 * t * t * t * t + b;
	return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
}

// Quintic
float CTween::Quint_easeIn(float t, float b, float c, float d)
{
	return c * (t /= d) * t * t * t * t + b;
}

float CTween::Quint_easeOut(float t, float b, float c, float d)
{
	return c * ((t = t / d - 1)* t * t * t * t + 1) + b;
}

float CTween::Quint_easeInOut(float t, float b, float c, float d)
{
	if ((t /= d / 2) < 1)
		return c / 2 * t * t * t * t * t + b;
	return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
}

// Sinusoidal
float CTween::Sine_easeIn(float t, float b, float c, float d)
{
	return -c * cos(t / d * (PI / 2)) + c + b;
}

float CTween::Sine_easeOut(float t, float b, float c, float d)
{
	return c * sin(t / d * (PI / 2)) + b;
}

float CTween::Sine_easeInOut(float t, float b, float c, float d)
{
	return -c / 2 * (cos(PI * t/ d) - 1) + b;
}

// Exponential
float CTween::Expo_easeIn(float t, float b, float c, float d)
{
	return (t == 0) ? b : c * pow(2, 10 * (t / d - 1)) + b;
}

float CTween::Expo_easeOut(float t, float b, float c, float d)
{
	return (t == d) ? b + c : c * (-pow(2, -10 * t / d) + 1) + b;
}

float CTween::Expo_easeInOut(float t, float b, float c, float d)
{
	if (t == 0)
		return b;
	if (t == d)
		return b+c;
	if ((t /= d / 2) < 1)
		return c / 2 * pow(2, 10 * (t - 1)) + b;
	return c / 2 * (-pow(2, -10 * --t) + 2) + b;
}

// Circular
float CTween::Circ_easeIn(float t, float b, float c, float d)
{
	return -c * (sqrt(1 - (t /= d) * t) - 1) + b;
}

float CTween::Circ_easeOut(float t, float b, float c, float d)
{
	return c * sqrt(1 - (t = t / d - 1) * t) + b;
}

float CTween::Circ_easeInOut(float t, float b, float c, float d)
{
	if ((t /= d / 2) < 1)
		return -c / 2 * (sqrt(1 - t * t) - 1) + b;
	return c / 2 * (sqrt(1 - (t -= 2) * t) + 1) + b;
}

// Elastic
float CTween::Elastic_easeIn(float t, float b, float c, float d, float a/* = 0.0f*/, float p/* = 0.0f*/)
{
	float s = 0;
	if (t == 0)
		return b;
	if ((t /= d) == 1)
		return b + c;
	if (!p)
		p = d * .3f;
	if (!a || a < abs(c))
	{
		a = c;
		s = p/4;
	}
	else
		s = p / (2 * PI) * asin (c / a);
	return -(a * pow(2, 10 * (t -= 1)) * sin((t * d - s) * (2 * PI) / p)) + b;
}

float CTween::Elastic_easeOut(float t, float b, float c, float d, float a/* = 0.0f*/, float p/* = 0.0f*/)
{
	float s = 0;
	if (t == 0)
		return b;
	if ((t /= d) == 1)
		return (b + c);
	if (!p)
		p = d *.3f;
	if (!a || a < abs(c))
	{
		a = c;
		s = p / 4;
	}
	else
		s = p / (2 * PI) * sin((float)c / a);

	return (a * pow(2.0f, (int) - 10 * t) * sin((t * d - s) * (2 * PI) / p) + c + b);
}

float CTween::Elastic_easeInOut(float t, float b, float c, float d, float a/* = 0.0f*/, float p/* = 0.0f*/)
{
	float s = 0;
	if (t == 0)
		return b;
	if ((t /= d / 2) == 2)
		return b + c;
	if (!p)
		p = d * (.3f * 1.5f);
	if (!a || a < abs(c))
	{
		a = c;
		s = p/4;
	}
	else
		s = p / (2 * PI) * asin (c / a);
	if (t < 1)
		return -.5f * (a * pow(2, 10 * (t -= 1)) * sin( (t * d - s) * (2 * PI) / p )) + b;
	return a * pow(2, -10 * (t -= 1)) * sin((t * d - s) * (2 * PI) / p ) * .5f + c + b;
}

// Back
float CTween::Back_easeIn(float t, float b, float c, float d, float s/* = 0.0f*/)
{
	if (EQUAL_ZERO(s))
		s = 1.70158f;
	return c * (t /= d) * t * ((s + 1) * t - s) + b;
}

float CTween::Back_easeOut(float t, float b, float c, float d, float s/* = 0.0f*/)
{
	if (EQUAL_ZERO(s))
		s = 1.70158f;
	return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
}

float CTween::Back_easeInOut(float t, float b, float c, float d, float s/* = 0.0f*/)
{
	if (EQUAL_ZERO(s))
		s = 1.70158f;
	if ((t /= d / 2) < 1)
		return c / 2 * (t * t * (((s *= (1.525f)) + 1) * t - s)) + b;
	return c / 2 * ((t -= 2) * t * (((s *= (1.525f)) + 1) * t + s) + 2) + b;
}

// Bounce
float CTween::Bounce_easeOut(float t, float b, float c, float d)
{
	if ((t /= d) < (1 / 2.75))
	{
		return c * (7.5625f * t * t) + b;
	}
	else if (t < (2 / 2.75))
	{
		return c * (7.5625f * (t -= (1.5f / 2.75f)) * t + .75f) + b;
	}
	else if (t < (2.5 / 2.75))
	{
		return c * (7.5625f * (t -= (2.25f / 2.75f)) * t + .9375f) + b;
	}
	else
	{
		return c * (7.5625f * (t -= (2.625f / 2.75f)) * t + .984375f) + b;
	}
}

float CTween::Bounce_easeIn(float t, float b, float c, float d)
{
	return c - Bounce_easeOut(d - t, 0, c, d) + b;
}

float CTween::Bounce_easeInOut(float t, float b, float c, float d)
{
	if (t < d / 2)
		return Bounce_easeIn(t * 2, 0, c, d) * .5f + b;
	else return Bounce_easeOut(t * 2 - d, 0, c, d) * .5f + c * .5f + b;
}


 类似资料: