SVG применяет один и тот же источник преобразования ко всем дочерним элементам группы / символа - PullRequest
0 голосов
/ 19 мая 2018

Я не могу получить повторно используемые предметы или всех детей группы, чтобы соответствовать указанному transform-origin.Цель состоит в том, чтобы иметь возможность многократно использовать одну и ту же форму с одним и тем же шаблоном стиля.Однако, учитывая transform-origin стиль, CSS или другой, не каскад.Это будет применяться только во время <use>.

Например:

svg {
  width: 125px; height: 125px;
  background: rgba(0, 0, 0, 0.5);
}
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
  <defs>
    <ellipse id="svg-ellipse-def" cx="500" cy="500" rx="140" ry="455" transform-origin="center" style="transform-origin: center"/>
  </defs>
  
  <symbol id="svg-ellipse" >
    <ellipse cx="500" cy="500" rx="140" ry="455" transform-origin="center" style="transform-origin: center"/>
  </symbol>
    
  <g fill="none" stroke="red" stroke-width="50">
     <use xlink:href="#svg-ellipse"/>
     <use xlink:href="#svg-ellipse" transform="rotate(45)"/>
     <use xlink:href="#svg-ellipse" transform="rotate(90)"/>
     <use xlink:href="#svg-ellipse-def" transform="rotate(-45)"/>
  </g>
</svg>

По существу, источник преобразования не применяется независимо от того, использую ли я атрибут class= или свойство transform-origin= или даже встроенный стиль.Я также пытался обернуть его в <defs> контейнер.

Желаемый результат:

<use xlink:href="#svg-ellipse" transform="rotate(45)"/>     
<use xlink:href="#svg-ellipse" transform="rotate(90)"/>
<use xlink:href="#svg-ellipse" transform="rotate(-45)"/>

Но сейчас это выглядит так:

<use xlink:href="#svg-ellipse" transform="rotate(45)" style="transform-origin:center"/>     
<use xlink:href="#svg-ellipse" transform="rotate(90)" style="transform-origin:center"/>
<use xlink:href="#svg-ellipse" transform="rotate(-45)" style="transform-origin:center"/>

svg {
  width: 125px; height: 125px;
  background: rgba(0,0,0,0.5);
}
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000">
  
  <symbol id="svg-ellipse" >
    <ellipse cx="500" cy="500" rx="140" ry="455"/>
  </symbol>
    
  <g fill="none" stroke="red" stroke-width="50">
     <use xlink:href="#svg-ellipse"/>
     <use xlink:href="#svg-ellipse" transform="rotate(45)"  transform-origin="center"/>
     <use xlink:href="#svg-ellipse" transform="rotate(90)" transform-origin="center"/>
     <use xlink:href="#svg-ellipse" transform="rotate(-45)"  transform-origin="center"/>
  </g>
</svg>

В соответствии с документацией :

Если элемент 'use' ссылается на элемент 'symbol':

В сгенерированном контенте «use» будет заменено на «g», где все атрибуты элемента «use», кроме «x», «y», «width»,'height' и 'xlink: href' передаются в сгенерированный элемент 'g'.Дополнительное преобразование translate (x, y) добавляется в конец (т. Е. Справа) атрибута 'transform' в сгенерированном 'g', где x и y представляют значения 'x' и 'y'атрибуты элемента use.Упомянутый «символ» и его содержимое глубоко клонируются в сгенерированное дерево, за исключением того, что «символ» заменяется на «svg».

Глядя на консоль разработчика, этоподтверждается, и стиль применяется встроенным, но не учитывается:

enter image description here

Даже если элемент <use> имеет встроенный стиль transform-origin, потому чтосимвол теперь конвертируется в его собственный SVG как дочерний элемент элемента <use>, и у него есть собственный встроенный стиль, разве это не должно иметь более высокий приоритет по сравнению со встроенным родительским элементом?

1 Ответ

0 голосов
/ 20 мая 2018

Вы можете настроить таргетинг на сам элемент <use>, но не на его содержимое.Содержимое может, в принципе, наследовать свойства CSS.Но барьер, с которым вы всегда столкнетесь: ни свойство CSS transform , ни свойство transform-origin не наследуются.

  • Если вывращая элемент <use>, вы поворачиваете его вокруг источника преобразования элемента <use>, в то время как содержимое теневого DOM остается на месте относительно его корня.

  • Если вызадайте источник преобразования для <symbol> или <ellipse>, он будет применяться только в том случае, если вы преобразуете это само, и преобразование будет клонировано в каждое из его повторных использований.

Лучшее решение, которое я вижу, - дать всем элементам использования, которые ссылаются на один и тот же символ, один и тот же источник преобразования.Чтобы селектор атрибутов работал, вам нужно отключить пространство имен xlink.В любом случае это не рекомендуется, но вам придется учитывать совместимость браузера .

Но тогда то же самое верно и для поддержки источника преобразования в SVG .Это, кстати, причина для установки transform-box: fill-box.После того, как между Firefox и Chrome были некоторые различия в реализации, теперь принято считать, что это свойство необходимо элементам SVG для их преобразования по отношению к их ограничительной рамке.Я немного изменил ваш пример, чтобы продемонстрировать.

svg {
  width: 125px; height: 125px;
  background: rgba(0, 0, 0, 0.5);
}

use[href="#symbol1"] {
  transform-origin: center;
  transform-box: fill-box;
}
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1500 1500">
  
  <symbol id="symbol1" >
    <ellipse cx="500" cy="500" rx="140" ry="455" />
  </symbol>
    
  <g fill="none" stroke="red" stroke-width="50">
     <use href="#symbol1" transform="translate(200, 400)" />
     <use href="#symbol1" transform="translate(200, 400) rotate(45)"/>
     <use href="#symbol1" transform="translate(200, 400) rotate(90)"/>
     <use href="#symbol1" transform="translate(200, 400) rotate(-45)"/>
  </g>
</svg>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...