Closed
Bug 523355
Opened 15 years ago
Closed 15 years ago
implement animation of stroke-dasharray
Categories
(Core :: CSS Parsing and Computation, defect, P3)
Core
CSS Parsing and Computation
Tracking
()
RESOLVED
FIXED
mozilla1.9.3a1
People
(Reporter: dbaron, Assigned: dbaron)
References
(Blocks 1 open bug)
Details
Attachments
(1 file)
16.07 KB,
patch
|
dholbert
:
review+
bzbarsky
:
superreview+
|
Details | Diff | Splinter Review |
Since I was thinking about animation of stroke-dasharray in bug 523193 last night, I went ahead and implemented it. Does the SMIL code need to change to explicitly opt in to animating this property? Or does it pick it up automatically?
Attachment #407289 -
Flags: superreview?(bzbarsky)
Attachment #407289 -
Flags: review?(dholbert)
Comment 1•15 years ago
|
||
(In reply to comment #0) > Does the SMIL code need to change to explicitly opt in to animating this > property? Or does it pick it up automatically? Just nsSMILCSSProperty::IsPropertyAnimatable, to indicate that it's now animatable. nsSMILCSSValueType::Add() also needs to be tweaked to explicitly fail for stroke-dasharray, since it' an explicitly non-additive[1] property, and since the "GetZeroValueForUnit" helper function doesn't handle eUnit_Dasharray. [1] http://www.w3.org/TR/SVG/painting.html#StrokeDasharrayProperty
Comment 2•15 years ago
|
||
Comment on attachment 407289 [details] [diff] [review] patch Why do you need |list1 && list2| in the while condition if you've ensured the lengths are the same?
Attachment #407289 -
Flags: superreview?(bzbarsky) → superreview+
Updated•15 years ago
|
Attachment #407289 -
Flags: review?(dholbert) → review+
Comment 3•15 years ago
|
||
Comment on attachment 407289 [details] [diff] [review] patch > PRBool > nsStyleAnimation::ComputeDistance(const Value& aStartValue, [SNIP] >+ double diff; >+ switch (val1.GetUnit()) { >+ case eCSSUnit_Percent: >+ diff = val1.GetPercentValue() - val2.GetPercentValue(); >+ break; >+ case eCSSUnit_Number: >+ diff = val1.GetFloatValue() - val2.GetFloatValue(); >+ break; [SNIP] >+ distance += diff * diff; So, this chunk says a change from 10% to 40% is the same distance as a change from 10px to 40px, whereas in fact, this is generally not the case. (ASIDE: I guess ComputeDistance already has a similar issue for standard lengths... but this issue can't actually cause problems in paced-mode SMIL animations yet, because we'll bail of animations that mix percents with non-percents.) Anyway -- I think it's worth adding a FIXME note here that these two distances (Percent & Number) are on different scales, and that correctness would require that they be normalized so that their scales match. >@@ -361,16 +429,74 @@ nsStyleAnimation::AddWeighted(double aCo [SNIP] >+ NS_ABORT_IF_FALSE(v1.GetUnit() == eCSSUnit_Number || >+ v1.GetUnit() == eCSSUnit_Percent, "unexpected"); [SNIP] >+ if (v1.GetUnit() == eCSSUnit_Number) { [SNIP] >+ } else { >+ NS_ABORT_IF_FALSE(v1.GetUnit() == eCSSUnit_Percent, "unexpected"); That last NS_ABORT_IF_FALSE seems redundant, given that we've just recently asserted that it's a number or a percent. (Not a big deal, though -- maybe it's just there for extra clarity?) >@@ -743,16 +870,63 @@ nsStyleAnimation::ExtractComputedValue(n [SNIP] >+ switch (coord.GetUnit()) { >+ case eStyleUnit_Coord: >+ // Number means the same thing as length; we want to >+ // animate them the same way. Normalize both to number >+ // since it has more accuracy (float vs nscoord). >+ value.SetFloatValue(nsPresContext:: >+ AppUnitsToFloatCSSPixels(coord.GetCoordValue()), >+ eCSSUnit_Number); >+ break; >+ case eStyleUnit_Factor: >+ value.SetFloatValue(coord.GetFactorValue(), >+ eCSSUnit_Number); >+ break; No action items for this chunk, just a note: Interesting -- I'd been assuming that length-valued properties always ended up with eStyleUnit_Coord-unit values in their computed style, but I see now that they can also end up as Float values, too (at least, for properties recognized by SVG -- not sure about others). So anyway, we don't currently handle this correctly for simple length-valued properties -- I just filed Bug 523551 on that. >@@ -743,16 +870,63 @@ nsStyleAnimation::ExtractComputedValue(n >+ nsCSSValueList *item = new nsCSSValueList; [SNIP] >+ switch (coord.GetUnit()) { [SNIP] >+ default: >+ NS_ABORT_IF_FALSE(PR_FALSE, "unexpected unit"); >+ return PR_FALSE; >+ } >+ *resultTail = item; The 'default' switch case here will leak the memory allocated for |item|... We're probably not likely to hit that case, judging by the the NS_ABORT_IF_FALSE, but it might be worth using a nsAutoPtr for magical auto-cleanup. (Or alternately, you could just add an explicit "delete item;" to that case, before the return statement.) >+ const nsCSSValue &val1 = list1->mValue; >+ const nsCSSValue &val2 = list2->mValue; [SNIP] >+ const nsCSSValue& v1 = list1->mValue; >+ const nsCSSValue& v2 = list2->mValue; We should probably be consistent about placement of the "&" in declarations of references. r=dholbert with the above addressed.
Comment 4•15 years ago
|
||
(In reply to comment #3) > So, this chunk says a change from 10% to 40% is the same distance as a change > from 10px to 40px, whereas in fact, this is generally not the case. Sorry -- I should clarify this point a bit. What I'm saying is that this chunk added to ComputeDistance can technically cause incorrect behavior even before we support interpolation from percent to non-percent, in scenarios like the one below. <SCENARIO> Suppose we're doing a SMIL animation of the stroke-dasharray property, with calcMode="paced", across the following sequence of values: "10px, 10%" // "40px, 10%" // "20px, 20%". Since we're in paced mode, we'll call ComputeDistance to find the intermediate distances. The first distance is 30, and the second distance is 10, for a total distance of 40. So, we'll let the first interval occupy 3/4 of the duration, and we'll let the second interval occupy the final 1/4. This is supposed to produce an "even pace of change". However, if the <svg> element is huge (say, 1000px x 1000px), then the 10% --> 20% change is *actually* a 100px difference -- much larger than the other 10px -> 40px change. So in fact, the first interval should really take 3/13 of the duration, and the second should take the final 10/13. </SCENARIO> In any case -- I don't think it's worth trying to fix this particular issue in this patch -- hence the FIXME suggestion in comment 3. This can probably be fixed as part of bug 520234. (I'm actually not 100% sure that stroke-dasharray is even supposed to support calcMode="paced". The SVG spec says that paced mode is "only supported for values that define a linear numeric range". I assume this includes multi-dimensional numeric values, like rgb() and rect()... and a 'stroke-dasharray' value is really just a multidimensional numeric value, too, so I imagine it's supposed to be supported. Intuitively, I feel like anything that can be interpolated should be able to support paced-mode animation.) http://www.w3.org/TR/SVG11/animate.html#CalcModeAttribute
Assignee | ||
Comment 5•15 years ago
|
||
Yeah, I was aware the distance measure was not particularly sensible; the invariant I've been trying to maintain (which I should probably document) is that distance between a starting point and the interpolation result is proportional to the portion given to Interpolate, since transitions depends on that. Other than that, I haven't necessarily worried about keeping distances for different types of units on the same numeric scale because I don't know a reasonable way to do that.
>That last NS_ABORT_IF_FALSE seems redundant, given that we've just recently
>asserted that it's a number or a percent. (Not a big deal, though -- maybe
>it's just there for extra clarity?)
Yeah, though it's a decent distance away, so I'd sort of like to keep it for clarity.
Assignee | ||
Comment 6•15 years ago
|
||
(In reply to comment #3) > The 'default' switch case here will leak the memory allocated for |item|... > We're probably not likely to hit that case, judging by the the > NS_ABORT_IF_FALSE, but it might be worth using a nsAutoPtr for magical > auto-cleanup. (Or alternately, you could just add an explicit "delete item;" to > that case, before the return statement.) And, actually, there's a simpler fix here: link |item| into the list right after we allocate it, so that deleting |result| in that failure case will also delete |item|.
Assignee | ||
Comment 7•15 years ago
|
||
http://hg.mozilla.org/mozilla-central/rev/8fbbf4665e89
Status: ASSIGNED → RESOLVED
Closed: 15 years ago
Priority: -- → P3
Resolution: --- → FIXED
Target Milestone: --- → mozilla1.9.3a1
Assignee | ||
Updated•15 years ago
|
Blocks: css-transitions
You need to log in
before you can comment on or make changes to this bug.
Description
•