Направление SVG linearGradient

220
19 октября 2018, 02:30

У меня есть простой линейный градиент внутри круга.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300">
  <linearGradient id="ct-svg-gradient" gradientTransform="rotate(65)">
    <stop offset="0%" stop-color="red" />
    <stop offset="100%" stop-color="yellow" />
  </linearGradient>
  <circle cx="100" cy="100" r="50" fill="url(#ct-svg-gradient)"/>
</svg>   

Как вы можете видеть, я пытаюсь повернуть градиент на 65 градусов. По крайней мере документы заявляют, что это возможно. Я попытался установить этот поворот на большее число, и это не дало ожидаемого результата.

Я понимаю, что проблема заключается в том, что linearGradient не может трансформировать transform origin в центр.

Я предполагаю, что мне придется использовать атрибуты x1, y1, x2, y2 для линейного градиента, без градиентной трансформации. Если это так, то какой самый простой способ получить эти четыре значения, если у меня есть только угол, на который я должен вращать градиент?

Я заинтересован в реализации такой функции, мой вход динамичен.

function convert(angle_in_degrees) { // or radians, I'll take care of conversion
  // the algorithm I'm interested in
  return {
    x1: ...,
    y1: ...,
    x2: ...,
    y2: ...,
  };
}

Буду благодарен за любой ответ.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300"> 
  <linearGradient id="ct-svg-gradient" gradientTransform="rotate(150)"> 
    <stop offset="0%" stop-color="red" /> 
    <stop offset="100%" stop-color="yellow" /> 
  </linearGradient> 
  <circle cx="100" cy="100" r="50" fill="url(#ct-svg-gradient)"/> 
</svg>

Answer 1

Это не так просто. чтобы ваш градиент мог заполнить объект от края к краю, вам нужно будет также передать его и принять во внимание его bounding box.

Если вам нужно только применять градиент к кругам, тогда было бы проще применить ориентированный по оси градиент и повернуть круг.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300"> 
  <linearGradient id="ct-svg-gradient"> 
    <stop offset="0%" stop-color="red" /> 
    <stop offset="100%" stop-color="yellow" /> 
  </linearGradient> 
  <circle cx="100" cy="100" r="50" fill="url(#ct-svg-gradient)" transform="rotate(150,100,100)"/> 
</svg>

Update

Вот простая функция JS, которая делает то, что вы хотите. Это не всегда даст лучшие результаты, но это должно быть легко понятно.

function setGradientAngle(elementId, gradientId, angle) 
{ 
  // Конвертирование угла в радианы 
  angle = angle * Math.PI / 180; 
  // Получить ограничительную рамку элемента (bounding box)  
 
  var bbox = document.getElementById(elementId).getBBox(); 
  // Вычисление центра вращения 
  var cx = bbox.x + bbox.width/2; 
  var cy = bbox.y + bbox.height/2; 
   //Минимальный радиус, который нам нужен, чтобы гарантировать, что градиент растягивает всю ширину 
   //Этот расчет может быть более умным. Мы просто делаем худший случай здесь для простоты. 
  var radius = Math.sqrt(bbox.width*bbox.width+bbox.height*bbox.height)/2; 
   //Вычисляем вектор от центра к градиентным координатам 
  var rx = Math.cos(angle) * radius; 
  var ry = Math.sin(angle) * radius; 
  // Обновление градиентных координат 
  var grad = document.getElementById(gradientId); 
  grad.setAttribute("gradientUnits", "userSpaceOnUse"); 
  grad.setAttribute("x1", cx - rx); 
  grad.setAttribute("y1", cy + ry); 
  grad.setAttribute("x2", cx + rx); 
  grad.setAttribute("y2", cy - ry); 
} 
 
setGradientAngle("mypath", "ct-svg-gradient", 150);
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300"> 
  <linearGradient id="ct-svg-gradient"> 
    <stop offset="0%" stop-color="red" /> 
    <stop offset="100%" stop-color="yellow" /> 
  </linearGradient> 
  <path id="mypath" fill="url(#ct-svg-gradient)" vector-effect="non-scaling-stroke" d="M116.48,288.71a582.68,582.68,0,0,0-69.84-40.32q-36.32-17.74-33.52-58.06a582.72,582.72,0,0,0,0-80.65Q10.32,69.35,46.64,51.61a582.68,582.68,0,0,0,69.84-40.32q33.52-22.58,67,0a582.67,582.67,0,0,0,69.84,40.32q36.32,17.74,33.52,58.06a582.65,582.65,0,0,0,0,80.65q2.79,40.32-33.52,58.06a582.67,582.67,0,0,0-69.84,40.32Q150,311.29,116.48,288.71Z"/> 
</svg>

READ ALSO
MySQL приоритет выборки по столбцам

MySQL приоритет выборки по столбцам

Внимательно изучил вот эту тему Приоритет выборки WHERE

260
Подскажите в файловой системе сайта на хостинге в какой папке можно найти, какая база данных подвязана к сайту?

Подскажите в файловой системе сайта на хостинге в какой папке можно найти, какая база данных подвязана к сайту?

Подскажите в файловой системе сайта на хостинге в какой папке можно найти, какая база данных подвязана к сайту? Скриншот файловой системы...

203
Посчитать место занимаемое в таблице

Посчитать место занимаемое в таблице

Категорически приветствую! Существует mysql-сервер (mysqld Ver 56

185
Кодировка БД и Сервлета UTF-8 не работает должным образом

Кодировка БД и Сервлета UTF-8 не работает должным образом

Имеется Web-приложение для регистрации документов (те

185