Largura de traço fixa em SVG

103

Eu gostaria de poder definir a largura do traço em um elemento SVG para ser "ciente de pixels", que sempre tem 1px de largura, independentemente das transformações de escala aplicadas atualmente. Estou ciente de que isso pode ser impossível, já que o objetivo do SVG é ser independente de pixel.

Segue o contexto:

Eu tenho um elemento SVG com seus atributos viewBox e preserveAspectRatio definidos. Parece algo assim

<svg version="1.1" baseProfile="full"
    viewBox="-100 -100 200 200" preserveAspectRatio="xMidYMid meet"
    xmlns="http://www.w3.org/2000/svg" >
</svg>

Isso significa que quando eu dimensiono esse elemento, as formas reais dentro dele são dimensionadas de acordo (até agora, tudo bem).

Como você pode ver, configurei o viewBox para que a origem ficasse no centro. Eu gostaria de desenhar um eixo xey dentro desse elemento, o que faço assim:

<line x1="-1000" x2="1000" y1="0" y2="0" />

Novamente, isso funciona bem. No entanto, o ideal é que esse eixo sempre tenha apenas 1 px de largura. Não tenho interesse nos eixos ficarem mais gordos quando escalono o elemento svg pai.

Então, estou ferrado?

wxs
fonte

Respostas:

128

Você pode usar a vector-effectpropriedade definida como non-scaling-stroke, consulte os documentos . Outra forma é usar transform(ref).

Isso funcionará em navegadores que suportam essas partes do SVG Tiny 1.2, por exemplo, Opera 10. O fallback inclui escrever um pequeno script para fazer o mesmo, basicamente invertendo o CTM e aplicando-o nos elementos que não devem escalar.

Se quiser linhas mais nítidas, você também pode desativar o anti-serrilhamento ( shape-rendering=optimizeSpeedou shape-rendering=crispEdges) e / ou brincar com o posicionamento.

Erik Dahlström
fonte
1
Infelizmente, isso está em um aplicativo XUL e não parece ser compatível com o efeito vetorial ainda. Ah bem.
wxs de
1
Isso deve aparecer no Firefox 15 e está tudo certo, então você deve poder usá-lo assim que criar seu aplicativo XUL no gecko 15.
Robert Longson
2
O IE11 ainda não oferece suporte à vector-effectpropriedade. É possível obter o mesmo efeito que vector-effect: non-scaling-strokeno IE11?
merlin
1
@merlin sim, com js é possível emular isso no IE.
Erik Dahlström
3
@merlin clone o elemento (configurando fillpara nonee vice-versa para stroke), calcule e configure as transformações apropriadas (uma para a parte de preenchimento e outra para a parte de traço). Vai ser um pouco confuso, com certeza, mas é isso - você também pode pedir à Microsoft para adicionar suporte para ele. Em qualquer caso, acho que sua pergunta merece ser uma pergunta própria.
Erik Dahlström