Actuellement en construction d'une application SVG basée sur un navigateur. Dans cette application, différentes formes peuvent être stylisées et positionnées par l'utilisateur, y compris des rectangles.
Lorsque j'applique un stroke-width
à un rect
élément SVG , par exemple 1px
, le trait est appliqué au rect
décalage et à l'encart de de différentes manières par différents navigateurs. Cela s'avère problématique, surtout lorsque j'essaie de calculer la largeur extérieure et la position visuelle d'un rectangle et de le positionner à côté d'autres éléments.
Par exemple:
- Firefox ajoute un encart de 1 px (en bas et à gauche) et un décalage de 1 px (en haut et à droite)
- Chrome ajoute un encart de 1 px (en haut et à gauche) et un décalage de 1 px (en bas et à droite)
Jusqu'à présent, ma seule solution serait de dessiner moi-même les bordures réelles (probablement avec l' path
outil) et de positionner les bordures derrière l'élément tracé. Mais cette solution est une solution de contournement désagréable, et je préférerais ne pas emprunter cette voie si possible.
Donc ma question est, pouvez-vous contrôler comment un SVG stroke-width
est dessiné sur des éléments?
paint-order
paramètre, où vous pouvez spécifier, que le remplissage doit être rendu au-dessus du trait, donc vous obtiendrez «l'alignement extérieur», voir jsfiddle.net/hne0kyLg/1Réponses:
Non, vous ne pouvez pas spécifier si le trait est dessiné à l'intérieur ou à l'extérieur d'un élément. J'ai fait une proposition au groupe de travail SVG pour cette fonctionnalité en 2003, mais elle n'a reçu aucun soutien (ou discussion).
Comme je l'ai noté dans la proposition,
Edit : Cette réponse peut être erronée à l'avenir. Il devrait être possible d'obtenir ces résultats en utilisant des effets vectoriels SVG , en combinant
veStrokePath
avecveIntersect
(pour «à l'intérieur») ou avecveExclude
(pour «à l'extérieur). Cependant, les effets vectoriels sont toujours un projet de module de travail sans implémentations que je puisse encore trouver.Edit 2 : Le projet de spécification SVG 2 comprend une
stroke-alignment
propriété (avec centre | à l'intérieur | en dehors des valeurs possibles). Cette propriété peut éventuellement devenir un UA.Edit 3 : De manière amusante et décevante, le groupe de travail SVG a supprimé
stroke-alignment
de SVG 2. Vous pouvez voir certaines des préoccupations décrites après la prose ici .la source
MISE À JOUR: L'
stroke-alignment
attribut a été déplacé le 1er avril 2015 vers une toute nouvelle spécification appelée SVG Strokes .À partir du projet de rédaction SVG 2.0 du 26 février 2015 (et peut-être depuis le 13 février ),
laavec les valeursstroke-alignment
propriété est présenteinner
,center
(par défaut) etouter
.Il semble fonctionner de la même manière que la
stroke-location
propriété proposée par @Phrogz et lastroke-position
suggestion ultérieure . Cette propriété est prévue depuis au moins 2011, mais à part une annotation qui dit, il n'a jamais été détaillé dans les spécifications car il a été reporté - jusqu'à présent, semble-t-il.
Aucun navigateur ne prend en charge cette propriété, ou, pour autant que je sache, aucune des nouvelles fonctionnalités de SVG 2 pour le moment, mais j'espère qu'elles le seront bientôt à mesure que les spécifications mûriront. C'est une propriété que je réclame personnellement d'avoir, et je suis vraiment heureux qu'elle soit enfin là dans la spécification.
Il semble y avoir quelques problèmes quant à la façon dont la propriété doit se comporter sur les chemins ouverts ainsi que sur les boucles. Ces problèmes prolongeront très probablement les implémentations sur les navigateurs. Cependant, je mettrai à jour cette réponse avec de nouvelles informations à mesure que les navigateurs commenceront à prendre en charge cette propriété.
la source
stroke-alignment
est spécifié dans SVG Strokes, un document de travail du W3C. Pendant ce temps, l'ébauche de l'éditeur SVG 2 W3C indique qu'une propriété de positionnement de trait doit être dans la spécification SVG à svgwg.org/svg2-draft/painting.html#SpecifyingStrokePaint , mais cette spécification a déjà atteint le statut de recommandation de candidat W3C et aucune propriété de ce type n'est dans la spécification en dehors d'un lien vers lastroke-position
proposition, ce qui ne semble pas être le cas.J'ai trouvé un moyen facile, qui a quelques restrictions, mais a fonctionné pour moi:
Voici un exemple de travail:
la source
<use>
? Pourquoi ne pas simplement insérer directement le chemin et le chemin du clip? Cela fonctionne très bien:<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>
. (Oui, c'est SVG tout à fait raisonnable et correct et restituera correctement partout. Ne craignez aucune récursivité.)Vous pouvez utiliser CSS pour styliser l'ordre des traits et des remplissages. C'est-à-dire, caressez d'abord puis remplissez-en deux et obtenez l'effet souhaité.
MDN sur
paint-order
: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/paint-orderCode CSS:
la source
Voici une fonction qui calculera le nombre de pixels que vous devez ajouter - en utilisant le trait donné - en haut, à droite, en bas et à gauche, tous basés sur le navigateur:
la source
Comme les personnes ci-dessus l'ont noté, vous devrez soit recalculer un décalage par rapport aux coordonnées du tracé du trait, soit doubler sa largeur, puis masquer un côté ou l'autre, car non seulement le SVG ne prend pas en charge nativement l'alignement du trait d'Illustrator, mais PostScript ne le fait pas non plus .
La spécification des traits dans le manuel Adobe PostScript 2e édition indique: " 4.5.1 Trait: L' opérateur de traits dessine une ligne d'une certaine épaisseur le long du chemin courant. Pour chaque segment droit ou courbe du chemin, le trait dessine une ligne centrée sur le segment dont les côtés sont parallèles au segment. " (mettre l'accent sur le leur)
Le reste de la spécification n'a pas d'attributs pour compenser la position de la ligne. Lorsqu'Illustrator vous permet de vous aligner à l'intérieur ou à l'extérieur, il recalcule le décalage du chemin réel (car il est toujours moins cher en calcul que la surimpression puis le masquage). Les coordonnées du chemin dans le document .ai sont des références, pas ce qui est tramé ou exporté vers un format final.
Comme le format natif d'Inkscape est une spécification SVG, il ne peut pas offrir une fonctionnalité qui manque à la spécification.
la source
Voici un travail autour de l' intérieur bordé en
rect
utilisantsymbol
etuse
.Exemple : https://jsbin.com/yopemiwame/edit?html,output
SVG :
Remarque: Assurez - vous de remplacer le
?
dans desuse
valeurs réelles.Contexte : La raison pour laquelle cela fonctionne est parce que le symbole établit une nouvelle fenêtre en remplaçant
symbol
avecsvg
et en créant un élément dans le DOM d'ombre. Celui-cisvg
du DOM fantôme est ensuite lié à votreSVG
élément actuel . Notez que lessvg
s peuvent être imbriqués et chacunsvg
crée une nouvelle fenêtre, qui coupe tout ce qui se chevauche, y compris la bordure qui se chevauche. Pour un aperçu beaucoup plus détaillé de ce qui se passe, lisez ce fantastique article de Sara Soueidan.la source
Je ne sais pas à quel point cela sera utile, mais dans mon cas, je viens de créer un autre cercle avec bordure uniquement et de le placer «à l'intérieur» de l'autre forme.
la source
Une solution (sale) possible consiste à utiliser des modèles,
voici un exemple avec un triangle intérieur barré:
https://jsfiddle.net/qr3p7php/5/
la source
La solution de Xavier Ho de doubler la largeur du trait et de changer l'ordre de peinture est brillante, mais ne fonctionne que si le remplissage est de couleur unie, sans transparence.
J'ai développé une autre approche, plus compliquée mais qui fonctionne pour n'importe quel remplissage. Il fonctionne également dans les ellipses ou les chemins (avec les derniers, il y a des cas d'angle avec un comportement étrange, par exemple des chemins ouverts qui se croisent, mais pas beaucoup).
L'astuce consiste à afficher la forme en deux couches. Un sans contour (remplissage uniquement) et un autre uniquement avec contour à double largeur (remplissage transparent) et passé à travers un masque qui montre la forme entière, mais masque la forme d'origine sans contour.
la source