Improve reaction scale animation.

This commit is contained in:
John Preston 2022-01-07 15:33:55 +03:00
parent cfc2a959cf
commit f98c08f4c6
2 changed files with 37 additions and 27 deletions

View file

@ -1021,10 +1021,7 @@ void Manager::paintAllEmoji(
const auto skip = st::reactionAppearStartSkip; const auto skip = st::reactionAppearStartSkip;
const auto animationRect = clip.marginsRemoved({ 0, skip, 0, skip }); const auto animationRect = clip.marginsRemoved({ 0, skip, 0, skip });
auto hq = std::optional<PainterHighQualityEnabler>(); PainterHighQualityEnabler hq(p);
if (scale != 1. && scale != kHoverScale) {
hq.emplace(p);
}
const auto between = st::reactionCornerSkip; const auto between = st::reactionCornerSkip;
const auto oneHeight = st::reactionCornerSize.height() + between; const auto oneHeight = st::reactionCornerSize.height() + between;
const auto finalSize = CornerImageSize(1.); const auto finalSize = CornerImageSize(1.);
@ -1061,25 +1058,18 @@ void Manager::paintAllEmoji(
const auto target = countTarget(icon).translated(emojiPosition); const auto target = countTarget(icon).translated(emojiPosition);
emojiPosition += shift; emojiPosition += shift;
const auto paintFrame = [&](not_null<Lottie::Icon*> animation) {
const auto size = int(std::floor(target.width() + 0.01));
const auto frame = animation->frame({ size, size }, update);
p.drawImage(target, frame.image);
};
if (!target.intersects(clip)) { if (!target.intersects(clip)) {
if (current) { if (current) {
if (const auto appear = icon.appear.get()) { clearStateForHidden(icon);
appear->jumpTo(0, nullptr);
}
if (icon.selected) {
setSelectedIcon(-1);
}
icon.appearAnimated = false;
icon.selectAnimated = false;
if (const auto select = icon.select.get()) {
select->jumpTo(0, nullptr);
}
icon.selectedScale.stop();
} }
} else if (icon.select && icon.select->animating()) { } else if (icon.select && icon.select->animating()) {
const auto size = int(base::SafeRound(target.width())); paintFrame(icon.select.get());
const auto frame = icon.select->frame({ size, size }, update);
p.drawImage(target, frame.image);
} else if (const auto appear = icon.appear.get()) { } else if (const auto appear = icon.appear.get()) {
if (current if (current
&& !icon.appearAnimated && !icon.appearAnimated
@ -1087,19 +1077,37 @@ void Manager::paintAllEmoji(
icon.appearAnimated = true; icon.appearAnimated = true;
appear->animate(update, 0, appear->framesCount() - 1); appear->animate(update, 0, appear->framesCount() - 1);
} }
const auto size = int(base::SafeRound(target.width())); paintFrame(appear);
const auto frame = appear->frame({ size, size }, update);
p.drawImage(target, frame.image);
} }
if (current if (current) {
&& icon.selectAnimated clearStateForSelectFinished(icon);
&& !icon.select->animating()
&& !icon.selected) {
icon.selectAnimated = false;
} }
} }
} }
void Manager::clearStateForHidden(ReactionIcons &icon) {
if (const auto appear = icon.appear.get()) {
appear->jumpTo(0, nullptr);
}
if (icon.selected) {
setSelectedIcon(-1);
}
icon.appearAnimated = false;
icon.selectAnimated = false;
if (const auto select = icon.select.get()) {
select->jumpTo(0, nullptr);
}
icon.selectedScale.stop();
}
void Manager::clearStateForSelectFinished(ReactionIcons &icon) {
if (icon.selectAnimated
&& !icon.select->animating()
&& !icon.selected) {
icon.selectAnimated = false;
}
}
void Manager::applyPatternedShadow(const QColor &shadow) { void Manager::applyPatternedShadow(const QColor &shadow) {
if (_shadow == shadow) { if (_shadow == shadow) {
return; return;

View file

@ -221,6 +221,8 @@ private:
void setBackground(const QColor &background); void setBackground(const QColor &background);
void setSelectedIcon(int index) const; void setSelectedIcon(int index) const;
void clearStateForHidden(ReactionIcons &icon);
void clearStateForSelectFinished(ReactionIcons &icon);
[[nodiscard]] QMargins innerMargins() const; [[nodiscard]] QMargins innerMargins() const;
[[nodiscard]] QRect buttonInner() const; [[nodiscard]] QRect buttonInner() const;