Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Scaling SVG Elements (wattenberger.com)
120 points by wattenberger on Nov 25, 2019 | hide | past | favorite | 36 comments


Cool visualization! Any plans to do more examples of SVG? There's lots of functionality in the format and it would be neat to see it documented in an interactive style like this.


I totally agree! I'm planning a video course on SVG, since there really aren't many good resources on it and I find it really powerful, and also fun!


This is a really beautiful way to demo this feature. Thanks!


For a constant height, why do width values between 0 and 100 cause (x axis) displacement, but width values above 100 cause scale reduction in both dimensions?

(A similar phenomena can be observed for a constant width while varying the height values.)


Good question! I'm trying to find a good way to explain this bit in the guide.

This is due to the preserveAspectRatio property on the svg element. Its default value is `meet`, which scales the svg with three rules:

- aspect ratio is preserved - the entire viewBox is visible within the viewport - the viewBox is scaled up as much as possible, while still meeting the other criteria

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

If you fiddle with the attribute value in the Dev Tools, try setting it to `xMinYMid` or `none` to see if that gives you a good sense of how it works. I'm worried that it might just confuse if not explained well :)


Thank you for the explanation (and for the cool visualization, btw).

It seems that preserveAspectRatio is an important part of understanding viewBox. IMO, it deserves a spot on the telescope's controls. I think a value of `none` might be the best starting point; all of the settings that result in combined scaling and displacement are less intuitive and likely harder to understand at first exposure.

Aside: Even if you decide to keep `xMidYMid ` as the default value for preserveAspectRatio, it seems that you ought to list it explicitly if you wish to specify a meetOrSlice value as Chrome is currently complaining with your existing preserveAspectRatio="meet":

  react-dom.production.min.js:978 Error: <svg> attribute preserveAspectRatio: Unrecognized enumerated value, "meet".


I'm current using Vue to manipulate a complex SVG as the foundation of my current game engine. It's not super snappy but it's effective and interesting. I've taken the concept pretty far and, thus far, I haven't see anyone else manipulating SVGs with Vue (or React or whatever) in this way before. Its surprising because it feels extremely intuitive.


I've worked with hardware accelerated vector graphics engines (2D GPUs). It sounds like a good idea to do everything vector, because some things are very simple while retaining quality as you said. But in my experience, the vector operations are so expensive compared to raster ones that you go back to rasters to maintain framerate.


Yes, even my relatively simple scenes are expensive to render. I'm hoping I can optimize it enough to be playable.

An interesting plus side: I can export the SVG as a file and get an extremely high quality screenshot.


How "simple" are they? I remember so long ago, there was some amazing Flash graphics, so 10 years later, there's no way we can't get much more impressive ones.


I also use SVG from Elm for my simple games. Zoom and click-and-drag translation (and things like parallax) become trivial. And I love how you can put event listeners directly on objects.

Perfect for, e.g. board games!


I really love creating things with SVG + React! I usually will use that until things start to jank up, and then switch to Canvas, which is more annoying for interactions and debugging.

You can get pretty far before that happens - for example, here's a post representing every country in SVG. https://wattenberger.com/blog/d3#maps-and-globes


> I haven't see anyone else manipulating SVGs with Vue (or React or whatever) in this way before. Its surprising because it feels extremely intuitive.

It's not surprising because it's extremely slow! If you're doing a 2D game, Canvas will be waaaay faster and is much more appropriate.


I'm working on an app for a startup to build diagrams using SVG and React (...lots of ForeignObject elements to embed HTML forms in the SVGs, bezier curves joining stuff together, etc). It's a really nice way of building a responsive 2D diagrammatic UI.


I work with svg a lot, mostly with angularjs but also some vue recently. I have also made games with svg https://js13kgames.com/entries/spacetime


Dont use site

Moving those sliders will nuke your CPU

