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

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

В 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>

rectangle width scaled pen

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

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

4b9b3361

Ответ 1

Edit:

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

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 отображает ваш файл так, как вы хотите (ширина штриха не зависит от масштаба), но Chrome отображает его, как вы показали.

Ответ 2

В постскриптуме описание пути и выполнение штриха - отдельные события, поэтому вполне возможно иметь отдельную "ручку" 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