Atualmente construindo um aplicativo SVG baseado em navegador. Dentro deste aplicativo, várias formas podem ser estilizadas e posicionadas pelo usuário, incluindo retângulos.
Quando aplico a stroke-width
em um rect
elemento SVG , por exemplo 1px
, o traçado é aplicado ao rect
deslocamento e inserção do de diferentes maneiras por diferentes navegadores. Isso está se mostrando problemático, especialmente quando tento calcular a largura externa e a posição visual de um retângulo e posicioná-lo ao lado de outros elementos.
Por exemplo:
- O Firefox adiciona 1 px inserido (inferior e esquerdo) e 1 px offset (superior e direito)
- O Chrome adiciona 1 px inserido (superior e esquerdo) e 1 px offset (inferior e direito)
Minha única solução até agora seria desenhar as bordas reais (provavelmente com a path
ferramenta) e posicionar as bordas atrás do elemento traçado. Mas essa solução é uma solução desagradável e eu preferiria não seguir esse caminho, se possível.
Então, minha pergunta é: você pode controlar como um SVG stroke-width
é desenhado em elementos?
paint-order
parâmetro, onde você pode especificar, que o preenchimento deve ser renderizado na parte superior do traçado, para que você obtenha o "alinhamento externo", consulte jsfiddle.net/hne0kyLg/1Respostas:
Não, você não pode especificar se o traçado é desenhado dentro ou fora de um elemento. Fiz uma proposta ao grupo de trabalho SVG para essa funcionalidade em 2003, mas ele não recebeu suporte (ou discussão).
Como observei na proposta,
Editar : Esta resposta pode estar errada no futuro. Deve ser possível alcançar esses resultados usando o SVG Vector Effects , combinando
veStrokePath
comveIntersect
(para 'dentro') ou comveExclude
(para 'fora). No entanto, o Vector Effects ainda é um módulo de rascunho de trabalho sem implementações que ainda posso encontrar.Edit 2 : A especificação de rascunho do SVG 2 inclui uma
stroke-alignment
propriedade (com o centro | dentro | fora dos valores possíveis). Essa propriedade poderá entrar em UAs eventualmente.Editar 3 : Amusingly e dissapointingly, o grupo de trabalho SVG removeu
stroke-alignment
a partir SVG 2. Você pode ver algumas das preocupações descritas após a prosa aqui .fonte
ATUALIZAÇÃO: o
stroke-alignment
atributo foi no dia 1º de abril de 2015 movido para uma especificação completamente nova chamada SVG Strokes .A partir do rascunho do Editor do SVG 2.0 de 26 de fevereiro de 2015 (e possivelmente desde 13 de fevereiro ),
acom os valoresstroke-alignment
propriedade está presenteinner
,center
(padrão) eouter
.Parece funcionar da mesma maneira que a
stroke-location
propriedade proposta por @Phrogz e astroke-position
sugestão posterior . Esta propriedade foi planejada desde pelo menos 2011, mas além de uma anotação que dizia, nunca foi detalhado nas especificações como foi adiado - até agora, parece.
Nenhum navegador suporta essa propriedade, ou, até onde eu sei, qualquer um dos novos recursos do SVG 2, ainda, mas espero que eles o façam logo que a especificação amadurecer. Esta tem sido uma propriedade que eu pessoalmente tenho pedido, e estou muito feliz por finalmente estar lá nas especificações.
Parece haver algumas questões sobre como a propriedade deve se comportar em caminhos abertos e em loops. Esses problemas provavelmente prolongarão as implementações nos navegadores. No entanto, atualizarei esta resposta com novas informações à medida que os navegadores começarem a oferecer suporte a essa propriedade.
fonte
stroke-alignment
é especificado em SVG Strokes, um rascunho de trabalho do W3C. Enquanto isso, o Rascunho do Editor SVG 2 W3C diz que uma propriedade de posicionamento de traçado deve estar na especificação SVG em svgwg.org/svg2-draft/painting.html#SpecifyingStrokePaint , mas essa especificação já atingiu o status de Recomendação do candidato do W3C e nenhuma propriedade é nas especificações, além de um link para astroke-position
proposta, fazendo parecer que não será o caso.Encontrei uma maneira fácil, que tem algumas restrições, mas funcionou para mim:
Aqui está um exemplo de trabalho:
fonte
<use>
? Por que não colocar diretamente o caminho e o caminho do clipe? Isso funciona muito bem:<svg width="240" height="240" viewBox="0 0 1024 1024"> <path id="ld" d="M256,0 L0,512 L384,512 L128,1024 L1024,384 L640,384 L896,0 L256,0 Z" clip-path="url(#clip)" stroke="#0081C6" stroke-width="160" fill="#00d2b8"/> <clipPath id="clip"> <use xlink:href="#ld"/> </clipPath> </svg>
. (Sim, isso é completamente razoável e SVG correta e vai processar corretamente em todos os lugares tema nenhum recursão..)Você pode usar CSS para estilizar a ordem dos traços e preenchimentos. Ou seja, toque primeiro e depois preencha em segundo, e obtenha o efeito desejado.
MDN em
paint-order
: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/paint-orderCódigo CSS:
fonte
Aqui está uma função que calcula quantos pixels você precisa adicionar - usando o traçado especificado - nas partes superior, direita, inferior e esquerda, todos baseados no navegador:
fonte
Como as pessoas acima observaram, você terá que recalcular um deslocamento nas coordenadas do caminho do traçado ou dobrar sua largura e depois mascarar um lado ou outro, porque o SVG não apenas não suporta nativamente o alinhamento do traçado do Illustrator, mas o PostScript também não. .
A especificação para traçados no PostScript da Adobe, 2a edição, afirma: " 4.5.1 Traçado: o operador traçado desenha uma linha com alguma espessura ao longo do caminho atual. Para cada segmento reto ou curvo no caminho, traçado traça uma linha centralizada em o segmento com lados paralelos ao segmento ". (ênfase deles)
O restante da especificação não possui atributos para compensar a posição da linha. Quando o Illustrator permite o alinhamento interno ou externo, ele recalcula o deslocamento do caminho real (porque ainda é computacionalmente mais barato do que sobreimprimir e mascarar). As coordenadas do caminho no documento .ai são referência, não o que é rasterizado ou exportado para um formato final.
Como o formato nativo do Inkscape é SVG de especificação, ele não pode oferecer um recurso que a especificação não possui.
fonte
Aqui está uma solução alternativa para bordas internas
rect
usandosymbol
euse
.Exemplo : https://jsbin.com/yopemiwame/edit?html,output
SVG :
Nota: Certifique-se de substituir o
?
emuse
com valores reais.Antecedentes : A razão pela qual isto funciona é porque símbolo estabelece uma nova janela, substituindo
symbol
comsvg
e criando um elemento no DOM sombra. Osvg
DOM da sombra é então vinculado ao seuSVG
elemento atual . Observe quesvg
s pode ser aninhado e cadasvg
um cria uma nova janela de exibição, que recorta tudo o que se sobrepõe, incluindo a borda sobreposta. Para uma visão muito mais detalhada do que está acontecendo, leia este fantástico artigo de Sara Soueidan.fonte
Não sei como isso será útil, mas no meu caso, criei outro círculo apenas com borda e coloquei "dentro" da outra forma.
fonte
Uma solução possível (suja) é usar padrões,
Aqui está um exemplo com um triângulo com traços internos:
https://jsfiddle.net/qr3p7php/5/
fonte
A solução de Xavier Ho de dobrar a largura do traçado e alterar a ordem da tinta é brilhante, embora só funcione se o preenchimento for de uma cor sólida, sem transparência.
Eu desenvolvi outra abordagem, mais complicada, mas funciona para qualquer preenchimento. Também funciona em elipses ou caminhos (com o posterior há alguns casos de canto com comportamento estranho, por exemplo, caminhos abertos que se cruzam entre si, mas não muito).
O truque é exibir a forma em duas camadas. Um sem traço (preenchimento apenas) e outro apenas com traçado na largura dupla (preenchimento transparente) e passado por uma máscara que mostra toda a forma, mas oculta a forma original sem traçado.
fonte