blob: 03d206c2d35aae98e99d70fe95b896be895becfa [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/animationworklet/worklet_animation_effect.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_computed_effect_timing.h"
#include "third_party/blink/renderer/core/animation/timing_calculations.h"
namespace blink {
WorkletAnimationEffect::WorkletAnimationEffect(
base::Optional<base::TimeDelta> local_time,
const Timing& specified_timing)
: local_time_(local_time),
specified_timing_(specified_timing),
calculated_() {
specified_timing_.AssertValid();
}
EffectTiming* WorkletAnimationEffect::getTiming() const {
return specified_timing_.ConvertToEffectTiming();
}
ComputedEffectTiming* WorkletAnimationEffect::getComputedTiming() const {
base::Optional<double> local_time;
if (local_time_)
local_time = base::Optional<double>(local_time_.value().InSecondsF());
bool needs_update = last_update_time_ != local_time;
last_update_time_ = local_time;
if (needs_update) {
// The playback rate is needed to calculate whether the effect is current or
// not (https://drafts.csswg.org/web-animations-1/#current). Since we only
// use this information to create a ComputedEffectTiming, which does not
// include that information, we do not need to supply one.
base::Optional<double> playback_rate = base::nullopt;
calculated_ = specified_timing_.CalculateTimings(
local_time, base::nullopt, Timing::AnimationDirection::kForwards, false,
playback_rate);
}
return specified_timing_.getComputedTiming(calculated_,
/*is_keyframe_effect*/ false);
}
base::Optional<double> WorkletAnimationEffect::localTime() const {
if (!local_time_)
return base::nullopt;
return local_time_.value().InMillisecondsF();
}
void WorkletAnimationEffect::setLocalTime(base::Optional<double> time_ms) {
if (!time_ms) {
local_time_.reset();
return;
}
DCHECK(!std::isnan(time_ms.value()));
// Convert double to base::TimeDelta because cc/animation expects
// base::TimeDelta.
//
// Note on precision loss: base::TimeDelta has microseconds precision which is
// also the precision recommended by the web animation specification as well
// [1]. If the input time value has a bigger precision then the conversion
// causes precision loss. Doing the conversion here ensures that reading the
// value back provides the actual value we use in further computation which
// is the least surprising path.
// [1] https://drafts.csswg.org/web-animations/#precision-of-time-values
local_time_ = base::TimeDelta::FromMillisecondsD(time_ms.value());
}
base::Optional<base::TimeDelta> WorkletAnimationEffect::local_time() const {
return local_time_;
}
} // namespace blink