External Editor Support

Version 1.0.0 of GIF Loop Coder added an integrated editor into the UI. Unfortunately, it somewhat degraded the experience for those users who prefer to use external code editors. Version 1.0.1 hopefully fixed all that.

One of the main problems was lack of documentation. It was still possible in version 1.0.0 to add a script tag in the app’s main HTML file that pointed to an external .js file. It just wasn’t obvious. If that script tag is there, it will load that script and run it just like the pre-1.0.0 versions. So I’ve made it a bit more obvious.

The other problem was that if you use an external script file like that, it will NOT load into the integrated editor. So it created this weird dissonance where you have one script in the editor (the basic template) that does not reflect the script that you were actually running. And the tool bar buttons for load, save and compile would override that external script.

And finally, the warning you get when reloading the page was a pain in the neck if you were running an external script.

To combat all that, there is a new glcSettings object defined in the app’s HTML page. That has a useIntegratedEditor property that is set to true. Change that to false and you’re basically back to the old GLC. No more editor, no more toolbar items or keyboard shortcuts for open, save and compile, and no more warnings for reloading.

So now you have the choice. Use the integrated editor or use your own, hopefully with a good experience on both.

Another minor but useful change is that panels now remember the last location you moved them to. No more fighting them continually showing up where you don’t want them. Arrange them how you want, and they should stay that way across sessions.

Version 1.0.0!

This is a pretty big release. The main addition is that GLC now has an integrated code editor!


Up to now, you had to edit your sketch in an external editor and then load the result in the browser. This usually meant editing the html file to have it point to your script, although there was functionality to load a file.

Now, all you have to do is launch the app. The editor is built-in. Write some code, and hit Control-Enter to see your changes. I’ve been using it like this for the past week or so, and I love this workflow. It’s so much more direct. Get to know the keyboard shortcuts. They really make things easier.

Of course, if you still love your external editor, that workflow is still possible for now. See the Tips section of the docs.

You’ll also see that a lot of the functionality of the control panel has been moved up to a top tool bar. And the code editor itself now fills the full screen. This is the first move to remove the QuickSettings UI from the app. I love QuickSettings, and it’s served the app well up until now. But it’s a prototyping UI library, not ideal for the long haul. So the rest of the panels may fade out over time as well.

The code editor is from https://codemirror.net/. I’m very impressed. I’m only scratching the surface of all it’s available features. So that’s another area to explore and maybe squeeze some more functionality out.

The next big step will be a standalone cross-platform executable. This should take away a few of the poor user experience items like loading and saving files. Loading a file is ok, but saving is horrible. There’s no connection to what your saving and what you loaded, no way to overwrite an existing file or even specify where you want to save a file. There are other things that having a standalone app will help as well. I’m going to be using Electron. I already have a working version, but need to hook up all the stuff that will make it behave more like a native app – like file saving. And then get the multi-OS builds going. Look for it early in the new year.

onEnterFrame, onExitFrame, and what’s all that 3d stuff?

Gif Loop Coder has its roots in two earlier programs I made for my own use.

One was 2-3 years ago and was for making sprite sheets for a game I made. It had a rough prototype of a scheduler, with a callback function that allowed you to draw whatever you want to the canvas, then would take those frames and assemble them into a sprite sheet. Pretty much what you see in the sprite sheet export functionality in GLC.

The second one was a year or so ago. Same basic scheduler and callback, and contained the same GIF encoder that GLC has. I was into fractals at that time, and used it to create images like this:


When I started to create GLC, I wanted to make it easier for others to use. So I gave it a UI with my QuickSettings library, and made a bunch of predefined, easy to animate shapes to use. But once in a while, I found I wanted to have raw access to the canvas like I did in the other apps I’d created.

I started to create a brand new app, which I was going to call GIF Frame Coder. In it, I ripped out all the shapes and render list and just left the scheduler, UI and GIF encoder. It worked great, but then I missed having the shapes. I realized that having two separate programs was a dumb idea. It was easy enough to provide the direct canvas access right in GLC.

And so now you have all of that. Render shapes with the render list like you’ve been doing all along, or dive into direct canvas access and write your own code to do whatever you want.

This is all done simply by providing you with two new variables: glc.canvas and glc.context and two new methods that you can define: glc.onEnterFrame and glc.onExitFrame. Yeah, I know, I’m coming closer and closer to recreating Flash 3. I don’t mind that at all.

Read more about it here:


