// // Java/Processing Flickr Rainbow. // Draws the 12 most recent images from each of the tags of the rainbow. // // (C) Copyright Tom Carden 2004. // // Code is published under an Attribution/Share-alike Creative Commons license. // http://creativecommons.org/licenses/by-sa/2.0/ // // Requires 2 PHP files, the source code of which are included at the bottom of this file. // // Additionally requires nanoxml-lite: http://nanoxml.cyberelf.be/downloads/nanoxml-lite-2.2.3.jar // //static final String keywords[] = { "blue,indigo", "orange", "violet,purple", "green", "pink", "yellow", "red" }; // ALERT! Spaces have strange effects! //static final color[] rainbowCols = { #0000ff, #ff8000, #ff00ff, #00ff00, #ffdddd, #ffff00, #ff0000 }; static final String keywords[] = { "violet,purple,pink", "blue,indigo", "green", "yellow,gold", "orange", "red,crimson,burgundy" }; // ALERT! Spaces have strange effects! static final color[] rainbowCols = { #ff00ff, #0000ff, #00ff00, #ffff00, #ff8000, #ff0000 }; static final int COLUMNS = 12; Vector images = null; Stack imageUrls = null; boolean stopFetching = false; boolean rainbow = true; boolean gotOne = false; // mouse over? public class FlickrImage { BImage img; float rx,ry; // rainbow position float gx,gy; // grid position float x,y; // actual position float rsc; float gsc; float sc; String url; boolean hover = false; float range = 0.0; FlickrImage() { x = rx = gx = width/2; y = ry = gy = height+37.5; sc = rsc = gsc = 1; } void exist() { if (rainbow) { x += (rx - x) / 15.0; y += (ry - y) / 15.0; } else { x += (gx - x) / 15.0; y += (gy - y) / 15.0; } range = sc * img.width * 0.5; hover = false; if (!gotOne && mouseX > x-range && mouseY > y-range && mouseX < x+range && mouseY < y+range) { sc += (1.05 - sc) / 3.0; cursor(HAND); gotOne = true; hover = true; if(mousePressed && online()) { link(url, "flickr"); } } else if (rainbow) { sc += (rsc - sc) / 15.0; } else { sc += (gsc - sc) / 15.0; } } void draw() { replicate(img,0,0,74,74,int(x-range),int(y-range),int(x+range),int(y+range)); } } public class FlickrFetcher implements Runnable { public void run() { float maxrad = 0.8 * min(height, width/2); for (int i = 0; imageUrls.size() > 0 && !stopFetching; i++) { String url = (String)imageUrls.pop(); FlickrImage nextImg = new FlickrImage(); print("fetching: " + url); nextImg.img = loadImage(url); println(" done"); float angle = PI * float(i%COLUMNS)/float(COLUMNS-1); float radius = maxrad - (0.75 * maxrad * float(i/COLUMNS) / float(keywords.length)); nextImg.rx = (width/2) + radius*cos(angle); nextImg.ry = (height*0.9) - radius*sin(angle); nextImg.rsc = 1.0 - ( 0.3 * (float)(i/COLUMNS) / float(keywords.length)); nextImg.gx = 37.5 + float(i%COLUMNS)*75.0; nextImg.gy = 37.5 + float(i/COLUMNS)*75.0; nextImg.gsc = 1.0; if (online()) { nextImg.url = "http://www.flickr.com/photo.gne?id="+url.substring(url.indexOf("id=")+3,url.indexOf("owner=")); } if (nextImg.img != null) { images.addElement(nextImg); } } } } void keyPressed() { rainbow = !rainbow; } boolean doneParsing = false; int progress = 0; void setup() { size(900, 450); println(online()); smooth(); images = new Vector(); imageUrls = new Stack(); new Thread( new Runnable() { public void run() { for (int i = 0; i < keywords.length; i++) { progress = i; Hashtable arguments = new Hashtable(); arguments.put("tags", keywords[i]); arguments.put("per_page", Integer.toString(COLUMNS)); XMLElement rsp = callFlickr("flickr.photos.search", arguments); if(rsp.getName().equals("rsp")) { if (rsp.getAttribute("stat").equals("ok")) { XMLElement photos = (XMLElement)rsp.getChildren().elementAt(0); Enumeration enum = photos.enumerateChildren(); while (enum.hasMoreElements()) { XMLElement photo = (XMLElement)enum.nextElement(); String id = photo.getStringAttribute("id"); String owner = photo.getStringAttribute("secret"); if (id != null && owner != null) { imageUrls.push(online() ? "flickr_photo.php?id="+id+"&owner="+owner : "http://www.flickr.com/photos/"+id+"_"+owner+"_s.jpg"); } } } } println(keywords[i] + ": " + imageUrls.size()); } doneParsing = true; new Thread( new FlickrFetcher() ).start(); } } ).start(); } void loop() { background(#eeeeff); if (doneParsing) { // translate(0.1*width,0.1*height); // scale(0.8); FlickrImage again = null; for (int i = 0; i < images.size(); i++) { FlickrImage img = (FlickrImage)images.elementAt(i); img.exist(); if (img.hover == true) { again = img; } } for (int i = images.size()-1; i >= 0; i--) { FlickrImage img = (FlickrImage)images.elementAt(i); img.draw(); } if (again != null) { again.draw(); images.removeElement(again); images.insertElementAt(again,0); } } else { for (int i = 0; i < progress; i++) { fill(rainbowCols[i]); stroke(255); rect(width*(float)i/(keywords.length),-10+height/2,width/(keywords.length),20); } } if (!gotOne) { cursor(ARROW); } gotOne = false; } public void stop() { stopFetching = true; super.stop(); } XMLElement callFlickr(String method, Hashtable arguments) { String api_key = "1b5ae44502f9b6b3270aab812e083046"; String url = online() ? "flickr_proxy.php?&method="+method : "http://www.flickr.com/services/rest/?api_key="+api_key+"&method="+method; for (Enumeration enumeration = arguments.keys(); enumeration.hasMoreElements(); ) { String name = (String)enumeration.nextElement(); url += "&" + name + "=" + (String)arguments.get(name); } print("loading: " + url); String lines[] = loadStrings(url); println(" done."); String xmlString=""; for(int i=0; i */ // // and flickr_proxy.php NB: your api key needs inserting in this file /* */