Render a hearthstone card using React and SVG.

Written by juli | Published 2017/02/28
Tech Story Tags: svg | react

TLDRvia the TL;DR App

Ever wondered how to render a hearthstone card using React and SVG?

What are you saying? That question is too specific? Well … even if you’ve never asked yourself how to render a hearthstone card using React and SVG, now you have the opportunity to learn about how to mix and mingle Hearthstone, SVG and React. Let’s get right into it!

We’ll start from a couple of spare card assets, mix that styled text and end up with a beautiful SVG and React powered mech-goblin card.

Layout card elements

The first task we have to do is to turn all the separate card elements like cost, frame and title into something that looks like a card. How do we do that? Well we have several options to layout elements and we have to choose one of them. We could arrange them using position: relative, we could use flexbox to compose those elements together or we could arrange them using SVG.

CSS has some great tools to layout elements, like position: relative; or flexbox, but I think that SVG is just better suited to laying out the separate elements that make up our card. SVG has a wide array of editors that let us arrange stuff visually instead of playing with raw pixels or playing with flexbox properties. Also SVG markup can be easily embedded into React components.

Composing together the elements and exporting the result we can achieve a neat card frame like the following:

And here is the created React component:

Round the card image

We have a card frame that looks almost exactly as a Hearthstone frame, except for the ugly square border around the card image. How can we remove that?

Easy! Using SVG’s <clipPath />. To clip an SVG element based on another, we can add it a clipPath attribute referencing another element. So we'll add clipPath="url(#image-clip-path)" to our Piloted Shredder image.

See the diff here.

Thank god that border is gone!

Show variable text

This card frame only needs some card text and it will look exactly like a real card! Fortunately it’s very easy to add text to it, we just add some svg text tags and interpolate its value with JSX.

See the diff here.

The sky’s the limit now that we’ve introduced variable text onto the card!

Styling the text

Sure, the card has some text now. But it looks nothing like the real hearthstone text. It needs some spice and style, so we’ll go ahead and add it.

Turns out the magic sauce that makes hearthstone text look like hearthstone text is the Belwe font! We’ll set the text to use this font family, give it a white fill and a thick black border and that’s it!

As always, here is the diff.

That’s some good looking hearthstone looking text!

Making the title flow through

Now those are some really good looking cost, health and strength values! But that title looks too stiff, it doesn’t look quite right, it shouldn’t be drawn in a straight line; so we’ll make it flow by following an imaginary squiggly line.

Again SVG gives us the right tool for the job, this time in the form of textPath, who can make text be rendered along the shape of a <path>. So I created in my SVG editor a <path with fill="none" and referenced it in the title using textPath.

See the diff here

Title’s got some sick flow now!

Wrapping up the text

We’ve been trying to ignore the fact that the card’s body text has html tags and does not wrap around the card edges. That’s the last detail that we need to make our bag of images and text look exactly like a hearthstone card.

Using HTML this would be as simple as putting the card text inside a div, but there is not a simple way to make automatically wrapped text in SVG. Even though this cannot be easily done in SVG, we can effortlesly embed an HTML snippet in our SVG markup using <foreignObject />.

Another thing we have to do is transform our HTML string into a react element. Fortunately this can be easily and safely done using html-to-react.

This is how we parse the card text string into a component and embed it using <foreignObject />.

Check out this diff

It’s a wrap!

We went from a few spare parts to a beautifully rendered Hearthstone card and learned some SVG and React tricks in the process. We learned that SVG is great at generating visual content, that React is great at giving dynamism to SVG and also saw that rendering a hearthstone card using both tools is really simple.

Check out the source code if you want to see the final result! You can also see it live in https://render-hearthstone-card-react-svg.now.sh/.


Written by juli | I write, I read, I learn.
Published by HackerNoon on 2017/02/28