Почему радиальный градиент в d3 изменяется, если высота / ширина контейнера svg не совпадает с высотой / шириной?

Я пытаюсь понять, как работает радиальный градиент в d3.js. У меня есть круг, и я заполнил его радиальным градиентом, указанным в теге defs. Я установил координату 'r' радиального градиента равной 60%, а 'cx' и 'cy' равными нулю. Насколько я понимаю, радиальный градиент всегда будет начинаться с координаты 0,0 (точно в середине моего элемента круга), а внешний круг радиального градиента «остановится» на 60% моего «r». Теперь, когда я изменяю только ширину моего контейнера svg и оставляю высоту неизменной, радиальный градиент не тот. Кажется, что внешний круг радиального градиента отодвигается. Я не могу понять, почему это происходит. Я часами искал в Интернете, но не смог найти достаточного ответа. Можно ли сохранить форму радиального градиента при изменении высоты или ширины?

рисунок 1 здесь Это изображение объясняет, чего я действительно хочу достичь. Я хочу заполнить дугу градиентом. Я думаю, мне нужно использовать «userSpaceOnUse» для единиц градиента, потому что я заполняю этот радиальный градиент на отдельные сегменты, как показано здесь изображение 2 здесь. Я попытался использовать вместо этого objectBoundingBox, но в результате я получил индивидуальный радиальный градиент, заполненный в каждом сегменте (он же круг в каждом сегменте). Когда я изменяю высоту / ширину контейнера, внешний круг радиального градиента отодвигается, поэтому цвет дуги фактически теряет эффект градиента. Вот почему я пытаюсь найти способ сохранить форму радиального градиента при изменении высоты / ширины.

Спасибо Это мой код:

var w = 1000, h = 1000
r = Math.min(w, h) /4 ;

var svg = d3.select("body").append("svg")
    .attr("width", w)
    .attr("height", h)
   .append("g")
    .attr("transform", "translate(" +Math.min(w,h)/2 + "," +Math.min(w,h) /2     + ")");

var radialGradient = d3.select("svg").append("defs")
  .append("radialGradient")
  .attr("id", "radial-gradient")
  .attr("gradientUnits", "userSpaceOnUse")
  .attr("cx", 0)
  .attr("cy", 0)
  .attr("r", "60%") 
  .attr("spreadMethod", "reflect");

radialGradient.append("stop")
  .attr("offset", "15%")
  .attr("stop-color", "red");

radialGradient.append("stop")
  .attr("offset", "25%")
  .attr("stop-color", "#fff");

radialGradient.append("stop")
  .attr("offset", "35%")
  .attr("stop-color", "red");

svg.append("circle")
  .attr("cx", 0)
  .attr("cy", 0)
  .attr("r", r)
  .style("fill", "url(#radial-gradient)");

person alexis    schedule 23.09.2016    source источник


Ответы (1)


Вы установили центр градиента на (cx, cy) 0,0, начало контейнера и указали использование пространства контейнера: userSpaceOnUse.

Чтобы исправить это, просто измените на:

 .attr("gradientUnits", "objectBoundingBox")    // your object limits
  .attr("cx", "50%")
  .attr("cy", "50%")                             // your object center

Надеюсь на эту помощь

person Klaujesi    schedule 23.09.2016
comment
Большое спасибо за ответ @Klaujesi. К сожалению, мне действительно нужно использовать userSpaceOnUse для градиентных единиц. Я отредактировал свой вопрос и добавил больше деталей и изображений, чтобы более подробно объяснить, в чем моя проблема. - person alexis; 23.09.2016
comment
вы можете добиться этого, используя 1 общий градиент (objectBoundingBox) + маска - person Klaujesi; 24.09.2016
comment
Спасибо за ваш ответ. Не могли бы вы привести пример? Или, может быть, несколько ссылок, чтобы я мог узнать больше об этой технике ?? Большое тебе спасибо. - person alexis; 26.09.2016