Подтвердить что ты не робот

Вставка текста в путь SVG

У меня есть SVG-путь, который рисует контур трикотажа, и я хочу, чтобы называть фамилии игроков в этой майке. Кроме того, поскольку я буду помещать имена различной длины в майку, я хотел бы сделать размер текста динамически масштабированным, чтобы соответствовать майке.

Мне удалось центрировать текст с помощью некоторой математики с участием getBoundingClientRect(), но я борюсь с динамическим размером текста. Сначала это выглядит нормально, но тогда, когда я изменяю размер экрана, размер текста не остается пропорциональным размеру трикотажа.

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

EDIT: теперь у меня достаточно очков репутации для добавления изображений (woo!), поэтому вот несколько фотографий, чтобы продемонстрировать проблему изменения размера, о которой я говорю. Текст не масштабируется пропорционально размеру трикотажа при увеличении/уменьшении масштаба. НО, если я обновляю страницу после того, как я увеличиваю/уменьшаю масштаб, то есть, чтобы начать с версии с увеличенным вводом/выводом, размер шрифта корректируется до текущего размера трикотажа и подходит для трикотажа по желанию.

original sizezoomed outzoomed in

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>Jersey</title>
</head>

<body>
  <svg id="jersey">
    <switch>
      <g>
        <g id="jerseyShape">
          <path id="outline" fill="green" transform="translate(-40,0)" opacity="0.35" fill="none" stroke="#000000" stroke-width="1.5" d="M116.462,113.911V39.01
                           c0,0-18.493-5.977-15.317-30.633c0,0-8.033-2.616-8.78-3.363S91.617,9.311,79.29,9.124h-1.305
                           C65.656,9.311,65.656,4.268,64.909,5.015s-8.778,3.363-8.778,3.363C59.305,33.034,40.813,39.01,40.813,39.01v74.901
                           C40.813,113.911,74.434,126.427,116.462,113.911z" />
        </g>
        <g id="jerseyContent">
          <svg>
            <text id="name" font-family="Verdana" text-anchor="middle" dominant-baseline="central">
              Jordan
            </text>
            <!-- Dynamically re-size name to fit jersey -->
            <script type="application/ecmascript">
              //Get path bounding rectangle
              var pathNode = document.getElementById("outline");
              var pRect = pathNode.getBoundingClientRect();

              //Get text bounding rectangle
              var textNode = document.getElementById("name");
              var tRect = textNode.getBBox();

              //Calculate the necessary scale to make the text fit within the jersey width while
              //not exceeding a height of 30
              var widthRatio = (pRect.width * 0.85) / tRect.width;
              var heightRatio = (pRect.height*0.3) / tRect.height;
              var textScale = Math.min(widthRatio, heightRatio);

              //Translate text to center of jersey and scale to fit
              textNode.setAttribute("transform", "translate(" + (1 + pRect.width / 2) + " " + (pRect.top + pRect.height / 2) + ")scale(" + textScale + ")");
            </script>
          </svg>
        </g>
      </g>
    </switch>
  </svg>
</body>

</html>
4b9b3361

Ответ 1

Вы также должны использовать getBBox() fo для получения размера пути. Таким образом, размеры будут находиться в одном и том же координатном пространстве даже после масштабирования.

Ответ 2

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

Я решил проблему, задав масштаб на всем g-элементе с id = "full"

Итак, теперь вы можете изменить значение шкалы на id = "full" и получить желаемый результат без выхода метки. Я обновил код таким образом, чтобы он учитывал значение масштаба при масштабировании в уменьшении (ctrl +/ctrl -)

$(window).on("resize", function(){ 
  var scale = "scale("+window.devicePixelRatio+")"
  $("#full").attr("transform", scale)
  console.log($("#full").attr("transform"));
  
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="utf-8">
      <title>Jersey</title>
    </head>
    
    <body style="width:100%; height:100%">
      <svg style="    height: 602px;    width: 100%;">
          <g id="full" transform="scale(1)">
            <g id="jerseyShape" transform="translate(-40,0)">
              <path id="outline" fill="green" opacity="0.35" fill="none" stroke="#000000" stroke-width="1.5" d="M116.462,113.911V39.01
                               c0,0-18.493-5.977-15.317-30.633c0,0-8.033-2.616-8.78-3.363S91.617,9.311,79.29,9.124h-1.305
                               C65.656,9.311,65.656,4.268,64.909,5.015s-8.778,3.363-8.778,3.363C59.305,33.034,40.813,39.01,40.813,39.01v74.901
                               C40.813,113.911,74.434,126.427,116.462,113.911z" />
                <text id="name" transform="translate(80,80)" font-family="Verdana" text-anchor="middle" dominant-baseline="central">
                  Jordan
                </text>                           
            </g>
          </g>
      </svg>
    </body>
    
    </html>