React Native SVG 3D Animations

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello react native developers in our last video we've built some fun svg animations well in this video we're adding the third dimension guys i hope you are well william here recording from beautiful switzerland in the past few days i've been working on building 3d projections between svg and reanimated2 and in this video i would like to show you how i've built some of these projections and how i've recreated some of the animations from the z-dog library with tight integration between gesture and learn svg and reanimate it too why on earth would we want to do that well for fun of course it might also have some practical aspects down the road and also i've noticed that every time we explore the 3d world it helps us harness and understand better the true dimension two-dimensional world and in the last video where we've built a pseudo-3d engine in react native it helped us identify bugs such as qx not working on android so it helps us with the 2d world and it these 3d explorations all started with complex 2d use cases most notably the pinch to zoom feature where we needed to accumulate across time complex transformations and we used linear algebra in order to do this and discovering this new mathematical tool made me want to explore the third dimension and in our last video regarding 3d transformations in react native link in the video description we projected four points four points representing the four corner of the react native view into the 3d world and then finding the 2d transformation for the react native view that will make the corners of the view match the position of the projected points this process is called homography and at the time because we are using reanimated v1 the algorithm we were using to calculate the 2d transformation was super crude now we could run thanks to the animation worklets in ranimid2 more complex algebraic functions on the ui thread most notably calculating the determinant of a big matrix and so that would be uh fun to uh redo such a process in really mature why not use libraries like free.gs there might be again it's really for fun and also for us to learn about linear algebra and building simple uh things to understand down the road the more complex things but it might also have some practical use cases where we want to apply complex transformations to native views or have a deep integration between the gesture renderer and the svg or react native view in this video i would like to show you some of the techniques i've used in order to build a pseudo-3d engine between reanimated2 and svg i took inspiration from the zed dog library and this library is super interesting because for some simple shapes it does like an ellipse or box it does the regular 3d workflow projecting 3d points onto the 2d space but for more complex shapes it does it plays a trick that is quite interesting which is to project key points of the shapes from the 3d world to the 2d world and then calculate the remaining of the shape based on these projected points so not your typical 3d workflow but by playing this trick we can build some fun and interesting examples redash ships process transform 3d function which is equivalent to process transform from the react native implementation but done as a worklet so you can execute it on the ui thread you give it a list of transformations same api than the react native api and as an output you get a four by four matrix you can use this matrix to go from a 3d vector to a 2d vector and this process is explained in details in our previous video about 3d transformations link in the video description so using this function from redash i would like to show you how we can build simple 3d shapes just by projecting the points of the shape onto the 2d space and then we're going to look at a more complex example where we calculate the production of key points from the shape and then we calculate the remaining of the shape based on the projected points before we get into it one thing if you're interested to learn the fundamentals of gestures and animations in react native i hope that you will check out my online course at startreeacnative.dev my goal with this course is to provide you all the tools and knowledge necessary in order to build delightful user experiences that will run at 60fps even on low end devices so if you're interested to learn the fundamentals i hope that you will check it out at start react native.dev let's build our first 3d shapes so i'm going to show you a couple of components which i created the first one is the names are very uncreative the first one is called zsvg is going to be the canva container so we pass the dimensions as as property so we have here the weave and the height of our canva and so there are some simple shapes i can show you so for instance z ellipse and the canva goes so we give it dimensions from our react native canva but internally for to simplify things it's using a canva of coordinates minus one to one and so here if i want to set the radius on the x and we're going to make it a circle first so if i want to set the radius on the x axis maybe i can use 0 5 0 4 and for the y so let's make it a circle so same radius on the x and y axis so we have a stroke weave which is zero one and stroke we can just pick any color let's i don't know let's take the first one [Music] and so here you see we have an ellipse which rotates in 3d so let's look a little bit in our components to see what's going on so we have two components the canva and the shape so in the canva so we we display the shapes but we have this camera component and we use uh context for the camera and the canva because this is going to be used by the children to do the projection so the camera component is very simple it's a overlaid transparent view we have a panges chandler and we calculate the x and y rotation depending on the position of the finger so if we move the finger on the y-axis we trigger a rotation of the x-axis and if we do we move the finger on the y-axis which trigger [Music] on the x-axis which regard rotation on the y axis and we need to convert from points so let's say the what are we doing here 2 so if we go from let's say the complete weave of the screen size this triggers a full rotation uh on the axis and same for the so same for the x and y axis and then on end we add some decay so depending on the velocity we continue the animation so that's what the camera does we apply the transformation to get the 4x4 matrix because it is set in the context it can be available from child components and so let's have a look at the ellipse so we get the radius x and y radius as parameters we draw the shape so this is a basic curve so we in re-dash we normalize paths to be sequences of basic curves and here we express the ellipse as a concatenation of four basic curve and add arc3 converts [Music] the parameters of a quarter circle into a bezier curve and actually in a previous video also looked at how to convert from a circle to bezier curves and using bezier curves instead of the shape directly can enable us to do path morphing or also to treat basically different shapes heterogeneous shapes or more generously and then so we calculate the path and we pass it to this child which is using the camera to transform plus so it has a transform property in case we want to add some transformations which we're gonna do so that gives us the final transformation matrix and then we project every single points from our basic curves to get the projected shape we serialize it as an animated property and that gives us uh what you're seeing here and then we can also animate the progression of the shape which is this example here where we have these three ellipses and then we can just rotate them in any directions so let's go back here to our ellipse and we can add another component a rectangle so zed rectangle and so i'm gonna use here different color and um weave let's say zero eight eight zero eight so now they should be so they are exactly on the same uh plan and you see even here you have some z what we call z fighting because of the same z index but we can now move them onto the z axis so i'm gonna [Music] use the transform property here so i'm going to add a transform so i'm going to add translate z and let's say minus 0 0-2 so now one should be in front of the other you see it here right so there is no more that fighting i can move maybe the other one forward uh add some feel maybe to the rectangle so you see here we have a nice pseudo 3d transformation and potentially we can use so here we didn't choose perspective in the transformation we can use the perspective transformation as defined in the react native implementation so if i go here to perspective so which is what we call weak perspective which is simply going to make closer object look bigger or further object to look smaller but potentially i guess we could try to build some more complex perspectives such as the ones you see in opengl systems and another example of such simple projections is a cube so you see here if i go to the cube example so we have the zed box so a cube or a box has eight points right so these four points here and the four points at the back which we have here which we project here so we have the projected points here and from these projected points we can calculate each face the six faces of our rectangle and we do this here in order to only project eight points so here potentially there is a lot of duplicate points which we don't want to project twice just as a small performance optimization in that dog they are simple shapes which are projected using the same method that we've just seen but then there is another category of shapes which is super interesting and so the cone the cylinder and the hemisphere and actually we're gonna look at the cone but you will see quickly i think it's gonna become apparent but these three shapes are kind of the same but a little bit different and these projections are done a bit differently here we project some key points of the shape and then based on these projected points we make some other calculations in the case of the cone we have the base of the cone you see which is a circle which is projected onto the 2d space to become an ellipse and then we have the apex of the cone which we're also going to use using the projection to calculate its position once we have these two projections we are going to calculate the tangents to the ellipse to build the triangle and that is going to give us this 3d cone so if i go to the code here here we have our circle which is projected to the 2d space to become an ellipse and then we have this red point which is moving here which is the projection of the apex so we have the 3d projections we need now from these projected points we need to calculate the tangents from these tangents of the ellipse that go through the apex so these points how we calculate these tangents first we need the parameters of our ellipse we have the um four control points which we used to draw the circle so here the circle is calculated as a concatenation of four basic curves but actually here it doesn't matter basically we know the radius of our circle but all that matters and we need to calculate a and b and i was scratching my head on how to calculate the parameters of our ellipse so if we go to the so the ellipse is defined as this equation and a and b so a is a semi major so it's a radius here on the x-axis and the b is a semi-minor axis which is this value and we know we know a couple of things we know that actually you see if i run the circ the projection in any position one of the radius is always the radius of the original circle so we have the value of a a is always so the semi-major axis is always equal to the radius i could draw the circle of radius r here and you will see that it always touches the points of the circle and then to calculate b i was scratching my head and i found this figure and this made me realize that this is exactly what we have right now so v is here here here here are the points we know about these are the projected points so the red points that you see here and what we want to calculate is a semi major axis so this one here and this one here is equal to r and in the article from wikipedia about the ellipse it gives us the formula to calculate b so you see here again we have our control points a we know is equal to the radius of the circle and we want b and there is this theorem of apollonius that tells us that this length here is equal to this length we here which means that c1 so using the pythagorean theorem c1 squared plus c two squared equals a squared plus b squared we know that a squared is r squared so we know that b is square root of c one squared plus c2 squared minus cs squared and then we need to calculate the tangents of the ellipse based on these two parameters from the wikipedia article we know that this is the formula of the tangent of an ellipse and we want the two tangents that go through the apex and we know that the apex is of coordinate so x0 is 0 and y 0 is the value we have once we project the apex so we know y0 so we can calculate y from here because here so x0 equals 0 so that gives us y0 divided by b square times y equals that 1 that gives us y equals b square divided by y zero so now we can substitute y in the equation of the ellipse because we know we want the two points in the ellipse for this y value so again based on the equation of the ellipse that would give us x squared divided by a square plus y squared equals b squared equals 1 this is the equation of the ellipse we can substitute y to find x so that would give us x squared divided by a squared equals 1 minus y squared divided by b square and that gives us x equals so we multiply by a square and this and everything so multiply by s square and everything square root so square root of a square would be a and then square root of y square a 1 minus y squared divided by b squared and we can even substitute directly y by this value here so that gives us y so 1 minus b squared divided by y 0 squared divided by b square before we get into the code we can check if our formulas are correct so here i have the formula of an ellipse i have the b and a parameters which we can vary to any random values and we have y 0 which is gonna be the coordinate of our of the apex so here we don't see it here but we have a point basically right that's six so x equals zero and y zero equals six and so we can enter we calculated that y equals b square divided by y zero oops sorry divided by y zero so that we know that the tangent is going to be at these points but we need to calculate the x coordinate and we know that x equals a times square root of 1 minus so b squared divided by y 0 squared up oops divided by b square we have made a mistake it's poor you see because here i see it's not so the result is not correct and i see that i miss uh was b power 4 and you see here this is the point we're looking for and we can copy it here with minus a and so here we have the two tangents that go through the position of our apex of course here we use x equals zero we're gonna we know that the apex is rotated we're gonna apply the rotation afterwards so we know that a equals r but now we are working here with the projected shape so we change the scale of the coordinate system so i'm gonna do scale.x times times divided by two and this is because we go from not zero to one but minus one to one so we divide by two so we have a and we know that b equals square root of c 1 squared plus c 2 squared minus a square and we know that situ is this point so i'm gonna not i'm not gonna reproject it again i'm gonna use the projected version directly so which is path.move so that's the first point so this requires me actually to know i know the internal structure of path which is this object here but if you don't know how it's represented internally you can simply do the projection of the point directly right like we do here for apex so i could do use project of the point directly but um here i'm saving one computation and so c2 c1 is path dot curves so the first curve destination point and so it's not scale but canva and these are vectors so we want the distance from the origin so i'm going to use this tutish for that so that simply calculates the occlusion distance of a vector and here we only look at the first two dimensions again here this you can find again through the pythagorean theorem so now let's calculate the tangents so we know that so if we go back here y 0 is b y is b squared divided by y 0. and y 0 is a distance of the apex from the origin and so again here right we ignore the rotation and the thing is rotated and we rotate after so y0 is this 2d of apex so we have y is equal at b squared divided by y zero and that gives us x x is so this formula a times square root of 1 minus so you see that this expression here is y square right so b power 4 divided by y 0 port 2 is y square so that would give us y square divided by b squared now if the if y 0 is less than b the ellipse is not visible so we're going to return we're not going to be able to calculate the tangents because the point is within the ellipse so we're go and anyways it means that the apex is invisible so we don't need to calculate anything so i'm gonna return apex and then points so zero zero zed is zero doesn't matter here up and then apex i mean yeah i don't i just can return something emptier and if the ellipse is visible so here we have [Music] x minus x this one is the apex and here we have y and also depending on the sign of y let's draw the so let me remove these debug things here and let's draw the apex so i'm going to do a vertex so vertex simply shows you the polygon from a list of points so points fill so we have a body color and so we have this one so let's do points use derived value and so we have data dot value dot points up so here we are getting some not a number if [Music] y is great y zero is greater than b now it doesn't make sense we miscalculated something somewhere and i think here it's i need to do this on the projected path not the here you go not i was working with the 3d path not the projected one so you see it uh actually works here we just need to match the rotation of the ellipse here and the rotation because we've made the calculation like this here we need to rotate to this corner so to minus pi divided by 2 and add this angle made by the the apex and here we know that this coordinate is a tan of y divided by x right every time we want an angle in all our previous videos every time we run the angle from the coordinate we know that um on the euclidean coordinate system it's gonna be a tan of y divided by x so the rotation on the z axis is minus pi divided by 2 plus a tan so 8 and 2 of apex dot y apex dot x and here we're going to use we're going to rotate each point [Music] by so you see we're cheating completely to calculate the 3d projection but it should give us an interesting result so um oh no it's minus math pi divided by two so that starts to looks good now we can interpolate the color of the base and this is why here i use process color so if we are seeing the base from face it means that the the apex is the z index the z value of the apex coordinate is negative so if data.value.apex.z is less than zero we see the this little ellipse from the face so that would be c or one if not co2 color one color two so you see here and the tangents don't look correct but i think i know why so here we are looking at it so we play you see we play many tricks to make it look like a 3d shape we do some projections we calculate the remaining we also play with colors to give the illusion of a free shape but here let me check looks good isn't that cool guys i hope you enjoyed these examples we are mostly doing these experiments for fun and also for the love of math but maybe you have some concrete and practical use cases for such techniques if so please let me know in the comments below i am looking forward to talk to you soon and until next time happy hacking [Music] mom give it back
Info
Channel: William Candillon
Views: 6,779
Rating: undefined out of 5
Keywords: React, React Native, Can it be done in React Native?, TypeScript, JavaScript, Expo, Reanimated, SVG, 3D Animations
Id: G0LeZ00-c58
Channel Id: undefined
Length: 34min 36sec (2076 seconds)
Published: Tue Nov 03 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.