Bug 1272549 - Part 3: Calculate the percent value of translation and the factor of scale.
Add one more argument, nsIFrame, in ComputeDistance, so we can get the size of
transform reference box.
MozReview-Commit-ID: CMx4sbFzhk9
--- a/dom/animation/KeyframeEffectReadOnly.cpp
+++ b/dom/animation/KeyframeEffectReadOnly.cpp
@@ -260,16 +260,17 @@ KeyframeEffectReadOnly::UpdateProperties
nsTArray<ComputedKeyframeValues> computedValues =
KeyframeUtils::GetComputedKeyframeValues(keyframesCopy,
mTarget->mElement,
aStyleContext);
if (mEffectOptions.mSpacingMode == SpacingMode::paced) {
KeyframeUtils::ApplySpacing(keyframesCopy, SpacingMode::paced,
mEffectOptions.mPacedProperty,
+ mTarget->mElement->GetPrimaryFrame(),
computedValues);
}
properties =
KeyframeUtils::GetAnimationPropertiesFromKeyframes(keyframesCopy,
computedValues,
aStyleContext);
--- a/dom/animation/KeyframeUtils.cpp
+++ b/dom/animation/KeyframeUtils.cpp
@@ -411,17 +411,18 @@ static void
DistributeRange(const Range<Keyframe>& aSpacingRange);
static void
PaceRange(const Range<Keyframe>& aKeyframes,
const Range<double>& aCumulativeDistances);
static nsTArray<double>
GetCumulativeDistances(const nsTArray<ComputedKeyframeValues>& aValues,
- nsCSSPropertyID aProperty);
+ nsCSSPropertyID aProperty,
+ nsIFrame* aFrame);
// ------------------------------------------------------------------
//
// Public API
//
// ------------------------------------------------------------------
/* static */ nsTArray<Keyframe>
@@ -475,28 +476,30 @@ KeyframeUtils::GetKeyframesFromObject(JS
return keyframes;
}
/* static */ void
KeyframeUtils::ApplySpacing(nsTArray<Keyframe>& aKeyframes,
SpacingMode aSpacingMode,
nsCSSPropertyID aProperty,
+ nsIFrame* aFrame,
nsTArray<ComputedKeyframeValues>& aComputedValues)
{
if (aKeyframes.IsEmpty()) {
return;
}
nsTArray<double> cumulativeDistances;
if (aSpacingMode == SpacingMode::paced) {
MOZ_ASSERT(IsAnimatableProperty(aProperty),
"Paced property should be animatable");
- cumulativeDistances = GetCumulativeDistances(aComputedValues, aProperty);
+ cumulativeDistances = GetCumulativeDistances(aComputedValues, aProperty,
+ aFrame);
// Reset the computed offsets if using paced spacing.
for (Keyframe& keyframe : aKeyframes) {
keyframe.mComputedOffset = Keyframe::kComputedOffsetNotSet;
}
}
// If the first keyframe has an unspecified offset, fill it in with 0%.
// If there is only a single keyframe, then it gets 100%.
@@ -577,17 +580,17 @@ KeyframeUtils::ApplySpacing(nsTArray<Key
}
}
/* static */ void
KeyframeUtils::ApplyDistributeSpacing(nsTArray<Keyframe>& aKeyframes)
{
nsTArray<ComputedKeyframeValues> emptyArray;
ApplySpacing(aKeyframes, SpacingMode::distribute, eCSSProperty_UNKNOWN,
- emptyArray);
+ nullptr, emptyArray);
}
/* static */ nsTArray<ComputedKeyframeValues>
KeyframeUtils::GetComputedKeyframeValues(const nsTArray<Keyframe>& aKeyframes,
dom::Element* aElement,
nsStyleContext* aStyleContext)
{
MOZ_ASSERT(aStyleContext);
@@ -1558,22 +1561,24 @@ PaceRange(const Range<Keyframe>& aKeyfra
}
}
/**
* Get cumulative distances for the paced property.
*
* @param aValues The computed values returned by GetComputedKeyframeValues.
* @param aPacedProperty The paced property.
+ * @param aFrame The frame used to calculate the spacing on transform property.
* @return The cumulative distances for the paced property. The length will be
* the same as aValues.
*/
static nsTArray<double>
GetCumulativeDistances(const nsTArray<ComputedKeyframeValues>& aValues,
- nsCSSPropertyID aPacedProperty)
+ nsCSSPropertyID aPacedProperty,
+ nsIFrame* aFrame)
{
// a) If aPacedProperty is a shorthand property, get its components.
// Otherwise, just add the longhand property into the set.
size_t pacedPropertyCount = 0;
nsCSSPropertyIDSet pacedPropertySet;
bool isShorthand = nsCSSProps::IsShorthand(aPacedProperty);
if (isShorthand) {
CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p, aPacedProperty,
@@ -1631,29 +1636,31 @@ GetCumulativeDistances(const nsTArray<Co
MOZ_ASSERT(pacedValues[propIdx].mProperty == prop,
"Property mismatch");
double componentDistance = 0.0;
if (StyleAnimationValue::ComputeDistance(
prop,
prevPacedValues[propIdx].mValue,
pacedValues[propIdx].mValue,
+ aFrame,
componentDistance)) {
dist += componentDistance * componentDistance;
}
}
dist = sqrt(dist);
} else {
// If the property is longhand, we just use the 1st value.
// If ComputeDistance() fails, |dist| will remain zero so there will be
// no distance between the previous paced value and this value.
Unused <<
StyleAnimationValue::ComputeDistance(aPacedProperty,
prevPacedValues[0].mValue,
pacedValues[0].mValue,
+ aFrame,
dist);
}
cumulativeDistances[i] = cumulativeDistances[preIdx] + dist;
}
prevPacedValues.SwapElements(pacedValues);
preIdx = i;
}
return cumulativeDistances;
--- a/dom/animation/KeyframeUtils.h
+++ b/dom/animation/KeyframeUtils.h
@@ -89,24 +89,27 @@ public:
*
* https://w3c.github.io/web-animations/#spacing-keyframes
*
* @param aKeyframes The set of keyframes to adjust.
* @param aSpacingMode The spacing mode to apply.
* @param aProperty The paced property. Only used when |aSpacingMode| is
* SpacingMode::paced. In all other cases it is ignored and hence may be
* any value, e.g. eCSSProperty_UNKNOWN.
+ * @param aFrame The primary frame of the current target for calculating paced
+ * animation on transform property.
* @param aComputedValues The set of computed keyframe values as returned by
* GetComputedKeyframeValues. Only used when |aSpacingMode| is
* SpacingMode::paced. In all other cases this parameter is unused and may
* be any value including an empty array.
*/
static void ApplySpacing(nsTArray<Keyframe>& aKeyframes,
SpacingMode aSpacingMode,
nsCSSPropertyID aProperty,
+ nsIFrame* aFrame,
nsTArray<ComputedKeyframeValues>& aComputedValues);
/**
* Wrapper for ApplySpacing to simplify using distribute spacing.
*
* @param aKeyframes The set of keyframes to adjust.
*/
static void ApplyDistributeSpacing(nsTArray<Keyframe>& aKeyframes);
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2704,17 +2704,18 @@ nsDOMWindowUtils::ComputeAnimationDistan
StyleAnimationValue v1, v2;
if (property == eCSSProperty_UNKNOWN ||
!ComputeAnimationValue(property, content->AsElement(), aValue1, v1) ||
!ComputeAnimationValue(property, content->AsElement(), aValue2, v2)) {
return NS_ERROR_ILLEGAL_VALUE;
}
- if (!StyleAnimationValue::ComputeDistance(property, v1, v2, *aResult)) {
+ if (!StyleAnimationValue::ComputeDistance(property, v1, v2, nullptr,
+ *aResult)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
nsDOMWindowUtils::RenderDocument(const nsRect& aRect,
--- a/dom/smil/nsSMILCSSValueType.cpp
+++ b/dom/smil/nsSMILCSSValueType.cpp
@@ -273,16 +273,17 @@ nsSMILCSSValueType::ComputeDistance(cons
&fromWrapper->mCSSValue : nullptr;
const StyleAnimationValue* toCSSValue = &toWrapper->mCSSValue;
if (!FinalizeStyleAnimationValues(fromCSSValue, toCSSValue)) {
return NS_ERROR_FAILURE;
}
return StyleAnimationValue::ComputeDistance(toWrapper->mPropID,
*fromCSSValue, *toCSSValue,
+ nullptr,
aDistance) ?
NS_OK : NS_ERROR_FAILURE;
}
nsresult
nsSMILCSSValueType::Interpolate(const nsSMILValue& aStartVal,
const nsSMILValue& aEndVal,
double aUnitDistance,
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -715,17 +715,18 @@ StyleAnimationValue::ComputeColorDistanc
double diffR = startR - endR;
double diffG = startG - endG;
double diffB = startB - endB;
return sqrt(diffA * diffA + diffR * diffR + diffG * diffG + diffB * diffB);
}
static double
ComputeTransformDistance(nsCSSValue::Array* aArray1,
- nsCSSValue::Array* aArray2)
+ nsCSSValue::Array* aArray2,
+ nsIFrame* aFrame)
{
if (!aArray1 || !aArray2) {
return 0.0;
}
RefPtr<nsCSSValue::Array> a1 = ToPrimitive(aArray1),
a2 = ToPrimitive(aArray2);
nsCSSKeyword tfunc = nsStyleTransformMatrix::TransformFunctionOf(a1);
@@ -736,21 +737,38 @@ ComputeTransformDistance(nsCSSValue::Arr
case eCSSKeyword_translate3d: {
MOZ_ASSERT(a1->Count() == 4, "unexpected count");
MOZ_ASSERT(a2->Count() == 4, "unexpected count");
nsCSSValue x, y, z;
AddTransformTranslate(1.0, a2->Item(1), -1.0, a1->Item(1), x);
AddTransformTranslate(1.0, a2->Item(2), -1.0, a1->Item(2), y);
AddTransformTranslate(1.0, a2->Item(3), -1.0, a1->Item(3), z);
- // TODO: Calculate the percent part. This will be fixed in the next patch.
- // Drop percent part because we cannot calculate it now.
+
+ // Initialize them without percent part.
double c1 = ExtractCalcValue(x).mLength;
double c2 = ExtractCalcValue(y).mLength;
double c3 = z.GetFloatValue();
+ if (aFrame) {
+ using namespace nsStyleTransformMatrix;
+ TransformReferenceBox refBox(aFrame);
+ RuleNodeCacheConditions dontCare;
+ c1 = ProcessTranslatePart(x,
+ aFrame->StyleContext(),
+ aFrame->PresContext(),
+ dontCare,
+ &refBox,
+ &TransformReferenceBox::Width);
+ c2 = ProcessTranslatePart(y,
+ aFrame->StyleContext(),
+ aFrame->PresContext(),
+ dontCare,
+ &refBox,
+ &TransformReferenceBox::Height);
+ }
distance = c1 * c1 + c2 * c2 + c3 * c3;
break;
}
case eCSSKeyword_scale3d: {
MOZ_ASSERT(a1->Count() == 4, "unexpected count");
MOZ_ASSERT(a2->Count() == 4, "unexpected count");
auto ComputeScaleDiff = [](const nsCSSValue& aValue1,
@@ -835,32 +853,35 @@ ComputeTransformDistance(nsCSSValue::Arr
MOZ_ASSERT_UNREACHABLE("Unsupported transform function");
break;
}
return distance;
}
static double
ComputeTransformListDistance(const nsCSSValueList* aList1,
- const nsCSSValueList* aList2)
+ const nsCSSValueList* aList2,
+ nsIFrame* aFrame)
{
double distance = 0.0;
do {
distance += ComputeTransformDistance(aList1->mValue.GetArrayValue(),
- aList2->mValue.GetArrayValue());
+ aList2->mValue.GetArrayValue(),
+ aFrame);
aList1 = aList1->mNext;
aList2 = aList2->mNext;
} while (aList1);
return sqrt(distance);
}
bool
StyleAnimationValue::ComputeDistance(nsCSSPropertyID aProperty,
const StyleAnimationValue& aStartValue,
const StyleAnimationValue& aEndValue,
+ nsIFrame* aFrame,
double& aDistance)
{
Unit commonUnit =
GetCommonUnit(aProperty, aStartValue.GetUnit(), aEndValue.GetUnit());
switch (commonUnit) {
case eUnit_Null:
case eUnit_Auto:
@@ -1271,17 +1292,17 @@ StyleAnimationValue::ComputeDistance(nsC
if (item1 || item2) {
// Either |break| above or length mismatch.
// TODO: Implement this for mismatched transform function in the later
// patch.
aDistance = 0.0;
return false;
} else {
- aDistance = ComputeTransformListDistance(list1, list2);
+ aDistance = ComputeTransformListDistance(list1, list2, aFrame);
}
}
return true;
}
case eUnit_BackgroundPositionCoord: {
const nsCSSValueList *position1 = aStartValue.GetCSSValueListValue();
const nsCSSValueList *position2 = aEndValue.GetCSSValueListValue();
--- a/layout/style/StyleAnimationValue.h
+++ b/layout/style/StyleAnimationValue.h
@@ -89,16 +89,17 @@ public:
* should be calculated.
* @param aDistance The result of the calculation.
* @return true on success, false on failure.
*/
static MOZ_MUST_USE bool
ComputeDistance(nsCSSPropertyID aProperty,
const StyleAnimationValue& aStartValue,
const StyleAnimationValue& aEndValue,
+ nsIFrame* aFrame,
double& aDistance);
/**
* Calculates an interpolated value that is the specified |aPortion| between
* the two given values.
*
* This really just does the following calculation:
* aResultValue = (1.0 - aPortion) * aStartValue + aPortion * aEndValue