Skip to content
Browse files

Merge pull request #6 from humphd/master

Rest of my stuff
  • Loading branch information...
2 parents 0f284f0 + eabf06c commit 4193a28a9e670fe7ce73740d0da0f70f3242c74c David Humphrey committed Oct 26, 2011
Showing with 98 additions and 105 deletions.
  1. +48 −63 examples/twitter/index.html
  2. +47 −41 examples/twitter/{livetwitter.js → processing-twitter.js}
  3. +3 −1 processing-mobile.js
View
111 examples/twitter/index.html
@@ -2,99 +2,84 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Processing.js LiveTwitter Demo</title>
- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript" ></script>
<script src="../../processing.js" type="text/javascript"></script>
- <script src="livetwitter.js" type="text/javascript"></script>
+ <script src="processing-twitter.js" type="text/javascript"></script>
</head>
<body>
<script id="sketch" type="application/processing">
// Dynamic list of Tweet objects
- HashMap tweets;
+ HashMap uniqueTweets;
- // A class representing a Tweet
+ // A class representing a Tweet. Tweet objects are created in JS
+ // and automatically placed in the tweets ArrayList (created in JS)
class Tweet {
- String id;
- String profileName;
- PImage profileImage;
- String text;
- Date time;
- int randomPosX;
- int randomPosY;
-
- Tweet(String aId,
- String aProfileName,
- String aProfileImageURL,
- String aText,
- Date aTime) {
- id = aId;
- profileName = aProfileName;
- profileImage = requestImage(aProfileImageURL);
- text = aText;
- time = aTime;
-
- // Draw profile images to the same place each frame
- randomPosX = random(0, width);
- randomPosY = random(0, height);
- }
+ public String id;
+ public String profileName;
+ public String profileImageUrl;
+ public PImage profileImage; // needs to be loaded manually
+ public String text;
+ public Date time;
+ public int randomPosX; // needs to be set -- randomPosX = random(0, width);
+ public int randomPosY; // needs to be set -- randomPosY = random(0, height);
}
void setup() {
size(1024, 1024);
- tweets = new HashMap();
+
+ uniqueTweets = new HashMap();
+ frameRate(1);
+
+ // Start a live feed loading, results will be available in a global
+ // ArrayList called tweets.
+ loadTweets('bacon');
+
+ // You can also pass geolocation data to limit tweets to a geographic area
+ // loadTweets('class', '43.7496,-79.4886,1km'); // York University
}
void draw() {
- background(255);
+ background(121);
- if (tweets.size() == 0) {
- return;
+ Tweet tweet;
+
+ // Store unique tweets that have come in
+ for (int i = 0; i < tweets.size(); i++) {
+ tweet = (tweet)tweets.get(i);
+ addTweet(tweet);
}
+ tweets.clear();
- Tweet tweet;
- Iterator it = tweets.entrySet().iterator();
+ // Loop through unique tweets we've stored
+ Iterator it = uniqueTweets.entrySet().iterator();
object elem;
-
+ int w, r;
while (it.hasNext()) {
elem = it.next();
tweet = (Tweet)elem.getValue();
+
+ // Draw the profile image
image(tweet.profileImage, tweet.randomPosX, tweet.randomPosY);
+
+ // Print the tweet to the Processing debug console
+ println(tweet.text);
}
}
- // Called from external JS, passes new Tweet object
+ // Store unique tweets (keyed on tweet.id), loading image data
void addTweet(Tweet tweet) {
- // Only store each tweet once (twitter sends them over and over)
- if (!tweets.containsKey(tweet.id)) {
- tweets.put(tweet.id, tweet);
- }
- }
+ if (!uniqueTweets.containsKey(tweet.id)) {
+ // Load a PImage of the profile pic
+ tweet.profileImage = requestImage(tweet.profileImageUrl);
- // Called from external JS, removes count tweets.
- void removeTweets(count) {
- while(count-- >= 0) {
- tweets.remove(tweets.size() - 1);
- }
- }
+ // Draw profile images to the same place each frame
+ tweet.randomPosX = random(0, width);
+ tweet.randomPosY = random(0, height);
- void clearTweets() {
- background(255);
- tweets.clear();
+ // Store the tweet in our list of unique tweets
+ uniqueTweets.put(tweet.id, tweet);
+ }
}
</script>
-
- <div>
- <button onclick="twitter.start();">Start</button>
- <button onclick="twitter.stop();">Stop</button>
- <button onclick="twitter.clear();">Clear</button>
- </div>
-
<canvas id="tweets"></canvas>
-
- <script type="text/javascript">
- var p = new Processing("tweets", document.getElementById("sketch").text);
-// $('#twitterSearch').liveTwitter('chicago', {limit: 10, rate: 5000, rpp: 10, geocode: '41.7897563,-87.5997711,1km'});
- liveTwitter('toronto', {limit: 50, rate: 5000, rpp: 50}, p);
-
- </script>
</body>
</html>
View
88 examples/twitter/livetwitter.js → examples/twitter/processing-twitter.js
@@ -8,25 +8,46 @@
* Modified by David Humphrey (@humphd) for use with Processing.js
*/
-/*
- * Usage example:
- * liveTwitter('bacon', {limit: 10, rate: 15000}, processingInstance);
- */
-
-
-(function ($) {
-
- // Extend jQuery with a reverse function if it isn't already defined
- if (!$.fn.reverse) {
- $.fn.reverse = function () {
- return this.pushStack(this.get().reverse(), arguments);
+(function (document, Processing) {
+
+ function getScript(success) {
+ var script = document.createElement('script');
+ script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js";
+ var head=document.getElementsByTagName('head')[0],
+ done=false;
+ script.onload = script.onreadystatechange = function(){
+ if ( !done && (!this.readyState
+ || this.readyState == 'loaded'
+ || this.readyState == 'complete') ) {
+ done=true;
+ success(jQuery);
+ script.onload = script.onreadystatechange = null;
+ }
};
+ head.appendChild(script);
}
- this.liveTwitter = function(query, options, processing, callback) {
+ // Expose two new globals to Processing sketches:
+ // 1) loadTweets() a function to start a live-feed query
+ // 2) tweets an ArrayList of tweets that have been loaded
+ var Pp = Processing.prototype;
+
+ Pp.tweets = new Pp.ArrayList();
+
+ Pp.loadTweets = function(query, geocode) {
+ var options = {geocode: geocode};
+ getScript(function(jQuery) {
+ loadTweets$(jQuery, query, options);
+ });
+ };
- // Put the tweets on the global so Processing can get them too.
- window.tweets = [];
+ function loadTweets$(jQuery, query, options, callback) {
+ // Extend jQuery with a reverse function if it isn't already defined
+ if (!$.fn.reverse) {
+ $.fn.reverse = function () {
+ return this.pushStack(this.get().reverse(), arguments);
+ };
+ }
$(this).each(function () {
var settings = {};
@@ -50,8 +71,8 @@
// These are the default settings.
settings = $.extend({
mode: 'search', // Mode, valid options are: 'search', 'user_timeline', 'list', 'home_timeline'
- rate: 15000, // Refresh rate in ms
- limit: 10, // Limit number of results
+ rate: 3000, // Refresh rate in ms
+ limit: 100, // Limit number of results
imageSize: 24, // Size of image in pixels
refresh: true,
timeLinks: true,
@@ -271,13 +292,13 @@
// Create an object useable by Processing
toP5: function (tweet) {
- return new processing.Tweet(
- tweet.id,
- tweet.screen_name,
- tweet.profile_image_url, // will get async loaded
- tweet.text,
- this.relativeTime(tweet.created_at)
- );
+ return {
+ id: tweet.id,
+ profileName: tweet.screen_name,
+ profileImageUrl: tweet.profile_image_url,
+ text: tweet.text,
+ date: this.relativeTime(tweet.created_at)
+ };
},
// Handle reloading
@@ -286,8 +307,6 @@
if (twitter.settings.refresh || initialize) {
$.getJSON(twitter.apiURL(), function (json) {
- var newTweets = 0;
-
// The search and regular APIs differ somewhat
var results = (twitter.settings.mode === 'search') ? json.results : json;
@@ -298,25 +317,13 @@
if (!twitter.settings.filter || twitter.settings.filter(this)) {
// Check if this is actually a new tweet
if (Date.parse(tweet.created_at) > twitter.lastTimeStamp) {
- processing.addTweet(twitter.toP5(tweet));
+ Pp.tweets.add(twitter.toP5(tweet));
// Remember the last timestamp for the next refresh.
twitter.lastTimeStamp = Date.parse(tweet.created_at);
-
- newTweets++;
}
}
});
-
- // Did we get any new tweets?
- if (newTweets > 0) {
- // Remove old entries exceeding the limit
- var extra = newTweets - twitter.settings.limit;
- if (extra > 0) {
- processing.removeTweets(newTweets - twitter.settings.limit);
- newTweets -= extra;
- }
- }
});
}
},
@@ -342,7 +349,6 @@
// Clear all tweets
clear: function () {
- processing.clearTweets();
this.lastTimeStamp = null;
}
};
@@ -359,4 +365,4 @@
});
return this;
};
-})(jQuery);
+})(window.document, Processing);
View
4 processing-mobile.js
@@ -11,6 +11,8 @@
* alpha: the direction the device is facing according to the compass
* beta: the angle in degrees the device is tilted front-to-back
* gamma the angle in degrees the device is tilted left-to-right.
+ * compassAccuracy the iOS 5 compass accuracy (or -1)
+ * compassHeading the iOS 5 cCompass heading in degrees or -1
*
* acceleration: (object) acceleration data for device along x, y, and z axes:
* x: (float) device acceleration in m/s^2 along the X axis (-1.0 to 1.0)
@@ -67,7 +69,7 @@
beta: 0,
gamma: 0,
compassAccuracy: -1,
- compassHeading: -1,
+ compassHeading: -1
}
};

0 comments on commit 4193a28

Please sign in to comment.
Something went wrong with that request. Please try again.