I had this idea for an animated gif that was customized for everyone who sees is. We know that a website can look different for each visitor, but I think we often assume that a .gif or .jpg or what ever will be just some file on a server that is the same for everyone.

I thought it would be fun to play with that assumption and surprise people when the gif is based off their location.

Trying it out

When you are trying this out, please review the Geo section. If you can, use the "telling us where you are" link to use the HTML5 location API. If you would rather not, use the middle of nowhere link, or enter in some custom GPS coordinates of your choosing. Also, Choose love, not war :)

How it works

When the connection first comes into the http handler we setup our image source, and then try to pull various Geographic information from the connection. We check for location cookies, then ?latitude=123.5&longitude=-25 get params. If none of that data is available, we fall back to a Maxmind GeoIPLite database.

A goroutine is spawned, handing that information off to the image source. We then create a channel that recieves giftImage structs. This struct has an image, and all the parameters needed for adjust how we render our gif.

Next up, we spawn go routine to the image source pipe, and provide the channel above.

While those two goroutines are busy downloading images, splicing in other gifs, etc they send giftImages on the channel provided.

Finally we call EncodeAll which is a modified version of the go standard library gif encoder, but we pass it the channel above, and the http writer.

This writer ranges over the giftImage channel, and encodes and sends off the frames as soon as they appear on the channel.

The end result is these images have started rendering on the client side while the server is running out and grabbing the data for future frames.

Challenges I ran into

Probably the biggest challenge I ran into was getting everything deployed to GCE via docker. I'm sure I could have done it differently but I would have loved to have been able to do something like the following.

$ git push google master
$ gcloud docker start

Also with an hour and a half to go, I realized that I only had a single instance of the giftServer per handler. This is where the image channel lived, so if multiple people visited the same image then the frames would be all spliced together. I wrapped the handler with an anonymous function to create a new server to handle the connections and everything was fine.

The resolution of the free geoip lookup is a little poor, or old, so was glad to be able to incorporate the HTML5 geolocation api to get a better location.

Accomplishments that I'm proud of

I was proud to be able to accomplish most of the features within the first 24 hours, and be able to spend quite a bit of time tweaking the images that were generated.

What I learned

I have done quite a bit of work, but haven't had much of a need for goroutines and channels. They really helped out with the design of this program and simplified the process quite a bit.

What's next for Gift

Maybe some more images, maybe the reddit front page, who know.

Share this project: