Animation Loop Framework threejs project example
The subject of creating an animation loop is something that will come up a lot, not just with threejs alone, but indeed with client side javaScript in general. When it comes to client side javaScript alone there are methods like that of setTimeout, as well as request animation frame. There are also a number of additional features that are related to this sort of thing in client side javaScript, but also in the threejs library such as the THREE.Clock class, and thus also performance.now, and Date.now that the class works on top of. However in today’s post I am going to be writing a thing or two about a new javaScript module project that is a kind of framework that builds on top of the core idea of an animation loop.
This is then yet another threejs example project to add on top of the many others that I may continue to work on a bit more off and on in the future. I have a general idea of what I would like this project to be in terms of the core set of ideas. That is to have the usual code that I keep copying and pasting from one project to the next, abstracted away into a module, or framework kind of from which I would say is the case here with this project. That is that with this module I call a main create method and pass an object that contains a method that can be called to set up the scene, camera, and so forth, and then another that will update things over time.
The animation loop framework and what to know first
This is a post on a threejs animation framework that can be used to create little animation projects in a page. It should go without saying but I will being it up again anyway, this is not a post for people that are new to threejs or client side javaScript in general. I will not be getting into detail about all the various little details of the threejs library and front end development that you should know before hand. However I do always make an effort to use these opening sections of my posts to bring up a few things that you might want to read up more on regardless of current standard experience and skill level.
There is a lot to take in when it comes to animation loops, I would not stop with this post for sure
There is more than one way to skin a cat as the expression goes, in the context of this post there is more than one way to make an animation loop. For this example I am just using the requestAnimationFrame method to call a loop function recursively, or at least that is what I was using in r0 of this threejs example. when it comes to future revisions I might revisit what it is that I am doing to create this main loop and maybe change a few things around. Anyway this request animation frame method is my default go to method for this sort of thing and I am sure that I am not alone with that. On the open internet there may be a lot of developers that say that you should only use that and nothing else ever, but I am not sure if I would automatically assume that.
In some cases I might want to make use of setTimeout actually, the main reason why is that there might be some situations in which I would want to have two loops. One loop for updating a model which would be powered by settimeout, and another loop for updating a view which would use request animation frame or similar alternative. This will be especially true if I get into using web workers as a way to push some heavy listing type tasks to a separate event loop, as I am limited to using methods like setTimeout in that kind of environment.
Just keep what is most important it mine with this sort of thing
It can get a little overwhelming when it comes to really looking into how to do an animation loop. However I think one of the most important things to keep in mind is that many visitors to a web site might only have so much in terms of system resources to work with. Also there might be a lot going on in a page that is all running in the main event loop of the page as well. So right off the bat I will want to build in a user interface that allows visitors to press a stop button that will stop the animation loop completely.
Right away my stop button feature seems to work great as when I press the stop button I noticed my systems CPU use drop way down to more or less zero. In future revisions I might add additional features that will allow for uses to adjust the frame rate for updating, and movement, or work out a way to adjust that automatically to further refine this very important have feature. However for now at a minimum that is working great right off the bat with r0 of the framework.
Source code is up on Github
On Github the source code as well as add tonal notes, and also the latest source code can be found here.
Version Numbers matter
When I first made this project and wrote this post I was using r140 of threejs.
1 - The first version (r0) of the animation loop framework and demos
In this section I will be writing about the state of the first revision of the animation loop module, as well as some demos thus far of the project that test out what I have thus far here. I had a core set of ideas that i wanted to get up and working right away with this one, and the first and foremost was to have a stop button for it. If I use this code in production it will likely be used for add a little header app type project at the top of the page, and when it comes to such things I think a stop button is a must. There is a lot that can end up going on in a page that will be fighting for resources, and even in cases where there is not much else going on some people use economy hardware that only has so much FLOP Power to work with as well.
There where a lot of other core ideas also that are up and running. When making animations with threejs thus far there are two general kinds of animations that come to mind. One kind of animation I would call a frame by frame style, or deterministic style, while the other kind I would call random, or stochastic style. When it comes to the kind of animations that I will be making with this kind of project I am sure most of them will be the random style, but I am still baking in feature that help with both.
1.0 - The source code of the framework
At the top of the module I have a whole lot of private helper functions that are used in the process of creating a loop object, or to add additional methods to work with when it comes to creating the source code of an animation. At the very top I have some methods that I copied over from my recent wrap module threejs project. This is used to create a wrap vector method that is one of several methods that I can use off of the public API of this that will come into play with random rather than frame by frame style animations. Simply put it is a way to wrap values around when something goes out of bounds, rather than clamping the value and not letting it continue.
Another helper function that I have here is my get canvas relative method that will return an object with an x, and y position that is relative to a canvas or container element, rather than the main window object of a page. Additional helpers thus far have to do with setting up style or rather class names for container and canvas elements, as well as attaching events for and drawing the user interface thus far.
I then have my main Loop Class that is used by the public create method to create a new instance of the main loop object of this framework. After that main constructor of the Loop class and the few prototype methods thus far for it I then also have a few public methods that can be used to create an instance of this Class as well a start and stop the main loop function.
|
|
1.1 - Frame by frame demo
Now that I have the source code of the framework out of the way I should go over at least one or two demos of the module to test things out. As I have mentioned above I think in two general styles of animation which are frame by frame, and random. Think in terms of the nature of videos, and how they compare to that of video games. A video is a static, fixed, collection of frames, while a video games state is subject to a wide variety of factors such as user input, and code that will control the state of Non player Elements of the Game and so forth. This first example will then be a kind of frame by frame, deterministic, or video style kind of animation then, and I will get to another demo of the other style in an addition demo of this framework.
|
|
1.2 - Random demo
I like frame by frame style animations a lot, so much in fact that I have made a major project that I still work on a little now and then for making videos. However this animation loop module is not that kind of project, there goal here is to make the kind of amazonian loop framework that would be used on a web page, rather than making a video. Although I can still very much make frame by frame animation with it, the focus is very much animation in general, including ones that might make use of user input, seed data, and random values.
For this example I then wanted to make another animation on top of the framework that is more on point with the other general style of animation. Nothing major for this one, but i would like to test out that wrap vector method that i put in place with this style of animation in mind.
|
|
Concusion
That will be it for now when it comes to this project, at least until I come around to do some editing of this post at least which may or may not happen. I do have a lot of pots building when it comes to these various projects, and some are more deserving of additional work than others. I have found that if this does prove to be the kind of project that I do in fact end up using in production that I will be working on it more.
In any case I do have a lot of ides written down for future revisions, such as seeing about using iframes as the kind of container element. There is also features like having a more advanced user interface that helps with adjusting the update frames per second rate, seeing about doing a thing or two with more than one layer that is updated at differing rates and a whole lot more. I will see about getting to some of this when and if I get around to it, but in any case thus far I think I have a great first crude yet effective starting point worked out thus far.