Open fsoder opened 5 years ago
If you implement the gradient in canvas do Firefox and Chrome still disagree?
No, then they both produce blue (https://jsfiddle.net/agyxt2d1/).
Safari fills with yellow too. That is what I would expect. However, it is not good that SVG differs from Canvas.
@fsoder Are there more edge cases or is this the only one you've found so far?
fr
was new in SVG 2, and designed to match with canvas. But it's possible that the default state (fr="0"
) does not match against what SVG 1.1 does.
I suspect that some or all of the browsers haven't changed their implementations to support fr
at all.
Which would mean that the result is more about what to do when the gradient vector has length zero and/or when multiple stops compute to the same final position on the gradient vector. I do recall in testing that there was cross-browser incompatibilities for linear gradients in this case, and we made a point of specifying behavior in SVG 2, but I don't know whether bugs were filed on the non-conforming browsers.
@dirkschulze this is what I'm aware of ATM. I know that other degenerate cases have been considered in SVG and other spec contexts before, but it may be reasonable to revisit (and make sure there are tests).
@AmeliaBR I too suspected that "implementation inertia" could explain part of it, but I don't know to what degree that is true. It is probably more about having a zero-length gradient vector than about the initial value of fr
(which should match the behavior of SVG 1.1). Gradient rendering tend to suffer from numerical issues, so the exact formulation used by the "solver" can have an effect [1].
[1] I.e a renderer that supports fr
may use a different formulation than one that doesn't (i.e only supports it as 0). I suspect this is why the "... on the edge" rule was there in the first place (for certain formulations you'll hit infinity on the edge, and probably have numerical instability close to the edge).
The SVG Working Group just discussed Radial gradients: "fully overlapping" vs "focal point on the edge" - which takes precedence?
.
A similar situation would be for a linear gradient if x1=x2 and y1=y2. In this case: Firefox shows the last stop color, Chrome shows the first stop color. Inkscape shows the average of the first and last stop colors. The SVG 2 spec says: If ‘x1’ = ‘x2’ and ‘y1’ = ‘y2’, then the area to be painted will be painted as a single color using the color and opacity of the last gradient stop. I would expect a similar rule to apply for radial gradients, thus I would expect the example to show yellow (the last stop color).
In SVG 1.1 an r value of 0 meant use the last colour stop per https://www.w3.org/TR/SVG11/pservers.html#RadialGradients, that text has been removed but Firefox still implements it at the moment, that's why you get the last colour stop.
Here is a test with various gradients: http://tavmjong.free.fr/SVG/SVG2_TESTS/gradient_animation.svg
The SVG Working Group just discussed Radial gradients: "fully overlapping" vs "focal point on the edge" - which takes precedence?
.
The SVG Working Group just discussed Radial gradients: "fully overlapping" vs "focal point on the edge" - which takes precedence?
, and agreed to the following:
RESOLUTION: For spread-method="repeat" and "reflect", infinitesimal repeats use the average color of the stops
RESOLVED: For spread-method="repeat" and "reflect", infinitesimal repeats use the average color of the stops
RESOLVED: for spread-method="pad" we use the last color stop
RESOLVED: for spread-method="pad" we use the last color stop for infinitesimal repeats
If you have a radial gradient with a start radius (
fr
) of 0, end radius (r
) of 0 and corresponding points have the same coordinates (i.e<cx,cy,r> == <fx,fy,fr>
), it could be said that the circles are both fully overlapping and that the focal point is on the edge of the end circle (if a degenerate circle can be said to have an edge that is).The "fully overlapping" rule comes from [1]. The "focal point on the edge" rule doesn't appear to be that well-defined (at least I only see it in the annotations and figures in [1] and sections above mention it but only for
spreadMethod=repeat
).Based on a simple test [2], there is currently some different interpretations: Gecko renders that test with yellow while Blink renders it blue.
[1] https://www.w3.org/TR/SVG2/pservers.html#RadialGradientNotes [2] https://jsfiddle.net/0v3tuoq4/