It has been a few months sense I wrote any new content on three.js which is a shame because this project does deserve more attention. Anyway when I am playing around with three.js I often like to use it to make simple looping animations, and it would be nice to have at least one or two ways to export these projects to a reliable well supported webm file format making it easy to share. To help with this I have come across a project called whammy that seems to work okay for the sake of making a webm file on a frame by frame basis. In this post I will be outlining a simple example of doing just this using three.js, and whammy.
In this post I was using three.js r91,
For the sake of keeping this post simple and to the point I will just be using a simple rotating cube example for this post. This will help to take the focus away from the animation and place it more so with the process of exporting an three.js animation to webm with whammy. Uising whammy is fairly simple, but there are a few pitfalls that I have ran into. Nothing major, but I will be going over them here.
Once I have both whammy, and three.js included in my html with script tags, I start off by setting some variables that I will be using to help with the movement of the animation. Using whammy starts off by just calling the Whammy.Video constructor passing the desired frame rate for the exported video. This will return an encoder that I can use to add frames one by one in a render loop, and then them I am done I just need to call a compile method from this encoder.
Next I have an animation method. Here I am using the current values of my frame, and maxFrame variables to find a percentage value that I then use to set the status of the frame animation for the current frame. For this animation I am just moving the position of the camera, and having it look at a simple mesh of a cube with the camera.lookAt method.
In the body of this method I request another animation frame for the method over and over again as long as the current frame index is lower than the maxFrame value that I set. Each time after rendering I add the current state of the canvas to the encoder with the encoder.add method, by creating a dataUrl of the image/webp type. The whammy documentation says that I can just add the canvas, but I run into an error when doing that.
Once the animation is over, and all the frames have been added using the encoder.add method, I then call the encoder.compile method that will output a blob than can then be used to create a data url which is what I do with the exportVid method.
When the encoder is finished compiling, a callback will fire with a blob passed as the first argument for that callback. I Can then use the URL.createObjectURL method to convert the blob to a data url. This data url can then be used as the src attribute when making a video element.
I make sure to set the controls attribute to true, so that I can play the video element. In addition in chrome there is a download option for the video as well.
So here I just set up the usual scene, camera, mesh, and renderer. Once I do that I call the animate method to get the ball running with this.
So far this seems like one of the best options for converting a simple three.js looping animation to a stand alone webm file. I have look into other options, but some of them are more complected, or I could not find a way to build the file on a frame by frame basis. If you know of any other methods of getting this done, or have an questions or concerns please let me know in the comments, and thanks for reading.