 Hi, I'm Jeremy. This is my slightly gravel top title. I'm going to start with a question. How can we dynamically generate interactive animated graphics in a web client? And over the years, there have been many answers to this question. Some of these, of course, have become dead ends. So, you know, I'm looking at Java applets, flash and action script. And actually the newest technology listed on here, WebGL, apparently came about eight years ago. But, you know, over the last several years, performance and general browser support have been improving. So, it's not really a blank space here, but moving on. The dominant ways that we draw 2D graphics are, you know, the HTML5, which gives us two things. Canvas and SVG. There's a lot of overlap between these, but in case you're not familiar, I'm going to introduce these quickly. So, say you want to draw these three squares via the Canvas APIs in HTML5. So, we have a Canvas element in our document. We get a 2D context from our Canvas element, and then we execute a series of commands which draw our squares. And as you draw these, they become pixels in a bitmap. The squares no longer exist as squares after that point. So, if we compare this to SVG, instead we have DOM elements that represent our primitive shapes. So, we don't have to write any JavaScript. We, of course, could if we wanted to, because we can write JavaScript to create these rectangles and insert them into the DOM. So, we can render pretty much all the same things with these two techniques. Some things are easier or harder with one or the other. But there are some subtle behavior differences that I'm just going to touch on quickly. If I can, the computer is behaving very differently than usual, I have to say. So, sorry. Does anyone know how to escape PowerPoint? Okay, better. So, one subtle behavior of difference is that because SVG creates DOM elements, we can attach event listeners. And these are backed by the browser and we have sort of sensitive edge detection. Whereas with a Canvas, we have a single element, it will detect events on the Canvas. And if I look at the source code, oops, my goodness. Okay, if we look at the source code quickly, you can see that in fact our SVG elements, we can attach our usual event listeners on our Canvas. There's no opportunity to attach event listeners to these rectangles. We can do things, of course, with the X and Y coordinates that we get from the house event. So, moving on. Another subtle behavioral difference has to do with text. So, on the left we have text rendered via SVG and even though it has some transformations applied to it, it's still text. As far as the browser is concerned, we can select it, we can search for it. So, that's cool. Whereas with SVG, I mean, sorry, with Canvas, we basically have the same text rendered as a bitmap. All we can really do is save it as a PNG file. Other differences that I was curious to investigate a bit are performance differences. So, there are claims out there that are often repeated that say that a Canvas works better when you have a large number of objects to render because there's no overhead of representing objects in the DOM that SVG has. Whereas SVG may work better at high resolutions because Canvas is basically rendering into a pixel above for a bitmap and the larger it is, the more overhead you would have. So, I thought, well, can we test these claims? Can we see what this is like in 2019 in a modern browser? So, I did some informal tests. First test here, you know, I thought, well, let's try animating 15,000 tiny moving, randomly moving squares and see how many can we animate and hit the 60 frames per second cap that a modern browser will impose on rendering. This is how many. On my MacBook Pro, I tried a few different browsers. They're all pretty consistent just for fun since we're, you know, looking at pictures. I added some mouse interaction, which doesn't seem to affect the frame rate at all. So that's a Canvas. With SVG, I hit a cap at 1,000 tiny moving squares, which is along the lines of expectations, a little bit sad there. But we can actually do better and stick with SVG. So this is still SVG, but now we're rendering 6,000 tiny moving squares. And the way we pull that off is we use this generic element called a path. It's kind of a do-it-all element. It does have some limitations because everything we draw to our path is going to share, you know, a color. We can't add DOM events to parts of the path, but, you know, in JavaScript, we can generate path data or we could specify it statically. But here, basically, we're giving commands in a data string. And we're saying move to a coordinate, draw some lines that outline our square, close the path, fill in the entire thing, and we get our randomly moving squares. So there we go for a performance comparison. So another one I'll highlight is that in a modern browser, at least, I couldn't reproduce this sort of piece of common wisdom. So unless I disabled hardware acceleration, so in Chrome in the advanced settings, you can go and turn off hardware acceleration, which is on by default, and then all of these characteristics change a bit. But, you know, basically, Canvas is going to be faster depending on what you want to do. There is a third option out there, which is WebGL. So as mentioned briefly before, so what is WebGL? Again, in case you're not familiar, WebGL is mainly a 3D rendering context for Canvas. So instead of, before we paint to our Canvas, instead of getting a 2D context, we get a WebGL context, and then we can execute commands on that. What kind of commands do we execute? They are basically OpenGL API calls. So if you know OpenGL, you would be very comfortable with WebGL. If you don't, you're in for a very steep learning curve, as we may see in a second. And what this enables in web browsers is you can see it in basically a huge number of JavaScript libraries that are out there that can load all kinds of model file formats. So if you have 3D models that you've created in an editor, there's probably a library out there that can load your model file and display in the browser. There are game engines that already targeted OpenGL and can now target JavaScript and web browsers. So big names like Unity on real engine will target WebGL in a web browser if you want them to. And I repeated my informal performance test on WebGL, because why not? And I got up to 45,000 tiny floating squares, which is a much denser mass. And we can look at the code, keep doing that, we can look at the code quickly. And you can see why at least I think there's a pretty steep learning curve. Again, you know if you're familiar with OpenGL, great. This stuff is pretty new to me, but as I mentioned, you get your WebGL context to run commands on. And then you have to do two mandatory things which are creating shaders. So you need a vertex shader, which my understanding determines for every vertex in the models that you're going to paint, where on the screen is your vertex going to end up. And you need a fragment shader, which determines for every pixel on the screen what color will that pixel be. So these are basically trivial implementations of these just for the purposes of this informal performance test. But this is not actually JavaScript code within these shaders either. These are coded strings in an OpenGL shader language. So that's exciting. We compile these shaders into a shader program. We set up some data structures that will pass data into these shaders. So this is all kind of minimum mandatory setup initialization. And then we can finally render our squares. So I did this perhaps there are better ways. But I did this by creating a single buffer which contains all the coordinates of all the square corners. And loading that into an OpenGL buffer which I believe will send the data to the graphics card. And then stepping through and rendering each square as a four pointed triangle strip. So do all that and you get 45,000 tiny floating squares. So and then here's the summary of this very informal performance test performed. I know today is Wednesday but I made this slide yesterday so forgive me. So like I said I was curious about the current state of things and that's what I found. I'm going to change gears a bit now and talk about applications. Because of course we don't, you know, browsers haven't been driven to adopt these technologies by the desire to render squares. Large ones, small ones, whatever. So I feel we should briefly touch on charts which is, you know, I was employed for some time rendering charts of application performance data. And way back in the day we had charting packages on the server. We generated bitmaps. We shipped them to the client. You could see your data. What more could you ask for? So there were a few things that we had to come up with to motivate a transition to rendering charts on the client. And since maybe demos are slightly more interesting than slides I'll just very quickly demo a few attributes that we should expect from our modern HTML5 charts. You know, there are many, many charting packages out there but hopefully they will give us features like on the fly layout. So, you know, JavaScript is fast, rendering is fast. Nowadays we should be able to recalculate geometry depending on how much space we have on a page. Animation, you know, arguably a faded animation like this isn't super useful. But if you're transitioning between different views of a data set or of real-time data is coming in, animation can be very valuable. And interactivity. So, you know, a sort of minimal form of interactivity is, you know, instead of solely relying on legends and y-axis labels we can, you know, mouse over a thing and get some context. So that was a very quick discussion of things we should expect from charts. Moving on, there are a lot of data sets that we can model well as diagrams of nodes connected to each other based on some relationships they may have. Here is an incredible trivial one. And the challenge with diagrams and, you know, showing them in a web application often is not rendering the thing because, you know, we have rectangles. We have text. We have some lines that we can probably figure out how to draw. And in an example like this, it's not very hard to figure out where we could put the nodes. There are many options that make sense. But what if we have a lot of nodes? What if they are heavily connected? What if the data is somewhat unpredictable? So I'm deviating a little bit from talking about rendering. But one algorithm that I always find very interesting for laying out graphs, it's been around for some time. You may have seen this demo before. But I'm going to show you guys a force-directed graph layout. So the fun part of this is that you do this by pretending to run a physics simulation on your nodes. So you initially randomly position your nodes and then you apply repulsive forces between pairs of nodes, which immediately makes this an n squared algorithm so we have performance concerns. We also, but we do this so that nodes will distribute themselves far around a page. We also apply attractive forces between nodes that are connected so that related things will end up near each other. So we need a data set to look at. So one that I found on Wikipedia, somebody pointed me in this direction, was this very exciting table of countries and their primary trading partners. So we could scroll through this and we could kind of understand who likes to trade with who. Perhaps we'd like to visualize it. So let's try that. And you know, an interesting thing about this algorithm is that we don't have to, but we can animate it. So have people seen this demo before? No. So this is kind of meta because we're watching the process of what the algorithm does. It actually sorted itself out fairly quickly and there's some issues that we could try to clean up like overlapping nodes and so on. But we can see that there are three trading hubs in the world. The data is a little weird because the EU trades with countries in the EU according to this data set. But this is based on data that was copied from that. Wikipedia table turned into a JavaScript array and then plugged into the algorithm that we were looking at. And in practice, if you're using an application and you want to visualize your data, you probably don't want to sit through that animation. So of course we can do the same thing off screen and just throw up the result, run it in a loop, not wait for frames to render. And you know, there's our output. So fairly easy to render, not very advanced requirements, but I don't know. I always find that algorithm interesting. So there it is. So moving on. Last topic. So, almost done. So who here codes for fun? Who doesn't necessarily need a practical endpoint? Some people. Okay. Maybe a third of the people here. So I'm going to talk about games briefly. For some people, games are work. I have friends who work in the video game industry. I've picked up a few things from them. For me, it's an off and on hobby. It's a way to explore ideas. Prototyping games is fun. It's challenging, even if you never finish your game prototype. And trying to put a game on the web has obvious, very obvious benefits because, you know, anybody with web browser can go play your game. So if one wants to write a game, first two things to consider, of course, are using a game engine. There are many out there. I already mentioned, you know, a couple big names, Unity and Unreal Engine. Another one, smaller one that I've used at one point was called Cocos2D. So what game engines provide to you is they will abstract away basically all of the low-level rendering. So you won't necessarily know if you're writing a 2D game, whether you're rendering to a canvas or a WebGL, you know, whatever is best supported by the browser is what you'll get. And, you know, if it's 3D, it's going to be WebGL most likely. But, you know, they'll help you manage your sprites, your assets. They may provide a built-in physics engine. If they don't, then you can look at the many physics engine options out there. So depending on the type of game you might be interested in, physics engines will help you model the objects in your game as primitives, like circles, lines, polygons, or in 3D, you know, 3D objects. And you can set physical attributes on them, and then you can predict collision times. You can do ragdoll physics. For today's purposes, I'm not going to do either of these. Because I like occasionally low-level coding. I'm not really interested in practical applications at this point, and I'm going to talk briefly about sprites. So if we want to develop a 2D game, of course, you know, say in Mario. Mario is your sprite. He runs around, his feet move, he jumps, his hand goes up in the air. We need to animate these things. If you're a graphic artist, you can sit down and draw animations frame by frame, and you can get very high-quality results. If you're like me, and your skills don't lie in that direction, and maybe you'd rather just code, you can go with this second direction, which is using vector graphics. So say we have a person we want to animate. We want to model him and have him move through space. In this case, we can just identify some key vertices or joints. And as long as we know the coordinates of these joints, we can render our sprite ultimately. And when we render, we can exploit the concept of keyframes. So if we want our animation of our vector graphic sprite to run at a very high frame rate, we don't want to sit down and define 60 frames to fill a second. We maybe want to define the frames at the beginning and the end, maybe a couple in the middle, and then we want to interpolate between these frames as time passes. And we don't have to linearly map the passage of time to the progress of our animation. We can take advantage of this concept called easing, where we can kind of ease into an animation and apply a curve function to our elapsed time and get sort of a more impactful end to the animation, or we can ease out and get a softer end to our animation. So let's see. That's a lie. Okay, very briefly, almost there. Very briefly, going to put up a game prototype. So we put these concepts together. We spend a few days coding, again, for fun. We wave our hands, and then we have a game prototype, where perhaps we have two boxers. They're ready to fight. They're Singapore, so they're sweating. It's hot. Our boxers can do a few things. Perhaps I feel I might be punched so I can guard myself. Perhaps I want to punch with my right hand, punch with my left hand, walk over to my opponent here. He has no AI, so he's defenseless. So he's just going to stand there, and then I can maybe take out some aggression. Maybe I have a bug in my actual work work that I can't figure out, and I can just, you know, do some punching and so on, and kind of ruminate on where this game prototype could go, how much cooler it could be if it was in 3D, implemented with WebGL instead of a canvas, and so on. So that, in fact, is the end of what I have today. So thank you for bearing with me. Yeah, Shailesh. Can you open the 45,000 boxes? It's so mesmerizing. So it gets more interesting if I make it smaller, but yeah, so I, you know, don't claim that this is the best possible benchmark, but this is what I live together. Any other, yes? Isn't there another option? Before going to shaders, you could just do WebGL without shaders? That may very well be. So as I tried to explain WebGL is very new to me, and I didn't have as much time as I would have liked to learn the details. So from what I read, I did not see that option, but I absolutely believe that that may exist. No claim of expertise here on that topic, yes. Okay. Have you also considered looking at WebAssembly at all for this type of more demanding graphical processing? Right, so I have certainly heard of WebAssembly, and I think that's probably a direction a lot of games will go in because of, you know, especially if you have to do physics simulations or even the graph layout example I gave, you know, it's not an especially fast algorithm if we had more than the 500 nodes I was showing. So even outside of game applications, you know, WebAssembly is going to help you out there. It's not something I personally experimented in, but... Yeah. I just saw the different SVG a bit. Yeah. If you use CSS transitions or CSP frames, I think maybe it can be more performance, but less dynamic than... Right, right. So yes, to be fair, I did not explore the option of animating via purely CSS, and in fact, I think that we don't need to render 45,000 or 15,000 objects usually, and the graph demo and the chart demo that I briefly showed used SVG, and it has nice features like you can select and search for the text, and so on. So I'm not maligning it. I just wanted to test that claim. Okay. Thank you. Thank you.