Some of you might have seen some of the gifs I’ve posted in the last couple of days, showing some 3d stuff. This is not a direct part of GLC, but uses the new functionality. I pulled up an old 3d library I created back in 2011, when I was first diving into JS. (Has it really been that long???) It’s called WireLib. I have to say, it’s not horrible JavaScript. Not as bad as I would have thought for my early endeavors. I started reworking it though, to make it more compatible with how GLC works. And at some point I started a full rewrite, calling it wire3d. It’s still a work in progress, but it’s growing to look a lot like how GLC’s render list works. Example:

x: 100,
y: 100,
z: 100,
w: 200,
h: 50,
d: 100,
rotationX: 0.2

All parameters optional of course. I don’t plan on putting this into GLC as core functionality, but with the new enter and exit frame features, it works great as an add on library. Stay tuned.

Oh yeah, updated code is up on github, or download at http://gifloopcoder.com/download version 0.9.4.

Object Variables

There’s a feature that was added to GLC a while back, which I realize I never properly explained.

When you create a shape, you pass in an object that contains various pre-defined properties that define how the shape is drawn. But, you can actually add other properties to that object as well – any property you want. Then, if you have a function defining a property, you can access that custom property by use of the keyword, this. For example:

centerX: width / 2,
centerY: height / 2,
x: function(t) {
return this.centerX + Math.cos(t * Math.PI * 2) * 100;
y: function(t) {
return this.centerY + Math.sin(t * Math.PI * 2) * 100;
radius: 10

Here, I’ve defined a centerX and centerY property on the object, and accessed that within the functions that define x and y. That’s a simple example to show how object variables work, but it doesn’t really show off how they can be useful. In this case, centerX and centerY could easily have just been regular variables anywhere in that code. So let’s take another example.

for(var i = 0; i < 6; i++) { var angle = Math.PI * 2 / 6 * i; list.addCircle({ x: width / 2 + Math.cos(angle) * 100, y: height / 2 + Math.sin(angle) * 100, radius: 10 }); }

Here we have a for loop creating six circles. It first creates an angle variable based on the for loop variable, i. It then uses that variable to calculate the x and y position of each circle. This gives us this image:


Now let's change that just a bit.

for(var i = 0; i < 6; i++) { var angle = Math.PI * 2 / 6 * i; list.addCircle({ x: function(t) { return width / 2 + Math.cos(angle) * 100; }, y: function(t) { return height / 2 + Math.sin(angle) * 100; }, radius: 10 }); }

I didn't change the formula for x and y at all. I just wrapped them in functions. But when we do this, we get this picture:


What happened?

OK, in the first example, we were calculating that formula, width / 2 + Math.cos(angle) * 100, right in the for loop, getting the number that evaluated to, and assigning it to x. And the same for y.

In the second example, we were NOT evaluating that formula in the for loop. It was just going into the function. You have to think of this in terms of time.

First, the for loop runs, creating all the circle objects. Inside of that, the variable, i, is going from 0 up to 5, and the angle variable on each iteration is:


But that angle variable is never actually accessed during the for loop. When the for loop finishes, angle = 5.23598... And that's where it stays. All of this happens before you ever see a single thing on the screen.

Then, well after that for loop has completed, GLC starts looping. It goes through each circle object and when it sees that they have functions for x and y, it calls those functions. When the functions run, they access the current value of angle, which, as we just saw, is now stuck at 5.23598... radians, or 300 degrees. And that's where each circle gets drawn.

This is the exact situation that object variables are designed to solve. We change the code to this:

for(var i = 0; i < 6; i++) { var angle = Math.PI * 2 / 6 * i; list.addCircle({ a: angle, x: function(t) { return width / 2 + Math.cos(this.a) * 100; }, y: function(t) { return height / 2 + Math.sin(this.a) * 100; }, radius: 10 }); }

Here, I've created an a property on the object. This gets assigned the current value of angle inside that for loop. So the first circle gets 0 for a. On the next iteration, angle is 1.047... but that doesn't change the a value for the first circle. The second circle gets 1.047 as its a though. And so on for the rest of the circles. Now each circle has a unique value for a that is locked in. And this brings us back to our original picture.


Now of course, at this point I'd go in and add to that formula to make some custom animation using t, such as:

for(var i = 0; i < 6; i++) { var angle = Math.PI * 2 / 6 * i; list.addCircle({ a: angle, x: function(t) { return width / 2 + Math.cos(this.a) * 100 + t * 50; }, y: function(t) { return height / 2 + Math.sin(this.a) * 100 + t * 50; }, radius: 10 }); }

Not the most exciting animation, but hopefully this helps.

Sprite Sheets

This is one that has been on the list for a while. And it’s been mostly complete for a while, too. Buckled down and got it done tonight.

Now you can export a sprite sheet from your animation in GLC. This is pretty straightforward. Just click the button and see the sprite sheet. But you can read a bit more about it in the docs.

I’ve also included a sprite sheet utility in the animation utilities section. This just lets you browse to your saved sprite sheet to load it in, and then view it in all its animated glory. It’ll also give you a bit of sample code, suggesting how you might implement the sprite sheet in HTML.

I’m not sure how useful this feature will wind up being overall, but if someone gets some use out of it, that’s great.

Check out the code from github, or get 0.9.3 in the downloads section.

0.9.2 – Parents

Just a quick note to say that a new version is up. http://www.gifloopcoder.com/download/glc_0_9_2.zip

This contains one huge change. You can now specify objects as the parents for other objects. Since I already wrote it up in the docs, I’ll refer you to what I wrote.

To accommodate this, there’s also a new object, the container.

All the credit for this new feature goes to Lincoln Anderson, who has also been creating some amazing gifs with GLC.



If you check out this image, you’ll see a couple new items in the control panel. My goal is to make GLC as easy as possible to use, without making the user worry about html, paths, build systems, module loading etc. Ideally I see two different versions of the app, one could live on line as a web page on this site, another would be a standalone, cross platform desktop application.

To make either of these fully possible, I need to remove the need for the user to hack around with html files to specify which sketch to load. So this release takes the first steps towards that by providing a way to load external files.

Now, you can ignore the html altogether and just launch the app in a browser, click the open file button and choose a file. That sketch will be loaded right into the UI.

Make some changes to the sketch in your favorite editor? Hit the reload button and those changes will be re-loaded. But of course, you can still specify the sketch you want to load in the html, just like before.

This took more work than I expected, as before, the entire page and app was being reloaded and refreshed when you loaded a new sketch. When loading a new sketch without restarting the entire app, there were sometimes things from the old sketch hanging around messing with the new one. Hopefully I got those all sorted out.

You’ll see the start of some other nifty features like keyboard shortcuts here as well. I hope this makes the app easier to work with.

You can check out the full code for these changes now, or download the zip at http://www.gifloopcoder.com/download. It’s version 0.9.1.

This is only the start of the changes I have planned. The obvious next step is an integrated code editor. It’s in progress.

And as much as I love my QuickSettings panels, they were intended for prototyping. They’ve served me well on this project so far, but it’s probably getting to the point where a better UI is in order.

Then there are other features like scenes, and sprite sheet export. Those are both largely done as well, but need polishing up and documenting.

Then a live web version and a standalone app, both with that integrated editor. Exciting, I think.


GLC started out as a quick experiment and has grown beyond what I expected it to. Because there are quite a few source files, I decided to use require.js to handle dependencies and load the various modules without having a million script tags in the main html file.

This made for a fairly simple html template in the sketches folder, but not perfect. That sketches folder needed to know where all of the GLC library classes were, as well as where require.js was. So it was not very portable. It was a giant tortoise carrying its shell around on its back.

Now that quite a few people are actually using the tool, I’ve decided to make things a lot simpler. I’ve packaged up and minified all of those library files into a single glc-min.js file that can be included in the sketches folder. This makes the sketches folder completely independent of the rest of the code, and 100% portable. All you need to run sketches is what’s in the sketches folder now.

This has also made it much easier to distribute the project. Assuming you don’t really care about all of the source classes and how things work, you can now forget about git, and download GLC here: http://www.gifloopcoder.com/download/.

The zip you get will contain only the sketches folder and the docs folder. The zips will be versioned, so when changes are made, just grab the new zip.

Of course, the full source will continue to live on github at https://github.com/bit101/gifloopcoder, and if you’re comfortable with that, you can feel free to continue to get it from there.

As time goes on, there will be other changes designed on making things easier and to get you up and coding as fast as possible.

GLC Tumblr

Just thought I’d note that I set up a GLC tumbr account:


You can submit your own gifs to the page as well, and I’d love to see a nice range of stuff up there. Just make sure that the gif is under 2MB – the tumblr limit, not mine. And as far as I can tell, tumblr won’t credit the poster, so if you want credit, credit yourself in the description. It’s also nice to include or link to the code that created the gif (pastebin.com is nice for this) but not required.