Как я могу повернуть символ вокруг его центра, не указывая его положение дважды? - PullRequest
0 голосов
/ 10 мая 2019

У меня есть несколько плиточных символов, которые я хотел бы разместить на сетке.Вот чего я пытаюсь достичь:

  • Используйте координаты мозаики для позиционирования символов (например, 4,2 вместо 85,43)
  • Используйте координаты пикселей (не координаты мозаики) для определения вершин символов
  • Поворот символов вокруг их центра без указания абсолютных координат.

У меня есть решения для первых двух (хотя могут быть и лучшие решения), но нев третьих.Я могу повернуть плитку на 4,2 на четверть оборота следующим образом:

<!-- 10/21 = 0.47619047619 -->
<use x="4" y="2" href="#rooftop-0" class="theme-0" transform="rotate(90 4.476 2.476)" />

Мне действительно не нравится указывать координаты плитки дважды.В идеале я хотел бы написать что-то вроде этого:

<use x="4" y="2" href="#rooftop-0" class="theme-0 rotate-1" />

Определение .rotate-1 в таблице стилей, похоже, не влияет на вращение.transform-origin="50% 50%", кажется, устанавливает источник в 50% области просмотра или что-то в этом роде.Может быть, поможет определение символа с координатами от -10 до 10 вместо 0 до 20?Должен ли я определить viewBox символов?

Другим решением было бы вручную изменить координаты вершин в символе, чтобы создать 3 другие ориентации.Я бы предпочел не!

В любом случае, это то, что у меня пока есть:

<?xml version="1.0" standalone="no"?>
<!-- 21*10+1 = 211 -->
<svg width="211" height="211" version="2.0" xmlns="http://www.w3.org/2000/svg">
  <style>
    .grid-line {
      fill: #DDD;
    }
    .grass-fill {
      fill: #8C8;
    }
    .tile {
      /* 1/21 = 0.04761904761 */
      transform: scale(0.04761904761, 0.04761904761);
    }

    .theme-0 {
      --roof-color-0: #F44;
      --roof-color-1: #F66;
      --roof-color-2: #F88;
      --roof-color-3: #FAA;
    }

    .theme-1 {
      --roof-color-0: #44F;
      --roof-color-1: #66F;
      --roof-color-2: #88F;
      --roof-color-3: #AAF;
    }
  </style>

  <defs>
    <pattern id="grid" width="21" height="21" patternUnits="userSpaceOnUse">
      <rect class="grid-line" x="0" y="0" width="1" height="21" />
      <rect class="grid-line" x="0" y="0" width="21" height="1" />
    </pattern>

    <symbol id="rooftop-0">
      <g class="tile">
        <rect class="grass-fill" width="20" height="20" />
        <polygon style="fill: var(--roof-color-0)" points="3,2 17,2 18,8 2,8" />
        <polygon style="fill: var(--roof-color-1)" points="2,8 18,8 17,14 3,14" />
        <polygon style="fill: var(--roof-color-2)" points="8,8 11,14 11,18 8,18" />
        <polygon style="fill: var(--roof-color-3)" points="8,8 8,18 5,18 5,14" />
      </g>
    </symbol>

    <symbol id="rooftop-1">
      <g class="tile">
        <rect class="grass-fill" width="20" height="20" />
        <polygon style="fill: var(--roof-color-0)" points="2,11 18,11 17,17 3,17" />
        <polygon style="fill: var(--roof-color-1)" points="3,5 17,5 18,11 2,11" />
        <polygon style="fill: var(--roof-color-2)" points="10,11 10,3 13,3 13,5" />
        <polygon style="fill: var(--roof-color-3)" points="10,11 7,5 7,3 10,3" />
      </g>
    </symbol>
  </defs>

  <g>
    <rect fill="#999" width="100%" height="100%" />
    <rect fill="url(#grid)" width="100%" height="100%" />
  </g>

  <g transform="translate(1, 1) scale(21, 21)">
    <use x="3" y="2" href="#rooftop-0" class="theme-1" />
    <!-- 10/21 = 0.47619047619 -->
    <use x="4" y="2" href="#rooftop-0" class="theme-0" transform="rotate(90 4.476 2.476)" />
    <use x="5" y="2" href="#rooftop-1" class="theme-1" />
  </g>
</svg>

Вот скриншот:

Screenshot

Я действительно надеюсь, что есть чистый способ сделать то, что я пытаюсь сделать.Вращение символа вокруг его центра кажется чем-то, что вы будете делать постоянно.

Ответы [ 2 ]

1 голос
/ 10 мая 2019

Вместо установки атрибутов с использованием координат x и y вы можете установить их с помощью transform="translate(x, y), таким образом, исходные параметры метода rotate() останутся прежними (0.5, 0.5 ):

