SVG Tutorial
svg-tutorial.com
svg-tutorial.com
e.g., doing hover effects in Canvas is a huge pain because you have to do all the work to figure out which element the mouse is on top of. With SVG you just use builtins like onmouseover!
One of the biggest downsides is that there is none of the percentage-based sizing that you get with HTML. Otherwise, it could replace HTML for virtually everything.
The problem, of course, is that there's not really a good way to do dynamic sizing if you want to be able to change the aspect ratio, which is where layout engines like Grid and Flex become so useful in HTML / CSS. But in my (fairly limited) experience, if I'm reaching for SVG it's because I need the tight control that comes with it, so it hasn't been an issue for my own projects.
I code the patterns that I cut on my GlowForge using React & SVG.
Works great.
This sounds like an area I would enjoy a lot but am barely a beginner in React. Any working examples that might give me the right direction / inspiration ? Thanks
I can't promise that it's like, the best code or the best approach to the problem, but I did get the component working, which is worth something. Check it out - I'd love to hear what you think!
[1]: https://epiccoleman.com/posts/2023-04-05-svg-circle-of-fifth...
[2]: https://epiccoleman.com/posts/2023-04-14-circle-of-fifths-in...
Minor nitpick @clip-path; they propose the following code:
<svg width="200" height="200" viewBox="-100 -100 200 200">
<defs>
<clipPath id="ball">
<circle cx="0" cy="20" r="70" />
</clipPath>
</defs>
<circle cx="0" cy="20" r="70" fill="#D1495B" />
<polyline
clip-path="url(#ball)"
points="-120 40 -80 0 -40 40 0 0 40 40 80 0 120 40"
fill="none"
stroke="#9C2D2A"
stroke-width="20"
/>
<circle
cx="0"
cy="-75"
r="12"
fill="none"
stroke="#F79257"
stroke-width="2"
/>
<rect x="-17.5" y="-65" width="35" height="20" fill="#F79257" />
</svg>
But that means describing the big circle twice. If you want to change the size of the circle you will have to modify it in two places. Since we're already using defs it would be better to write this IMHO: <svg width="200" height="200" viewBox="-100 -100 200 200">
<defs>
<circle cx="0" cy="20" r="70" id="round"/>
<clipPath id="ball">
<use href="#round"/>
</clipPath>
</defs>
<use href="#round" fill="#D1495B" />
(rest unchanged) <svg width="200" height="200" viewBox="-100 -100 200 200">
<defs>
<clipPath id="ball">
- <circle cx="0" cy="20" r="70" />
+ <use href="#round" />
</clipPath>
</defs>
- <circle cx="0" cy="20" r="70" fill="#D1495B" />
+ <circle cx="0" cy="20" r="70" fill="#D1495B" id="round" />
(Personally I’d also drop the <defs>-wrapping. Never did understand why structuring them that way is recommended, I don’t think it actually gets you anything except for the vanishingly rare case where you want to put something that would render if it were not in a <defs> tag—I say “vanishingly rare” because situations like you showed—//defs/circle—should normally actually use <symbol>.)Like some of the other commenters here, I've found a lot of fun in building React components that are backed by SVG. React and JSX make it easy to add the interaction, and SVG lets you do some pretty cool UIs that wouldn't be easily possible with just HTML.
I actually have published a React component that renders an interactive "Circle of Fifths," which I built for a music theory side project I was working on (although this project is currently languishing among many other half-baked repos). There's still a lot to do with the component, but it's in a usable state[1].
I wrote what I think is probably my best blog post[2] about the process of figuring out how to build the Circle of Fifths with SVG. I'm particularly proud of the little explainer section in the middle that follows the drawing of a somewhat complex <path> element.
I'm currently building out a fretboard diagram generator using a very similar approach, and having that post on hand for reference has been pretty useful. This is maybe my favorite thing about writing up the stuff I work on, it's nice to be able to "replay" how I thought through a problem.
[1]: https://github.com/epiccoleman/react-circle-of-fifths
[2]: https://epiccoleman.com/posts/2023-04-05-svg-circle-of-fifth...
The <foreignObject> tag is especially useful, as it allows you to put normal html inside svg, so you can use html for things that html does better (links, images, basic flexbox styling etc) within a svg art project.
For the author, btw, a few links on the site are not working: your bio.link on the bottom of the page, and in Day 11: How to Draw Quadratic Bézier Curves with SVG, there is a link to an interactive bezier curve demo that is down.
As for foreignObject, I also didn't knew about it. That's awesome
> walk across the hall to get the hex codes for the other color
What’s messing with me is that you seemed to have a computer that drew hex colors. Also, you knew the hex value you wanted. Kinda hate second guessing your actions from the 20th century but why did you walk?
There was a green version as well. I don't really remember why I didn't have a green graphic that I could pull the correct values from. I just recall going across the hall to talk about a Green version of the graphic and with the designer we changed the value in the SVG code instead of Illustrator (Or whatever program he was using.)
As for "Why walk across the hall?", there are times when going to someone's desk to discuss a situation is faster and more effective than an email or a chat.
Personally, I'm partial to path which can do almost anything and tends to be less verbose than other methods.
Long time student, but I see that I still have lots to learn.
I suck so much at drawing and dislike images so much that for ease and performance, I built my entire side project with svg.
After today, it looks like I have quite a bit of refactoring to do. Thank you, OP!
For instance, does anyone know why the thumbnail preview does not work on Twitter? It works with the sub-pages.
Alignment is a trip, let me tell you...
While I've played around with Inkscape, I'm definitely on the "writing XML" side of the fence in order to create what I need.
I know there is text anchor: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/t...
And someone suggested the foreignObject tag that might be useful here: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/for...
Recently, I've been using Standard Ebooks' toolkit to convert my Master's Defense into EPUB. SE uses SVG as its image format for covers - along with a few scaled JPGs. Unsurprisingly, all of this starts out as text and there is extensive use of text-anchor to get the alignment right.
Although they use XHTML as the primary input format, foreignObject is a concept I haven't encountered before, might be worth checking out...
https://standardebooks.org/contribute/producing-an-ebook-ste...
[0] GitHub link in profile.
Inkscape's alignment functions works for me. For things where I needed more precision, what I do is press ctrl+shift+x and type in the coordinates there. (Inkscape's XML editor seem to crash very often for me, but it's workable if I remember to save after every edit).
I know people use it and like it, but in trying to get something done in a way that would save time, this approach didn't really click for me.
Had to do quite a bit of work to get filesizes down to something reasonable for:
http://shapeoko.github.io/Docs/
One late development was working up a mechanism where an image could be clicked on to open it in a new window:
http://shapeoko.github.io/Docs/content/tPictures/PS20028-100...
and then the part names in the parts list could be clicked on to highlight the matching part in the diagram.
For complicated shapes/curves I'll sometimes run it through an online editor to help visualize, this is a good one: https://yqnn.github.io/svg-path-editor/
Unlike Illustrator/Sketch/Inkscape it can also create and manipulate SVG animation elements (https://boxy-svg.com/blog/21) - a very powerful feature which is now supported by all major browsers.
It seems like a fairly straightforward mapping of UI -> SVG features, which must have taken a ton of effort. I'll have to take a closer look at the animation tool, I've often wondered if web technologies would ever get close to Flash's capabilities.
For something like this bell example (https://svg-tutorial.com/svg/bell), you can certainly hand-code it if you're really math-inclined and can estimate the formulas of curves just by looking at them, but for us mere mortals, it's easier to just draw out the curves in a graphics app (like https://youtu.be/5x2uHUB_pzw?si=fSLjRKlZNgVKVcOx&t=123 for Figma) then export as an SVG. And for things like the ringer (is that what you call it? the orange ball thing at the bottom of the bell that strikes the bell to make the sound), being able to visually draw it on a canvas, change its size, drag it around and play with its colors and dimensions, etc. is really helpful. Figma is fine for simpler graphics, but it's really more of a UX tool than a graphic design tool, and Illustrator is a lot more powerful. Inkscape is a FOSS option.
In other circumstances, though, manipulating the SVG XML directly is also very helpful. Let's say you want to programatically generate a bar chart. If you have a big dataset, it's going to take a designer forever to manually plot them and change them every time the data changes. But it's easy for a dev to use Javascript (or any language) to draw each rectangle, programmatically adjust their heights and colors based on the data, add tooltips, etc. And that way you can dynamically update them in real-time whenever the data changes (like if the user selects a different date range, or new events come in). A lot of this is made easier by libs like https://frappe.io/charts or https://apexcharts.com. But before you take that approach, you should know that for complex charts, sometimes Canvas rendering (or just generating graphics in the backend) can be more performant than SVG.
SVGs can also be animated and interactive, not just with CSS transitions but by directly manipulating the XML geometries, like http://snapsvg.io/demos/ or https://www.svgator.com/ or https://codepen.io/collection/XpwMLO/. This is fine for product pages and such, but for really graphics-intensive apps (full games) it's probably slower than other rendering pipelines. (Not my specialty, won't speculate too much.)
TLDR Drawing them in a graphics app is usually easier for the designers, but the XML can be programmatically manipulated afterward to great effect. The ideal workflow depends on what you're trying to accomplish, and also who you have on your team.
The "clapper".
I am still on the steep end of the SVG learning curve, but also generally start in Illustrator and then export, clean up, and hand-code the details.
I dunno specifically if that’s first class or webpack is covering it, but it really feels good in a few cases to make an SVG component with some logic built in. So now I can have an SVG and some react-driven logic modifies its shape, colour, omitting sections of it, etc.
But when you online SVG code, the browser can't cache the image. So if the SVGs are larger, or have only a few variations, you may prefer to have a separate endpoint for each image variant.
https://chat.openai.com/share/49e91be6-bdef-4f4d-a263-80a884...
At least if they're in the same JSX component, the server can gzip that SVG string so it's not as big over the wire. But if the same icon gets used in different pages, the costs multiply.
It's nice to have the OPTION of treating SVG as code when you want it to be code, but otherwise, it's better for the user to treat it as a graphic and let the usual caching mechanisms (server+browser) do their jobs.
One of the examples in this tutorial is also a data-driven diagram generated from React. You can do pretty cool things by combining the two.
One niggle: They refer to the SVG "tag." I had started HTMLing in the mid-1990s, and we always called everything "tags."
Then, XHTML came in, and people started screaming at us for calling them "tags." They were elements, dammit!
I say "element," these days, but my brain still says "tag."
I mean what is worse? Incorrectness, or losing ad revenue :-)
I have done a ton of tutorials, myself, and have found that using vernacular, and expressing in basic, readable language, always works best. Being too pedantic can make it seem "stilted."
But, yes, SVG is an application of XML.
I never used "tag" properly, then.
But for complete elements, like <br /> or <hr />, would it be proper to refer to them as "tags"?
This is why you have DOM functions like “getElementsByTagName”, which allows you to say “I know the tag name is “hr” (and the tag is <hr />), but I want to get references to all the elements which are defined by that tag.
As a general rule, if you’re thinking about a “thing” on a webpage, you’re think about an element. If you’re thinking about what you need to write to get that element to appear on the webpage, you’re thinking about a tag.
Most of the time, folks will understand what you mean even if you use the wrong one though.
[1] https://www.w3.org/TR/xml/#NT-EmptyElemTag
This is obviously not as flexible as true SVG, but it is familiar to author for anyone who's written a React application. I've used it on the backend to generate match reports for League of Legends [1]
Might be hard to believe, but some folks want to learn stuff and understand how things work under the hood, which is a group that OP's site appears to target.
Examining the output seems like another interesting way to learn SVG until one can speak it natively.
> Might be hard to believe
This is condescending and unhelpful.
As usual, a lot of these things I could learn if I decided to, but it’s nice when someone puts it together in a pretty package and shows up on HN.
For Day 10, I don't see a snowman. I think you lose the background somewhere so it's white on white, I'm on my phone though so I can't dig in too far.
I took a look on my desktop and I can just barely see it. I think if you kept the blue background it would be easier on both platforms.
- Lesson content section has unnecessary horizontal scrollbar visible
- No visual distinguishing or handling for scrollable area (vs the finished display area) had me trying to scroll with my mouse hovering on the lefthand side often, and momentarily confused why it wouldn't go. Make the whole main body section scroll the content, ideally.
I'm not sure where you see horizontal scrollbars though. Are you on Windows?
I want to render them to a canvas with different (dynamic) color configurations and I'm exploring different ways to do this.
I'm pretty sure I've heard of D3, I'll have to check it out. Thanks.
- How to Draw Basic Shapes with SVG - https://svg-tutorial.com/svg/basic-shapes
- How to Build a Christmas Tree with SVG - https://svg-tutorial.com/svg/polygon
- How to Make a Gingerbread Figure with SVG - https://svg-tutorial.com/svg/gingerbread-figure
- How to Build a House with SVG - https://svg-tutorial.com/svg/house
- How to use clip-path with SVG - https://svg-tutorial.com/svg/clip-path
- How to Draw a Basic Path with SVG - https://svg-tutorial.com/svg/basic-path
- How to Draw a Star with SVG - https://svg-tutorial.com/svg/transform
- How to Draw a Snowflake with SVG - https://svg-tutorial.com/svg/use
- How to Draw a Forest with SVG - https://svg-tutorial.com/svg/forest
- How to Use Gradients with SVG - https://svg-tutorial.com/svg/gradient
- How to Draw Quadratic Bézier Curves with SVG - https://svg-tutorial.com/svg/quadratic-bezier
- How to Draw Cubic Bézier Curves with SVG - https://svg-tutorial.com/svg/cubic-bezier
- How to Draw a Bell with SVG - https://svg-tutorial.com/svg/bell
- How to Draw an Arc with SVG - https://svg-tutorial.com/svg/arc
- How to Draw a Ribbon with SVG - https://svg-tutorial.com/svg/ribbon
- How to Draw a Bear with SVG - https://svg-tutorial.com/svg/bear
- How to Draw Text Along a Path with SVG - https://svg-tutorial.com/svg/text-path
- How to Animate Along a Path with SVG - https://svg-tutorial.com/svg/path-based-animation
- How to Add Animation on Hover of an SVG element - https://svg-tutorial.com/svg/animation-on-hover
- How to Animate a Snowing effect with SVG and CSS - https://svg-tutorial.com/svg/snowing
- How to Create Background Patterns with SVG and CSS - https://svg-tutorial.com/svg/background-pattern
- How to Draw a Clock with SVG and JavaScript that Shows the Actual Time - https://svg-tutorial.com/svg/clock
- How to Add Interaction to SVG elements with JavaScript - https://svg-tutorial.com/svg/interaction
- How to Generate an SVG Diagram from JavaScript - https://svg-tutorial.com/svg/data-driven-diagram
- How to Break Down an SVG Image into Multiple Components - https://svg-tutorial.com/svg/multiple-components
Generated by running this in Firefox DevTools:
copy(Array.from(document.querySelectorAll('.day'), el => {
const title = el.querySelector('.title').textContent;
const url = el.href;
return `- ${title} - ${url}`
}).join('\n\n'))https://developer.mozilla.org/en-US/docs/Web/SVG/Element/sty...
And SVG elements can have classes: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/c...
oh wait, it's december. no i don't xD