#include <SFML/Graphics.hpp>
#include <Plinth/Sfml/Anchor.hpp>
#include <Plinth/Sfml/Animation.hpp>
int main()
{
sf::Font font;
if (!font.loadFromFile("resources/arial.ttf"))
return EXIT_FAILURE;
sf::Text infoText("1 Fade In\n2 Flash\n3 Rotate In\n4 Roll In\n5 Zoom Out Down\n6 Bounce", font, 16);
sf::Text text("Animated", font, 100);
text.setOrigin(pl::Anchor::Local::getCenter(text));
const sf::Time duration{ sf::seconds(1) };
struct Anim
{
pl::Animation::Text fadeIn;
pl::Animation::Text flash;
pl::Animation::Text rotateIn;
pl::Animation::Text rollIn;
pl::Animation::Text zoomOutDown;
pl::Animation::Text bounce;
} anim;
// fade in
anim.fadeIn.color.addKeyA(sf::Time::Zero, 0);
anim.fadeIn.color.addKey(duration, sf::Color::White);
// flash
anim.flash.color.addKey(sf::Time::Zero, sf::Color::White);
anim.flash.color.addKeyA(duration / 4.f, 0);
anim.flash.color.addKeyA(duration / 2.f, 255);
anim.flash.color.addKeyA(duration / 4.f * 3.f, 0);
anim.flash.color.addKeyA(duration, 255);
// rotate in
anim.rotateIn.color.addKeyA(sf::Time::Zero, 0);
anim.rotateIn.color.addKey(duration, sf::Color::White);
anim.rotateIn.rotation.addKey(sf::Time::Zero, -180);
anim.rotateIn.rotation.addKey(duration, 0, 1.f, 0.f);
// roll in
anim.rollIn.color.addKeyA(sf::Time::Zero, 0);
anim.rollIn.color.addKey(duration, sf::Color::White);
anim.rollIn.rotation.addKey(sf::Time::Zero, -180);
anim.rollIn.rotation.addKey(duration, 0, 1.f, 0.f);
anim.rollIn.position.addKey(sf::Time::Zero, { -400.f, 0.f });
anim.rollIn.position.addKeyX(duration, 0.f, 1.f, 0.f);
// zoom out down
anim.zoomOutDown.color.addKey(duration / 2.f, sf::Color::White);
anim.zoomOutDown.color.addKeyA(duration, 0);
anim.zoomOutDown.scale.addKey(sf::Time::Zero, { 1.f, 1.f }, 0.f, 0.5f);
anim.zoomOutDown.scale.addKey(duration / 2.f, { 0.5f, 0.5f }, 0.5f, 0.f);
anim.zoomOutDown.position.addKey(sf::Time::Zero, { 0.f, 0.f }, 0.f, 0.5f);
anim.zoomOutDown.position.addKeyY(duration / 2.f, -70.f, 0.5f, 1.f);
anim.zoomOutDown.position.addKeyY(duration, 400.f);
// bounce
anim.bounce.position.addKey(sf::Time::Zero, { 0.f, 0.f }, 0.f, 0.5f);
anim.bounce.position.addKeyY(duration * 0.2f, -100.f, 0.5f, 0.f);
anim.bounce.position.addKeyY(duration * 0.35f, -100.f, 0.f, 1.f);
anim.bounce.position.addKeyY(duration * 0.55f, 0.f);
anim.bounce.position.addKeyY(duration * 0.75f, -40.f, 0.5f, 0.5f);
anim.bounce.position.addKeyY(duration * 0.85f, 0.f);
anim.bounce.position.addKeyY(duration * 0.925f, -15.f, 0.5f, 0.5f);
anim.bounce.position.addKeyY(duration, 0.f);
enum class AnimState
{
None,
FadeIn,
Flash,
RotateIn,
RollIn,
ZoomOutDown,
Bounce,
} animState{ AnimState::None };
sf::Clock clock;
sf::Time startTime;
sf::RenderWindow window(sf::VideoMode(800, 600), "Mini Animations");
const sf::Vector2f windowCenter(window.getSize() / 2u);
text.setPosition(windowCenter);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
else if (event.type == sf::Event::KeyPressed)
{
// only allow starting an animation if none is currently active
if (animState == AnimState::None)
{
startTime = clock.getElapsedTime();
if (event.key.code == sf::Keyboard::Key::Num1)
animState = AnimState::FadeIn;
else if (event.key.code == sf::Keyboard::Key::Num2)
animState = AnimState::Flash;
else if (event.key.code == sf::Keyboard::Key::Num3)
animState = AnimState::RotateIn;
else if (event.key.code == sf::Keyboard::Key::Num4)
animState = AnimState::RollIn;
else if (event.key.code == sf::Keyboard::Key::Num5)
animState = AnimState::ZoomOutDown;
else if (event.key.code == sf::Keyboard::Key::Num6)
animState = AnimState::Bounce;
}
}
}
if (animState != AnimState::None)
{
const sf::Time animTime{ clock.getElapsedTime() - startTime };
// use only the animation track for the current animation and manipulate only the tracks required
switch (animState)
{
case AnimState::FadeIn:
text.setFillColor(anim.fadeIn.color.get(animTime));
break;
case AnimState::Flash:
text.setFillColor(anim.flash.color.get(animTime));
break;
case AnimState::RotateIn:
text.setFillColor(anim.rotateIn.color.get(animTime));
text.setRotation(anim.rotateIn.rotation.get(animTime));
break;
case AnimState::RollIn:
text.setFillColor(anim.rollIn.color.get(animTime));
text.setRotation(anim.rollIn.rotation.get(animTime));
text.setPosition(windowCenter + anim.rollIn.position.get(animTime));
break;
case AnimState::ZoomOutDown:
text.setFillColor(anim.zoomOutDown.color.get(animTime));
text.setScale(anim.zoomOutDown.scale.get(animTime));
text.setPosition(windowCenter + anim.zoomOutDown.position.get(animTime));
break;
case AnimState::Bounce:
text.setPosition(windowCenter + anim.bounce.position.get(animTime));
break;
default:
; // do nothing
}
if (animTime > duration)
{
// reset animState
animState = AnimState::None;
// reset text object
text.setPosition(windowCenter);
text.setScale({ 1.f, 1.f });
text.setFillColor(sf::Color::White);
text.setRotation(0.f);
}
}
window.clear();
window.draw(infoText);
window.draw(text);
window.display();
}
return EXIT_SUCCESS;
}
Here's a video of this code in action: