Video details

Chain React 2018: Using SVG in React Native by Ori Harel

React Native

Vector graphics is in fact the best way to provide great visualization and interaction combined. It exist on all platforms in some way or form, so it's just natural to use it in React Native. In this talk, I'll show you how I integrated the use of SVG with the opinionated component and state system of React, but in the same time keeping things highly performant when interacting with the UI thread - a topic a lot of developers are struggling with.


One of the benefits of speaking so late in a conference that I get to see my friends. We are not strangers anymore. So hello, friends. First of all, I want to start with a question that I've been curious about. How many of you came to react native from native development. Please raise your hand and how many from front end? Javascript. Wow, 50 50, I say. Oh, good to know. So finally, a real step. So today we're going to talk about how to implement those graphics, SVG graphics inside the React Native app. So we're ready to talk about SVG. Let's go for it. So my name is Oi. I'm a software developer at a company called Capriza. For the last year or so, we've been very busy doing React native. I'm going to talk about it a little bit, but before that, I was busy doing front end development for a few years and before that, Android native development. So I kind of got the grasp of both worlds, native and front end. If you want to look me up on social media, Twitter, whatever, this is my handle. One more thing. I came from Israel, which is pretty far away. So quick note about Capriza company I work for. So Capriza is a company and we made the system called Approve simple, which consolidates approvals from various It systems in an enterprise. So we sell to enterprises. We built an app from the ground up in React native for the last six months. This particular app we built in the first three months we got it up and ready in the App Store and it all evolves around this nice carousel. So we had a lot of good journey with the flat list and scrolling. You can ask me all about it after. So today's talk is going to be a two part talk. We're going to first start off with some basics about SVG and vector graphics, talk about what's happening in the web and what's going on in Native and React native. The second part, I'm going to share some stories I have regarding animations with regarding lack native SVG. So let's start off. So how many here are familiar with SVG from the web? Wow, great. So I'm going to quickly cover it. Before we're talking about SVG, let's talk about vector graphics. Why do we care about vector graphics? So if you care about complicated graphics, complicated visualizations. Right now in our plain React Native app, you have the view object, which is you can style it, you can style the height, the width, border shadows. It's pretty much it's pretty much limited in the sense of what the designer is providing in his tools. You can also go with images, but that's also limited. You cannot control the color of the images. It won't scale. You have to put in an image for every resolution and every screen size. If you want to do animations, then forget it. You have to add an array of images and pose a burden on the bundle size. Also very important most chances if your designer is already using some sort of vector graphics powered tools such as Photoshop, Sketch. And that's actually those considerations applied for all platforms, not only mobile web also. So that triggered this SVG and Web too. So what is SVG? It stands for Scalable Vector Graphics. It's been a web standard for a while so it's 90. 99. It's pretty old. What it is is actually XML based markup graphics. So we all love XML based markup. It's the parent node and the child node. Html works like that. The native works like that. Of course. React and react native. Very simple to use. Actually there are some amazing stuff that you can do just with SVG. I don't know if you're familiar with this graphics, but that's actually SVG. So we just hit up the Inspector for all of you web developers. So you can see that it's compounded of 1000 of elements. You can start playing around with it, see what happens. I really enjoy it. And there is a very good documentation on web in Mdn. If you want to learn about SVG, I really recommend you're check it out. It's very friendly, written, unlike documentation in usual, if you check it out you are covered in terms of knowing SVG. So some basic example in Web, a little bit of web code. We haven't seen a web code here, so just a little bit you have the wrapping element of SVG. It has several attributes to name a few. Width, height, all documented, some basic shapes, rectangle, circle text. There is a positioning system which is kind of similar to the absolute positioning system of CSS with the top left corner coordinates of zero. And as you go to the bottom to the right you get the positive X axis and y axis accordingly. This example, you can see the blue rectangle position on 2.5 and 2.5 coordinates. One special element to note and actually this is where all the magic of SVG lies in is the path element. So path element what it is actually it has the D attribute which is a series of commands, the originating point of M and then series of commands of lines and curves. This actually what enables to draw anything on screen. And this is very very simple example, there is this line, it originates in some .2 and two, and those are two shortened ways to write the curves. It can get complicated really fast. Just see this naive looking icon and this is what it takes to draw it. So a little bit about that later. Moving to native. So actually native graphics already are built upon vector graphics techniques. So even when you just draw a default button, it draws into a canvas in some sort of vector graphic way. It has to be like this in order to support the various resolutions and screen sizes. In Apple, there is a core graphics, and on Android the Android graphics. Just an example for you. Android native developers might find this familiar. If you want to draw, you want to bypass all the default widgets you want to draw directly to the screen. So you extend the Drawbull class and inside the Draw method, just as you saw the series of commands of the D attribute in the path, you see a series of method devocations to draw a path element. Over the course of time, there were some abstractions on top of it. There is a very famous third party plugin in, and on Android, actually, the official SDK already have a new library called Vector Drawvo, relatively new, which starts to looks like SVG in terms of markup language and elements. However, those are different elements, not SVG. So React native actually React Native ships with the vector graphics library called out. It's not exactly SVG, it uses different components, but it's in React native, and it works close platform. On iOS, you have to manually add it because it caused some sort of burden on the bundle size. Another way to go, and actually the more recommended way is to use this package called React Native SVG. I'm going to talk about this package from this point on, some word about this package. It's maintained by these two main contributors, Magic is Might and Michael Sand. And what's good about it? What's beautiful about it is confirmed exactly to the web stand up of SVG. So if you know SVG from your front end days, you know SVG in React native. And that's the point of this package. It's already included in a React native community. You can import it straight out of Expo. If you're using Expo, it has rich documentation and it even supports touch events, which is a very important mobile apps. So this is the same example that we saw in Web. This is in React Native SVG. So as you can see, it's the same thing. We're using the same elements, we get the same result with the same attributes. Another neat thing that you can do with SVG, and this is done in React native SVG is some tricks you can do with text. So we are using the depth element, which you can draw elements in line without drawing them on the screen. And by using the text path, we can just refer to the path element and make the text flow across that path element. So quick note about what's going on under the hood. So a regular native view bridge, as you may know, consists of view elements on the JavaScript side, which maps to some elements, some objects on the native side, mainly the View manager and the view. So every view on the React native side maps to view on the native side. However, in React native SVG, things work a little bit differently. So for every view or for every element on the SVG, it doesn't map to a view, it maps to the shadow node we saw on RAMSA. Doctor is a shadow thread. So in the shadow node, it manages the imperatively calling of the canvas. So basically it's a class. That what it does. It draws into one global canvas on screen using the pet limit that it invokes. However, SVG is a lot more than just basic elements, right? We can do rectangles and circles without SVG, but one of the most popular usage of SVG is drawing charts. So I hope by now you're all hypnotized and I can say whatever I want now. So when one talk about charts, the word D three comes out really fast. So how many of you here are aware of D Three? Yeah, I was expecting that so quickly. D Three, a JavaScript library for dynamic data visualization. It's originally made for the browser and it has browser APIs inside it, so you couldn't use it outside of the browser. But as of version 4.0, they made some module separations and some of the modules just generate data. So other platforms outside of the browser, such as React Native can now use D three in order to generate those long de attributes and use them. So we're going to see some example. We're going to show example regarding Pi, let's pick the pie example. So suppose we have like a demo data and array with three items. Every item has a number and a color. So we start with a wrapping SVG element and for each item in the array we create a path element. And for the D attribute we are using the D three API. So I'm not going to dive too much deep into the D Three. It's a reason for a different talk. I really recommend you to check out Sherry Wood's talk from React Amsterdam. I think it was this year. She talks about how to code these three with React and how it behaves with the state and the components. Really highly recommend it. So this is how we get the pie rendelled. That was very quickly an SVG overview. So what I'm going to talk about now is how to animate those. So those graphics are really boring if they're not moving on screen, right? So let's talk about animations. So first, the good news is we get to use the animated API that we all love, hopefully. So we all know that in order to use animated, we need to create animated values, those numerical values that we can animate from one value to another value if we want. We can even animate string values by using the interpolate and it even lets us add some text to it, which the style sheet sometimes uses. So as long as it's parseride on a JavaScript parcel, then it works. However, what happens if we have to animate between those values? We saw that the path element is using these long values. Those cannot be interpolated. The interpolation API is not supporting these long string values or some other elements such as direct which have all sorts of attributes that receive objects. So in this example, an array, two items in an array and what happened? How can we animate that? So those are the challenges that I faced in the last few months doing SVG and react native. So I'm going to cover three use cases in animations that hopefully will give you some tools to overcome those challenges. So first let's talk about the basics. So a basic example, we just want to animate single value. So no problem there. I just want to show you that it does work on the default case. So we interpolate. We are animating the X value of the rack animated. We are creating animated racks and we interpolate the zero and one to five and two and 20 and we push it to the X value. So that was the simple case. But suppose we want to animate the pie. So in order to animate the pie, as I told you, the pie consists of several slices. Each slice is a very long and complicated D attribute. So how can we animate that? So what I did, I took a look in the D three APIs and I looked for some value that I can increase over time, a very single value that I can increase over time that will let me animate it. So I found that multiplier of the end angle in the Pi API, whatever that does. And if I increase it, the pie gets more percentage. So this is what I did. In order to do that I'm using a wrapping element called slice, creating an animated component out of that and the animated value is 0.1 until two like we saw that's the multiplier and I'm going to push that animated value into that animated slice and slice is very simple, wrapper around the path element that we saw and I'm just going to propagate the animated angle into the create by slice method which now looks like that. So it receives a third parameter. Now it will invoke the D three API with that additional parameter. So this is how we get the animation a third use case. So that's a wrecked element in SVG. And what I did here, I did some manipulations on stroke. There are various strokes attributes for SVG that you can manipulate in order to get this effect with the underline in one state and the entire bode will drawn on the next state. So what we want to do is we want to get from this state into that state. So we have to change few properties, right? So they're all stroke properties. So the first few properties, no issues there, they just receive single values. The first receive numerical values, the second receive the string value. So no problem interpolating that. However, the stroke array receives an object and how can we animate that object. So what I did here I had to drop the declarative approach and move to imperative approach which is kind of a reasonable hack in animations so I'm not using it on the prop level of the component. Instead I'm using another API of animated value called add listener. I'm using animated value XY in order to create two values instead of one and for every tick in the animation the listener gets called and I am relatively using the set native props on the ref element and this is how I just change the value. So this is another technique how to overcome the interpolation challenge. So those were my three challenges in animating React native SVG. There might be other challenges that I didn't encounter but I got to a point where I just randomly looked for cool animations on web and within ten to 15 minutes I just threw it in my react native app using one of those tricks or techniques. If you want some of you may ask whether those animation support use native drivers so we all strive to move all the heavy lifting of animations from the JavaScript side into the native side, right? The bad news is it's not supported yet. However it is very much work in progress. So if you can check out this work and inside a repository of React native SVG you can see already a working example it's done in a different branch but it's a working example of animation on a wrecked with guess what unitive driver crew if you can see it so there is hope you can check out those examples in the GitHub repo that I made for this talk and hopefully you saw some cool tricks that will let you use react native and SVG and what's important is you can just keep leverage your knowledge or already existing knowledge from web regarding SVG inside the react native app. Thank you, that's my talk.