Как сделать ширину штриха невосприимчивой к текущей матрице преобразования


В SVG (и Canvas, Quartz, Postscript, ...), матрица преобразования влияет как на координаты пути, так и на ширину линии. Есть ли способ сделать корректировку, чтобы ширина линии не пострадала? То есть в следующем примере масштаб отличается для X и Y, что превращает квадрат в прямоугольник, что нормально, но это также делает линии шире с двух сторон.

  <g transform="rotate(30) scale(5,1) ">
      <rect x="10" y="10" width="20" height="20" 
            stroke="blue" fill="none" stroke-width="2"/>
  </g>

масштабируемое перо ширины прямоугольника

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

Не имея этого, я думаю, что мне не нужно рассказывать SVG о моем CTM и вместо этого преобразовывать координаты самостоятельно, что означает преобразование примитивов, таких как rect, в их эквиваленты path.

2 34

2 ответа:

Редактировать:

Существует атрибут, который вы можете добавить к вашей прямой кишке, чтобы получить именно такое поведение:

vector-effect="non-scaling-stroke"

Это было неправильно:

Это сработает, если применить преобразование непосредственно к фигуре, а не к группе, в которой она находится. Конечно, если вы хотите сгруппировать несколько элементов и масштабировать их все вместе, такой подход не сработает.
<rect x="10" y="10" width="20" height="20" 
            stroke="blue" fill="none" stroke-width="2"
            transform="rotate(30) scale(5,1)"/>

Это также может зависеть от вашего средства просмотра SVG; Inkscape отображает файл так, как вы хотите (ширина Штриха не зависит от масштаба) но хром делает это так, как вы показали.

В postscript описание пути и выполнение штриха являются отдельными событиями, поэтому вполне возможно иметь отдельную "ручку" TM.

%!PS
%A Funky Shape

matrix currentmatrix %save normal matrix for stroke pen
306 396 translate
72 72 scale
1 1 5 { pop
    360 5 div rotate
    1 0 translate
    0 0 moveto
    1 1 5 { pop
        360 5 div rotate
        1 0 translate
        1 0 lineto
        -1 0 translate
    } for
    -1 0 translate
    closepath
} for
setmatrix
[ 1 -3 4 2 0 0 ] concat %put some skew in the pen
10 rotate     %makes it look more "organic"
stroke
showpage