Added first state to snowflakes effect in main menu.

This commit is contained in:
23rd 2022-12-21 17:02:40 +03:00 committed by John Preston
parent 2364b0ad4e
commit 8296d72923
5 changed files with 41 additions and 14 deletions

View file

@ -74,33 +74,37 @@ namespace {
} // namespace } // namespace
Snowflakes::Snowflakes(Fn<void(const QRect &r)> updateCallback) Snowflakes::Snowflakes(Fn<void(const QRect &r)> updateCallback)
: _lifeLength({ 300, 100 }) : _lifeLength({ 300 * 2, 100 * 2 })
, _deathTime({ 2000, 100 }) , _deathTime({ 2000 * 5, 100 * 5 })
, _scale({ 60, 100 }) , _scale({ 60, 100 })
, _velocity({ 20, 4 }) , _velocity({ 20 * 7, 4 * 7 })
, _angle({ 70, 40 }) , _angle({ 70, 40 })
, _relativeX({ 0, 100 }) , _relativeX({ 0, 100 })
, _relativeY({ -10, 70 })
, _appearProgressTill(200. / _deathTime.from) , _appearProgressTill(200. / _deathTime.from)
, _disappearProgressAfter(_appearProgressTill) , _disappearProgressAfter(_appearProgressTill)
, _dotMargins(3., 3., 3., 3.) , _dotMargins(3., 3., 3., 3.)
, _renderMargins(1., 1., 1., 1.) , _renderMargins(1., 1., 1., 1.)
, _animation([=](crl::time now) { , _animation([=](crl::time now) {
if (now > _nextBirthTime && !_paused) { if (now > _nextBirthTime && !_paused.at) {
createParticle(now); createParticle(now);
} }
if (_rectToUpdate.isValid()) { if (_rectToUpdate.isValid()) {
updateCallback(base::take(_rectToUpdate)); updateCallback(base::take(_rectToUpdate));
} }
}) { }) {
if (anim::Disabled()) { {
const auto from = _deathTime.from + _deathTime.length; const auto from = _deathTime.from + _deathTime.length;
auto r = bytes::vector(from); auto r = bytes::vector(from);
base::RandomFill(r.data(), r.size()); base::RandomFill(r.data(), r.size());
const auto now = crl::now();
for (auto i = -from; i < 0; i += randomInterval(_lifeLength, r[-i])) { for (auto i = -from; i < 0; i += randomInterval(_lifeLength, r[-i])) {
createParticle(i); createParticle(now + i);
} }
updateCallback(_rectToUpdate); updateCallback(_rectToUpdate);
} else { }
if (!anim::Disabled()) {
_animation.start(); _animation.start();
} }
} }
@ -112,7 +116,7 @@ int Snowflakes::randomInterval(
} }
crl::time Snowflakes::timeNow() const { crl::time Snowflakes::timeNow() const {
return anim::Disabled() ? 0 : crl::now(); return _paused.at ? _paused.at : (crl::now() - _paused.diff);
} }
void Snowflakes::paint(QPainter &p, const QRectF &rect) { void Snowflakes::paint(QPainter &p, const QRectF &rect) {
@ -121,8 +125,9 @@ void Snowflakes::paint(QPainter &p, const QRectF &rect) {
PainterHighQualityEnabler hq(p); PainterHighQualityEnabler hq(p);
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
p.setBrush(_brush); p.setBrush(_brush);
const auto now = timeNow();
for (const auto &particle : _particles) { for (const auto &particle : _particles) {
const auto progress = (timeNow() - particle.birthTime) const auto progress = (now - particle.birthTime)
/ float64(particle.deathTime - particle.birthTime); / float64(particle.deathTime - particle.birthTime);
if (progress > 1.) { if (progress > 1.) {
continue; continue;
@ -162,7 +167,14 @@ void Snowflakes::paint(QPainter &p, const QRectF &rect) {
} }
void Snowflakes::setPaused(bool paused) { void Snowflakes::setPaused(bool paused) {
_paused = paused; paused |= anim::Disabled();
if (paused) {
_paused.diff = 0;
_paused.at = crl::now();
} else {
_paused.diff = _paused.at ? (crl::now() - _paused.at) : 0;
_paused.at = 0;
}
} }
void Snowflakes::setBrush(QBrush brush) { void Snowflakes::setBrush(QBrush brush) {
@ -171,7 +183,7 @@ void Snowflakes::setBrush(QBrush brush) {
} }
void Snowflakes::createParticle(crl::time now) { void Snowflakes::createParticle(crl::time now) {
constexpr auto kRandomSize = 8; constexpr auto kRandomSize = 9;
auto random = bytes::vector(kRandomSize); auto random = bytes::vector(kRandomSize);
base::RandomFill(random.data(), random.size()); base::RandomFill(random.data(), random.size());
@ -187,7 +199,7 @@ void Snowflakes::createParticle(crl::time now) {
.deathTime = now + randomInterval(_deathTime, next()), .deathTime = now + randomInterval(_deathTime, next()),
.scale = float64(randomInterval(_scale, next())) / 100., .scale = float64(randomInterval(_scale, next())) / 100.,
.relativeX = float64(randomInterval(_relativeX, next())) / 100., .relativeX = float64(randomInterval(_relativeX, next())) / 100.,
.relativeY = float64(randomInterval(_relativeX, next())) / 100., .relativeY = float64(randomInterval(_relativeY, next())) / 100.,
.velocityX = std::cos(M_PI / 180. * angle) * velocity, .velocityX = std::cos(M_PI / 180. * angle) * velocity,
.velocityY = std::sin(M_PI / 180. * angle) * velocity, .velocityY = std::sin(M_PI / 180. * angle) * velocity,
.type = ((uchar(next()) % 2) == 1 ? Type::Snowflake : Type::Dot), .type = ((uchar(next()) % 2) == 1 ? Type::Snowflake : Type::Dot),

View file

@ -54,6 +54,7 @@ private:
const Interval _velocity; const Interval _velocity;
const Interval _angle; const Interval _angle;
const Interval _relativeX; const Interval _relativeX;
const Interval _relativeY;
const float64 _appearProgressTill; const float64 _appearProgressTill;
const float64 _disappearProgressAfter; const float64 _disappearProgressAfter;
@ -66,7 +67,10 @@ private:
std::vector<Particle> _particles; std::vector<Particle> _particles;
crl::time _nextBirthTime = 0; crl::time _nextBirthTime = 0;
bool _paused = false; struct {
crl::time diff = 0;
crl::time at = 0;
} _paused;
QBrush _brush; QBrush _brush;
QRect _rectToUpdate; QRect _rectToUpdate;

View file

@ -492,6 +492,10 @@ MainMenu::MainMenu(
const auto snow = snowLifetime->make_state<Ui::Snowflakes>( const auto snow = snowLifetime->make_state<Ui::Snowflakes>(
[=](const QRect &r) { snowRaw->update(r); }); [=](const QRect &r) { snowRaw->update(r); });
snow->setBrush(QColor(230, 230, 230)); snow->setBrush(QColor(230, 230, 230));
_showFinished.value(
) | rpl::start_with_next([=](bool shown) {
snow->setPaused(!shown);
}, snowRaw->lifetime());
snowRaw->paintRequest( snowRaw->paintRequest(
) | rpl::start_with_next([=](const QRect &r) { ) | rpl::start_with_next([=](const QRect &r) {
auto p = Painter(snowRaw); auto p = Painter(snowRaw);
@ -694,6 +698,10 @@ void MainMenu::parentResized() {
resize(st::mainMenuWidth, parentWidget()->height()); resize(st::mainMenuWidth, parentWidget()->height());
} }
void MainMenu::showFinished() {
_showFinished = true;
}
void MainMenu::setupMenu() { void MainMenu::setupMenu() {
using namespace Settings; using namespace Settings;

View file

@ -47,6 +47,7 @@ public:
~MainMenu(); ~MainMenu();
void parentResized() override; void parentResized() override;
void showFinished() override;
protected: protected:
void paintEvent(QPaintEvent *e) override; void paintEvent(QPaintEvent *e) override;
@ -98,6 +99,8 @@ private:
base::Timer _nightThemeSwitch; base::Timer _nightThemeSwitch;
base::unique_qptr<Ui::PopupMenu> _contextMenu; base::unique_qptr<Ui::PopupMenu> _contextMenu;
rpl::variable<bool> _showFinished = false;
}; };
struct OthersUnreadState { struct OthersUnreadState {

@ -1 +1 @@
Subproject commit 07d9420c19c008f9b49faaabde3e7d2139255961 Subproject commit 9f5ddf3d8aaa95e0c32c187f7e8b6c3239953991