Our BLOG

Building Cheerify.it

Cheerify.it started with a simple idea: What would a website look like if you could decorate it with Christmas lights and sync it music. We've been wanting to play with using browser bookmarks to manipulate the contents of a website, so we extended the original idea to be able to "Cheerify" any website. Taking over a website via browser bookmarks is not a new idea. Because javascript runs on the client side, there is a lot of potential for automation of redundant tasks. We wanted to create something less useful but more fun. Something along the lines of the Doge bookmark, YAAARRRify bookmark and Harlem Shake bookmark but just a little more ridiculous. Building The Prototype We had seen bookmarks manipulate elements on screen to music before. The tricky part was going to be building a framework that allowed us to easily sync animations to music. First, I want to give a huge shout out to Moovweb for their Harlem Shake bookmarklet. Not only did it serve as a source of inspiration but it gave me a great place to start building out my framework. The original Harlem Shake bookmarklet works by inserting an HTML5 audio element into the page and using a setTimeout to wait 15 seconds before making everything on the screen go crazy. They've since updated their code on GitHub to a more reliable method, but I'll get to that in a second. So using the Harlem Shake code as a starting point, we built a framework for adding effects to a timeline. Our framework uses a setInterval() to check the HTML5 audio's currentTime property every 10th of a second. We then iterate through an array of effects to trigger as we approach each timestamp. The array is made up of smaller arrays that include a timestamp and a function to call. Using anonymous functions within our effects array kept our code readable and made it easy for other developers to help orchestrate. It's important to note I could have also used the timeupdate event of the audio element instead of set interval; however, setInterval allowed us to control our proprietary frame rate. HTML5/CSS3 As browsers become smarter, we can do cooler things with them. In this case, we used Cheerify.it as an excuse to play with some of the more cutting edge features of modern browsers like CSS3 animations and HTML5 audio. HTML5 Audio Html5 Audio has come a long way. For this experience, we didn't worry about creating fallbacks for older browsers like we normally would. We've used MediaElements.js on several websites in the past with great success. This time around we kept it simple using only two source files, MP3 and OGG. We then took advantage of the audio element's methods and properties to keep the animations in sync with the music as well as create a little music player that allows users to play/pause and mute the whole experience. CSS3 The real fun was coming up with CSS3 animations. Every animation was made using pure CSS3, even the dancing snowman. Only thing we could have done better with the snowman is used the animation-delay property instead of setTimeout() to trigger different parts of the animation. Both work, just in the future, CSS over javascript. Vanilla Javascript When it came time to writing the javascript that made the magic happen, we decided early on we would build it without jQuery. We mainly did this because we didn't need it. It was also an opportunity to brush up on our DOM manipulation-fu while exploring some of the lesser used ways of selecting elements. To make things easier while we animated, we created a javascript object of arrays of elements that could be manipulated. We started by grabbing all of the elements on screen, document.getElementsByTagName("*"). We then looped through all of the elements and added them to our object of arrays based on: How big they were Where they were located Whether they were hidden or not Whether they were within the viewport or not Then, we created a function for adding effects to elements. This function would add a class to an element and remove it after a set amount of time. This is how we animate all of the things. Creating An Easier Way To Share The Experience All of our early prototypes were executed using the browser bookmark. This made things easy because all I had to do was insert my javascript file before the closing body tag and the whole experience would start. We all agreed however that browser bookmarks are not as intuitive as we needed the experience to be. Our solve for this was to allow people to Cheerify their site by typing a URL into an input box and then pressing "Cheerify It". To accomplish this we used PHP to test if we had a site to cheerify. After grabbing and cleaning up the URL, we used CURL to get the contents of the web page. This is where it got a bit mucky. We assumed that the destination site had well-formed HTML and attempted to insert our cheerify script before the closing body tag. Believe it or not, there are sites out there that have more than one body tag and others with no body tag at all. So, now we had a URL that looked something like http://www.cheerify.it/?site=https://www.ampagency.com with all of the contents of that page grabbed, manipulated and ready to output to the browser. We then echoed out our manipulated HTML and hoped all was well. It wasn't, yet. Using this method, we made several assumptions about how the HTML was formatted. We also had broken paths to all assets using relative URLs. To fix this, we did a very primitive preg_replace to replace all relative paths with absolute ones. This fixed relative URLs in the HTML but not relative URLs lazy loaded with javascript. This was probably the hackiest part of the whole project. To fix broken sites that add content with javascript, we did another search and replaced on all paths after the DOM was fully loaded and all javascript had been executed. I then overwrote the javascript alert() function to silently output to the console to avoid any other interruptions. Going Live One of my favorite development automation tools is Grunt. It played a huge part in automating the staging, minification, auto-prefixing and de-linting of the code during the development process. I've included a modified version of the Gruntfile.js we used in the Cheerify.it GitHub repo. Wrap Up The Cheerify site was a lot of fun to work on and and the team did a great job turning the whole project around in a short time frame. Check out the Cheerify.it Source Code on Github and leave a comment below with your thoughts. Finally, don't forget to Cheerify this page.

    Related Posts