probably because the entire <body> is essentially just:

    <script src="/prism.js"></script>
    <script src="/static/js/20.c80b9d97.chunk.js"></script>
    <script src="/static/js/main.635019b5.chunk.js"></script>
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <script src="https://d3js.org/d3-array.v2.min.js"></script>


I don't like the architecture either, but this is one of the better sites using it that I've seen. It ran more smoothly than most non-interactive news sites, and the CPU usage was pretty much zero except when I was interacting with it.

What about your setup do you think might be causing this problem, given that very few other people are experiencing it?


Hmm, I didn't notice anything on Firefox on my Mac. I have a ton of tabs open and about and 15 programs running, including handbrake rendering some videos. I opened up Activity Monitor and watched what happened while loading and then manipulating the sliders. Nothing. Absolutely nothing budged under CPU, GPU, or Memory. The site was smooth as a hot knife through butter.

Maybe you should list your OS, your browser, and your hardware specs.


It runs fine on my crap Motorola Android. So, something is afoot with GPs device.


I also experienced performance issues when using the sliders. My whole computer acted like it was going to freeze (Firefox/ Windows)


Works fine on my ageing iPad mini. What was it about those 5 scripts that you thought would cause a problem? What machine/browser are you using?


No problem and smooth as butter in Firefox Windows.


Works fine on Android Firefox. They should put in a debounce function on the sliders so it doesn't update as it's moving.


That would undermine the purpose of the site which is to help build an intuitive understanding of the svg viewport. There is educational value in having the graphic update while the slider moves.


There is nothing preventing setting a debounce function to update frequently. For example, why would you want to calculate updates more than 30 times a second, or why would you want multiple updates during a single animation frame ( ie update faster than the browser repaints)? Debouncing is an insurance policy against insane things that you don’t want to happen. A smart debounce function can even modify itself in response to how long an expensive function is taking on average for a particular device— to increase the debounce time if there is not sufficient time to complete one calculation before another begins. I’ll go as far to say that a properly tuned debounce function that is triggered on leading edge will, if anything, decrease perceptible lag, not add to it. It will also minimize (though not guarantee w/o additional mechanisms) out-of-sequence updates. Out of sequence updates can lead to janky/confusing behavior.

— edit: I see that I went off the deep-end, assuming that you were against using debounce functions in general. I now see that grandparent was conflating debouncing and not updating until slider comes to a stop. These are of course not the same thing. Apologies. I hope my comments on debouncing are useful to someone though.


Presumably just listening to the slider state and updating some global variables is fast enough to not need throttling, but I would definitely update the SVG DOM inside a draw loop running in requestAnimationFrame since there's no point in doing it any faster than that anyway.

I'm not an expert on high-frame-rate web drawing, but I've played with it a fair amount, and AFAIK there's no need to do any fancy debouncing logic beyond requestAnimationFrame.


A need may arise if a calculation took longer than a frame. (I’ve encountered this making a little programming language that generates graphics that updates in real time as you type. I’d imagine similar issues with web based latex-> pdf generators that update the pdf as you type )


If a calculation takes longer than a frame, then you’re going to stutter no matter what you do, right? I feel like the browser will do its best to let you interact with the slider between frames, but really I can’t think of a good way to have a smooth interactive UI with calculations that take more than a frame.


ah, the joys of frontend web development!

I added a 30ms debounce, just to help out a bit. I'm seeing some serious jank in Firefox, which smells like the beginning of a rabbit hole. Hopefully I'll find some time to dig in there.


Strange. I'm on a Macbook and this page nukes my CPU on FF Nightly, but not on Chrome.


FF Developer 71.0b10 MacBook Pro from mid 2018 running Mojave, works great.


Works fine for me on FF/Linux.


Same problem here, had to restart the browser (Firefox/Windows). Ate all memory.


Also works just fine with me. Firefox on linux here.


My 2015 Thinkpad with an i5 got 12% utilitaztion?


Yeah, on an 8 core thats 100% utilization of one of the cores...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: