Сначала я покажу, как это сделать, если прямоугольник, который вы заполняете градиентом, представляет собой квадрат:
svg{border:solid; width:45vw}
<svg viewBox="0 0 300 300">
<defs>
<radialGradient id="MyGradient" gradientUnits="objectBoundingBox"
cx="0.3" cy="0.4" r="0.3" fx="0.1" fy="0.2">
<stop offset="0%" stop-color="red" />
<stop offset="50%" stop-color="blue" />
<stop offset="100%" stop-color="black" />
</radialGradient>
</defs>
<rect fill="url(#MyGradient)" stroke="black" stroke-width="5"
x="50" y="100" width="200" height="200"/>
</svg>
<svg viewBox="0 0 300 300">
<defs>
<radialGradient id="MyGradient1" gradientUnits="userSpaceOnUse"
cx="110" cy="180" r="60" fx="70" fy="140" >
<stop offset="0%" stop-color="red" />
<stop offset="50%" stop-color="blue" />
<stop offset="100%" stop-color="black" />
</radialGradient>
</defs>
<rect fill="url(#MyGradient1)" stroke="black" stroke-width="5"
x="50" y="100" width="200" height="200"/>
</svg>
В случае gradientUnits = "userSpaceOnUse":
Ограничивающая рамка прямоугольника для заливки:
bb:{x:50, y:100, width:200, height:200}
Вычисленные атрибуты для gradientUnits="userSpaceOnUse"
:
cx = bb.x + bb.width *.3 = 50 + 200 * .3 = 110
cy = bb.y + bb.height *.4 100 + 200*.4 = 180
r = bb.width*.3 = 200*.3 = 60
fx = bb.x + bb.width *.1 = 50 + 200 * .1 = 70
fy = bb.y + bb.height *.2 = 100 + 200 * .2 = 140
Таким образом, вы можете использовать
<radialGradient id="MyGradient1" gradientUnits="userSpaceOnUse" cx="110" cy="180" r="60" fx="70" fy="140" >
При использовании objectBoundingBox
значения атрибутов radialGradient принимают значения от 0 до 1 или от 0 до 100% от заполненного поля.
Вы также можете использовать objectBoundingBox
как значение для clipPathUnits
. Взгляните на следующий пример.
Это clipPath, где контур обрезки представляет собой круг. Если обрезанная форма представляет собой квадрат, результатом будет круг. Если обрезанная форма представляет собой прямоугольник, результатом является эллипс, означающий, что путь обрезки растягивается в соответствии с соотношением сторон обрезанной формы.
<svg viewBox="0 0 120 60">
<defs>
<clipPath id="clip" clipPathUnits="objectBoundingBox">
<circle cx=".5" cy=".5" r=".45" />
</clipPath>
</defs>
<rect id="r" x="5" y="5" width="50" height="50" />
<use xlink:href="#r" fill="gold" clip-path="url(#clip)" />
<rect id="r1" x="60" y="15" width="55" height="30" />
<use xlink:href="#r1" fill="gold" clip-path="url(#clip)" />
</svg>
То же самое происходит с градиентом. Если радиальный градиент с gradientUnits="objectBoundingBox"
используется для заливки прямоугольника с другой шириной и высотой, результатом будет эллиптический градиент (как в вашем примере). Если вы хотите преобразовать эллиптический градиент в gradientUnits="userSpaceOnUse"
, вам понадобится способ создать градиент с другим rx и ry. К сожалению, это невозможно .