# Re: several messages about radial gradients

From: Philip Taylor <pjt47@cam.ac.uk>
Date: Thu, 14 Feb 2008 14:25:43 +0000
Message-ID: <47B44F67.9060608@cam.ac.uk>
To: Ian Hickson <ian@hixie.ch>
CC: Boris Zbarsky <bzbarsky@MIT.EDU>, "public-html@w3.org" <public-html@w3.org>
```
Ian Hickson wrote:
>>>> Both SVG behaviours can be emulated using the canvas behaviour. When
>>>> one circle is inside the other, the canvas behaviour can be emulated
>>>> using the SVG 1.1 behaviour (with some adjustments to colour stop
>>>> offsets).
>
> Philip, can you elaborate on this?

My original thoughts were about how SVG code like:

<radialGradient cx cy r fx fy>
<stop offset .../>
...
</radialGradient>

could be rendered on canvas approximately like:

dx = fx-cx, dy = fy-cy
d = sqrt(dx^2 + dy^2)
if d > r: # (force the focus point to be inside the circle)
dx *= 0.999 * r/d
dy *= 0.999 * r/d
g = ctx.createRadialGradient(cx+dx, cy+dy, 0, cx, cy, r)
g.addColorStop(offset, ...)

(ignoring some handling for r<=0, misordered stops, out-of-range stops,
and all sorts of other complexities).

Canvas code like:

g = ctx.createRadialGradient(x0, y0, r0, x1, y1, r1)
g.addColorStop(offset, ...)
...

(assuming r0 < r1) could be rendered to SVG approximately like:

d = sqrt((x1-x0)^2 + (y1-y0)^2)
<radialGradient cx={x1} cy={y1} r={r1} fx={x0} fy={y0}>
<stop offset={r0/d + (1-r0/d)*offset} .../>
...
</radialGradient>

iff (x0,y0,r0) is contained within (x1,y1,r1). If it's not contained
within, then it has the weird canvas cone behaviour and can't be
approximated by an SVG gradient (because SVG forces the focus point to
be inside the circle, exactly to avoid the situations where you'd have
to draw a weird cone or something).

I'm not sure that's particularly relevant to anything, though.

SVG and canvas can never be exactly the same, because SVG has
circle-plus-focus-point while canvas has outer-circle-plus-inner-circle.
Code sharing should (and does) occur in the low-level rendering code
(Cairo, Quartz, etc), not in the browser API code (SVG, canvas).

I think the relevant issue is that the various low-level rendering
libraries (and the different versions of those libraries, and the
different backends within each version) are sufficiently interoperable
for SVG but not for canvas, and it is significantly easier for
implementors if we fix that by changing canvas to only use the
interoperable subset of those libraries (by forcing the smaller circle
to be contained within the larger circle, which just requires a few
extra calculations in the canvas API implementation), rather than
requiring changes inside those libraries.

--
Philip Taylor
pjt47@cam.ac.uk
```
Received on Thursday, 14 February 2008 14:26:02 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Wednesday, 9 May 2012 00:16:12 GMT