lr123
lr123

Reputation: 1650

Scaling SVG coordinates, but not elements

I have a bunch of <circle> elements, and I want to zoom in on them.

I want to go from this:

To this:

Notice that I'm not enlarging the circles, only the distance between them.

How can I efficiently do this? What I'm doing right now is to setting the cx and cy coordinates individually on each circle. This works, but is slow when I've got thousands of circles.

I can put them all in a <g> and scale that with transform: scale(x);. This is a lot faster, but it will scale both the distances and the size of the circles.

Is there any way to scale the coordinates independently of the circle radius? Can I specify the circle radius in units that relative to screen size, for instance?

I'm using d3 for this, but any solution is appreciated.

Upvotes: 0

Views: 496

Answers (1)

Paul LeBeau
Paul LeBeau

Reputation: 101820

The simplest approach IMO is to use zero-length lines, with rounded end caps, to form your circles. You set their diameter using stroke-width. Then you can use vector-effect: non-scaling-stroke to prevent them from scaling when you enlarge the SVG.

https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/vector-effect

vector-effect is supported by most modern browsers.

svg {
  background-color: black;
}

path {
  fill: none;
  stroke: #ccc;
  stroke-width: 5;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}


path:nth-child(3) {
  stroke: plum;
}
<svg width="100" viewBox="0 0 100 100">
  <path d="M 20,20 h 0"/>
  <path d="M 20,40 h 0"/>
  <path d="M 30,50 h 0"/>
</svg>



<svg width="200" viewBox="0 0 100 100">
  <path d="M 20,20 h 0"/>
  <path d="M 20,40 h 0"/>
  <path d="M 30,50 h 0"/>
</svg>

Upvotes: 4

Related Questions