#include "ash/system/progress_indicator/progress_ring_pulse_animation.h"
#include <array>
#include "base/dcheck_is_on.h"
#include "base/notreached.h"
#include "ui/gfx/animation/tween.h"
#include "ui/gfx/scoped_animation_duration_scale_mode.h"
namespace ash {
namespace {
constexpr float kAnimationDurationInMs = 2331.f;
struct AnimationKeyFrame {
float fraction = 0.f;
float opacity = 0.f;
};
constexpr std::array<AnimationKeyFrame, 10> kAnimationKeyFrames = {{
{.fraction = 0.f, .opacity = 1.f},
{.fraction = 333.f / kAnimationDurationInMs, .opacity = 0.f},
{.fraction = 433.f / kAnimationDurationInMs, .opacity = 0.f},
{.fraction = 766.f / kAnimationDurationInMs, .opacity = 1.f},
{.fraction = 999.f / kAnimationDurationInMs, .opacity = 1.f},
{.fraction = 1332.f / kAnimationDurationInMs, .opacity = 0.f},
{.fraction = 1432.f / kAnimationDurationInMs, .opacity = 0.f},
{.fraction = 1765.f / kAnimationDurationInMs, .opacity = 1.f},
{.fraction = 1998.f / kAnimationDurationInMs, .opacity = 1.f},
{.fraction = 1.f, .opacity = 0.f}
}};
}
ProgressRingPulseAnimation::ProgressRingPulseAnimation()
: ProgressRingAnimation(Type::kPulse,
base::Milliseconds(kAnimationDurationInMs),
false) {
#if DCHECK_IS_ON()
constexpr size_t kAnimationKeyFramesCount = std::size(kAnimationKeyFrames);
DCHECK_GE(kAnimationKeyFramesCount, 2u);
for (size_t i = 0u; i < kAnimationKeyFramesCount; ++i) {
if (i == 0u) {
DCHECK_EQ(kAnimationKeyFrames[i].fraction, 0.f);
} else if (i == kAnimationKeyFramesCount - 1u) {
DCHECK_EQ(kAnimationKeyFrames[i].fraction, 1.f);
} else {
DCHECK_GT(kAnimationKeyFrames[i].fraction, 0.f);
DCHECK_LT(kAnimationKeyFrames[i].fraction, 1.f);
DCHECK_GT(kAnimationKeyFrames[i].fraction,
kAnimationKeyFrames[i - 1u].fraction);
}
}
#endif
}
ProgressRingPulseAnimation::~ProgressRingPulseAnimation() = default;
void ProgressRingPulseAnimation::UpdateAnimatableProperties(
double fraction,
float* start_position,
float* end_position,
float* outer_ring_opacity) {
*end_position = 1.f;
for (size_t i = 1u; i < std::size(kAnimationKeyFrames); ++i) {
if (fraction > kAnimationKeyFrames[i].fraction)
continue;
const AnimationKeyFrame& previous_key_frame = kAnimationKeyFrames[i - 1u];
const AnimationKeyFrame& target_key_frame = kAnimationKeyFrames[i];
fraction = (fraction - previous_key_frame.fraction) /
(target_key_frame.fraction - previous_key_frame.fraction);
*outer_ring_opacity = gfx::Tween::FloatValueBetween(
fraction, previous_key_frame.opacity,
target_key_frame.opacity);
return;
}
NOTREACHED();
}
}