News

Create a 3D tweet archive with Three.js

Create a permanent archive of events on Twitter and display the content in 3D, giving users an interesting way to view their tweets

3Dtweet800

The idea behind this tutorial is if you’ve ever been to a conference, event or training day, there are usually a bunch of interesting tweets floating around afterwards that you wished you’d favourited. So in simple terms we are showing how to archive tweets, but more than that, we are going to show you how to display them in a really interesting way using the 3D properties of CSS3.

Credit is due to all the talented authors whose work we make use of here. To save tweets to a Google spreadsheet, we are using a template built by Martin Hawksey at bit.ly/Z2bMIg that saves the tweets from a search term (for example, a hashtag of an event). The tweets are saved in the CSV format so we’ll use a CSV plug-in for jQuery to parse this into our webpage courtesy of Evan Plaice (code.google.com/p/jquery-csv). Finally we use Mr. doobs’ CSS3D renderer in the ever-popular Three.js. The project needs to be on a web server to work, but you can use a local server on your own computer if you have it configured.

DOWNLOAD TUTORIAL FILES

Getting started

To start this project we will need to take an archive of tweets, head over to mashe.hawksey.info/2013/02/twitter-archive-tagsv5 in your browser and click on the large orange link ‘Twitter Archive Google Spreadsheet – TAGS v5.0’. You will need a Google Drive account for this. You will be prompted to make a copy, click to accept this and make the copy.

Enable the application

Click Enable Custom Menu. This will bring up a prompt for authorisation, click OK, then in the next window hit Accept. Click the Enable Custom Menu again and new menus are added to the page. Click the new TAGS menu and choose ‘Twitter API Authentication’ from the drop-down list.

Enable Twitter

Sign into Twitter and give your application a name and description. You will also need to add a website that the app is due to reside on, however we will be using the Google spreadsheet. Next add the callback URL, which is spreadsheets.google.com/macros. Finally fill in the Captcha at the bottom of the page and click the blue button to proceed.

Authenticate Twitter

The next page displayed will give you a consumer key and consumer secret. Copy them in turn and paste them in the previous tab in your browser, which will be the spreadsheet. Click the Save Configuration button and then go to the Tools menu and choose Script Editor. In the new tab click on the Select Function menu and choose Authenticate Twitter.

Enter a search term

Once you have selected the function, click the play button next to that and you will get a pop-up window stating Authorisation Required. Click Authorise and your spreadsheet is now connected to Twitter. Go back to your Google spreadsheet and enter a search term in point three on the page, this could be a hash tag, a name or a URL.

Generate the spreadsheet

Go to the TAGS menu and choose Run Now. You will need to click on the Archive tab at the bottom of the page. Once run, we are now ready to save the data out as a CSV (Comma Separated Value) file – but let’s get rid of some of the columns we don’t need. Put your cursor anywhere in column A and click Edit>Delete Column A. Then repeat for columns Q, P, O, N, M, K, J and G.

Save the file

Now go to File>Download As>Comma Separated Values. In your OS rename this file ‘archive.csv’ to make it easier to work with. Now copy the Start Folder from the resource disk onto your desktop. These files will need to be on a web server to work, so if you have a local server running put them there.

Adding variables

Inside the Start Folder is a folder named ‘tweetarchive’ – place this on your web server and add your ‘archive.csv’ file to this folder. Open the index.html page in Dreamweaver or similar. Most of the code is in place but scroll down to find the opening script tag on line 135 and add these variables after it.

 001 var table, targets;
  002 var camera, scene, renderer;
  003 var controls;
  004 var objects = [];
  005 $(document).ready(function() {

Load the CSV

We added a jQuery document-ready function in the last step so immediately after that let’s add the code shown here. We are making an AJAX request to load the CSV file so change the URL to your own server. Once we have it loaded we populate the table variable with an array generated from the CSV of tweets.

 001  $.ajax({
 002     url : “http://localhost:8888/tweetarchive/    archive.csv”,
 003     dataType: “text”,
 004     success : function (data) {
 005          var file = data[0];
 006          table = $.csv.toArrays(data);
 007          console.log(table);
 008          targets = { table: [], sphere: [],     helix: [], grid: [] };

Set up the functions

Finally when the document is loaded and the CSV file is loaded, we start setting up the functions. First, we call the ‘init’ function, which will help us to create the elements in 3D. Here we have also added the animate function, which will move all of the tweets in 3D – but this will only happen if the user mouse-clicks on the tweets and then moves them.

 001    init();
 002            animate();
 003            }
 004   });
 005   });

