ChatGPT解决这个技术问题 Extra ChatGPT

Fixed stroke width in SVG

I would like to be able to set the stroke-width on an SVG element to be "pixel-aware", that is always be 1px wide regardless of the current scaling transformations applied. I am aware that this may well be impossible, since the whole point of SVG is to be pixel independent.

Context follows:

I have an SVG element with its viewBox and preserveAspectRatio attributes set. It looks something like this

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

This means that when I scale that element, the actual shapes inside it scale accordingly (so far so good).

As you can see, I have set up the viewBox so that the origin is in the center. I would like to draw an x- and a y-axis within that element, which I do thus:

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

Again, this works fine. Ideally, though, this axis would always be only 1px wide. I have no interest in the axes getting fatter when i scale the parent svg element.

So am I screwed?


Z
Zach Saucier

You can use the vector-effect property set to non-scaling-stroke, see the docs. Another way is to use transform(ref).

That will work in browsers that support those parts from SVG Tiny 1.2, for example Opera 10. The fallback includes writing a small script to do the same, basically inverting the CTM and applying it on the elements that shouldn't scale.

If you want sharper lines you can also disable antialiasing (shape-rendering=optimizeSpeed or shape-rendering=crispEdges) and/or play with the positioning.


Unfortunately this is in a XUL app, and that doesn't seem to support vector-effect yet. Oh well.
This should appear in Firefox 15 all being well so you should be able to use it once you build your XUL app on gecko 15.
IE11 still doesn't support vector-effect property. Is it possible to achieve the same effect as vector-effect: non-scaling-stroke in IE11?
@merlin yes, with js it's possible to emulate this in IE.
@merlin clone the element (setting fill to none and vice versa for the stroke), compute & set the appropriate transforms (one for the fill part and one for the stroke part). It's going to be a little messy for sure, but there it is - you might also want to ask Microsoft to add support for it. In any case I think your question deserves to be a question of its own.
s
supersan

Here is a more concise answer based on Erik's answer to help you get started quickly.

Adding the vector-effect="non-scaling-stroke" to the SVG rect makes the border size (or stroke size) fixed.


关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now