<svg viewBox="0 0 211 211">
  <style>
    .grid-line {
      fill: #DDD;
    }
    .grass-fill {
      fill: #8C8;
    }
    .theme-0 {
      --roof-color-0: #F44;
      --roof-color-1: #F66;
      --roof-color-2: #F88;
      --roof-color-3: #FAA;
    }

    .theme-1 {
      --roof-color-0: #44F;
      --roof-color-1: #66F;
      --roof-color-2: #88F;
      --roof-color-3: #AAF;
    }
  </style>

  <defs>
    <pattern id="grid" x="-0.5" y="-0.5" width="20" height="20" patternUnits="userSpaceOnUse">
      <rect class="grid-line" x="0" y="0" width="1" height="20" />
      <rect class="grid-line" x="0" y="0" width="20" height="1" />
    </pattern>

    <symbol id="rooftop-0" viewBox="0 0 20 20">
      <g class="tile" transform="translate(0.5, 0.5) scale(0.95)">
        <rect class="grass-fill" width="20" height="20" />
        <polygon style="fill: var(--roof-color-0)" points="3,2 17,2 18,8 2,8" />
        <polygon style="fill: var(--roof-color-1)" points="2,8 18,8 17,14 3,14" />
        <polygon style="fill: var(--roof-color-2)" points="8,8 11,14 11,18 8,18" />
        <polygon style="fill: var(--roof-color-3)" points="8,8 8,18 5,18 5,14" />
      </g>
    </symbol>

    <symbol id="rooftop-1" viewBox="0 0 20 20">
      <g class="tile"transform="translate(0.5, 0.5) scale(0.95)">
        <rect class="grass-fill" width="20" height="20" />
        <polygon style="fill: var(--roof-color-0)" points="2,11 18,11 17,17 3,17" />
        <polygon style="fill: var(--roof-color-1)" points="3,5 17,5 18,11 2,11" />
        <polygon style="fill: var(--roof-color-2)" points="10,11 10,3 13,3 13,5" />
        <polygon style="fill: var(--roof-color-3)" points="10,11 7,5 7,3 10,3" />
      </g>
    </symbol>
  </defs>
  
  <g>
    <rect fill="#999" width="100%" height="100%" />
    <rect fill="url(#grid)" width="100%" height="100%" />
  </g>
  
  <g transform="scale(20, 20)">
      <use xlink:href="#rooftop-0" class="theme-1" width="1" height="1" transform="translate(4, 2) rotate(0,0.5,0.5)"/>
      <use xlink:href="#rooftop-1" class="theme-0" width="1" height="1" transform="translate(5, 2) rotate(90,0.5,0.5)"/>
      <use xlink:href="#rooftop-0" class="theme-1" width="1" height="1" transform="translate(6, 2) rotate(180,0.5,0.5)"/>
  </g>
</svg>
0 голосов
/ 10 мая 2019

Надеюсь, это то, что вы спрашивали: теперь у символа есть атрибут wiewBox: viewBox="0 0 20 20" Это означает, что символ имеет ширину 20 единиц и высоту 20 единиц.Теперь вы можете использовать символ следующим образом:

<use xlink:href="#rooftop-0"  width="20" height="20" x="63" y="21"  />

Как вы можете видеть, я могу дать символу ширину и высоту в этом случае width = "20" height = "20", но вы можете дать емулюбой размер вам нужен.Также вы можете использовать атрибуты x и y, чтобы изменить положение используемого символа.

Теперь вы также можете вращать элемент использования вокруг его центра, используя transform="rotate(90,73,31)" Это вращает элемент на 90 градусов вокруг точки {x: 73, y: 31}

<svg viewBox="0 0 211 211">
  <style>
    .grid-line {
      fill: #DDD;
    }
    .grass-fill {
      fill: #8C8;
    }
    
    .theme-0 {
      --roof-color-0: #F44;
      --roof-color-1: #F66;
      --roof-color-2: #F88;
      --roof-color-3: #FAA;
    }
    
    .theme-1 {
      --roof-color-0: #44F;
      --roof-color-1: #66F;
      --roof-color-2: #88F;
      --roof-color-3: #AAF;
    }
  </style>
  
  <defs>
    <pattern id="grid" width="21" height="21" patternUnits="userSpaceOnUse">
      <rect class="grid-line" x="0" y="0" width="1" height="21" />
      <rect class="grid-line" x="0" y="0" width="21" height="1" />
    </pattern>
    
    <symbol id="rooftop-0" viewBox="0 0 20 20">
      <g class="tile">
        <rect class="grass-fill" width="20" height="20" />
        <polygon style="fill: var(--roof-color-0)" points="3,2 17,2 18,8 2,8" />
        <polygon style="fill: var(--roof-color-1)" points="2,8 18,8 17,14 3,14" />
        <polygon style="fill: var(--roof-color-2)" points="8,8 11,14 11,18 8,18" />
        <polygon style="fill: var(--roof-color-3)" points="8,8 8,18 5,18 5,14" />
      </g>
    </symbol>
    

  </defs>
  
  <g>
    <rect fill="#999" width="100%" height="100%" />
    <rect fill="url(#grid)" width="100%" height="100%" />
  </g>
  
  <g transform="translate(1, 1)">
    <use x="42" y="21" xlink:href="#rooftop-0" class="theme-1" width="20" height="20" />
    
    <use x="63" y="21" xlink:href="#rooftop-0" class="theme-0" width="20" height="20" transform="rotate(90,73,31)" />
  </g>
</svg>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...