Inside the ‘init’ function

Move down the page and position your cursor inside the ‘init’ function. Now add the code as shown. This sets up a ThreeJS camera in the scene and sets the position of this camera to be back on the Z axis, looking at the centre of the scene, where the tweets are. The scene is then initialised.

001 camera = new THREE.PerspectiveCamera( 75,     window.innerWidth / window.innerHeight, 1,     10000 );
 002 camera.position.z = 1800;
 003 scene = new THREE.Scene();

Creating a loop

Continue adding the following code shown immediately after the last. Here we are starting a for loop to go through each entry in the table array and create a <div> element for each entry. The class name of this is called ‘element’ and a red background is added but with a random opacity.

 001 for ( var i = 1; i < table.length; i ++ ) {
 002        var item = table[ i ];
 003        var element = document.createElement(     ‘div’ );
 004        element.className = ‘element’;
 005        element.style.backgroundColor =     ‘rgba(183,0,0,’ + ( Math.random() * 0.5 + 0.25     ) + ‘)’;

Take a number

Now add let’s add the following code. here we create a new <div> with class of ‘number’ for every tweet. This is positioned with CSS in the top-right of the tweet window. This does not serve any purpose except in testing it allowed us to see if all the tweets were being rendered. We found it could render up to about 270 tweets on screen in 3D – not bad!

 001 var number = document.createElement( ‘div’ );
 002 number.className = ‘number’;
 003 number.textContent = i;
 004 element.appendChild( number );

Display Twitter name

The next element we need to display is the Twitter username. If you look back at the CSV file, the first element in there is the username, and to get that in an array it is position ‘0’. We gave this the class name of ‘symbol’ so any CSS with that class will relate to this.

 001 var symbol = document.createElement( ‘div’ );
 002 symbol.className = ‘symbol’;
 003 symbol.textContent = item[ 0 ];
 004 element.appendChild( symbol );

The medium is the message

The next <div> element that we create is for the message of the tweet. Again, you can look at the CSV file to see that this is the second column. We add this to the existing <div> tag for the tweet and position it using CSS just below the name of the Twitter user.

 001 var details = document.createElement
 ( ‘div’ );
 002
 003 details.className = ‘details’;
 004 details.innerHTML = item[ 1 ]; 
 005 element.appendChild( details );

Display user picture

The next element that we need to display is the user’s picture, so we again create another <div> tag and give this the class name of ‘pic’. Then we need to add some HTML into this, so we use the JavaScript ‘innerHTML’ command and add the item from the array that contains the user’s picture.

 001 var pic = document.createElement
 ( ‘div’ );
 002 pic.className = ‘pic’;
 003 pic.innerHTML = ‘<img src=’ + item[ 9 ] +     ‘>’;
 004 element.appendChild( pic );

Final step

The last part of this is to add the whole <div> object that contains all of this information. Each of these <divs> are then placed at a random location in 3D space for each of the axis. We close the for loop with the closing bracket. Save the page and view this in the browser via a web server to see it load all those tweets and display them. That’s all there is to it!

 001 var object = new THREE.CSS3DObject( element );
 002     object.position.x = Math.random() * 4000 -     2000;
 003     object.position.y = Math.random() * 4000 -     2000;
 004     object.position.z = Math.random() * 4000 -     2000;    
 005     scene.add( object );
 006
 007     objects.push( object );
 008 }
×