bool CompositorAnimations::getAnimatedBoundingBox(FloatBox& box, const AnimationEffect& effect, double minValue, double maxValue) const { const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(effect); PropertySet properties = keyframeEffect.properties(); if (properties.isEmpty()) return true; minValue = std::min(minValue, 0.0); maxValue = std::max(maxValue, 1.0); for (const auto& property : properties) { // TODO: Add the ability to get expanded bounds for filters as well. if (property != CSSPropertyTransform && property != CSSPropertyWebkitTransform) continue; const PropertySpecificKeyframeVector& frames = keyframeEffect.getPropertySpecificKeyframes(property); if (frames.isEmpty() || frames.size() < 2) continue; FloatBox originalBox(box); for (size_t j = 0; j < frames.size() - 1; ++j) { const AnimatableTransform* startTransform = toAnimatableTransform(frames[j]->getAnimatableValue().get()); const AnimatableTransform* endTransform = toAnimatableTransform(frames[j+1]->getAnimatableValue().get()); if (!startTransform || !endTransform) return false; // TODO: Add support for inflating modes other than Replace. if (frames[j]->composite() != AnimationEffect::CompositeReplace) return false; const TimingFunction& timing = frames[j]->easing(); double min = 0; double max = 1; if (j == 0) { float frameLength = frames[j+1]->offset(); if (frameLength > 0) { min = minValue / frameLength; } } if (j == frames.size() - 2) { float frameLength = frames[j+1]->offset() - frames[j]->offset(); if (frameLength > 0) { max = 1 + (maxValue - 1) / frameLength; } } FloatBox bounds; timing.range(&min, &max); if (!endTransform->transformOperations().blendedBoundsForBox(originalBox, startTransform->transformOperations(), min, max, &bounds)) return false; box.expandTo(bounds); } } return true; }
bool AnimationStack::getAnimatedBoundingBox(FloatBox& box, CSSPropertyID property) const { FloatBox originalBox(box); for (const auto& sampledEffect : m_effects) { if (sampledEffect->effect() && sampledEffect->effect()->affects(PropertyHandle(property))) { KeyframeEffect* effect = sampledEffect->effect(); const Timing& timing = effect->specifiedTiming(); double startRange = 0; double endRange = 1; timing.timingFunction->range(&startRange, &endRange); FloatBox expandingBox(originalBox); if (!CompositorAnimations::instance()->getAnimatedBoundingBox(expandingBox, *effect->model(), startRange, endRange)) return false; box.expandTo(expandingBox); } } return true; }