class Color {
int r,g,b;
Color(int r,int g,int b) {
this.r = r;
this.g = g;
this.b = b;
}
int getRed() {
return r;
}
int getGreen() {
return g;
}
int getBlue() {
return b;
}
void setRed(int r) {
this.r = r;
}
void setGreen(int g) {
this.g = g;
}
void setBlue(int b) {
this.b = b;
}
}
class Line
{
String myString;
float xPosition;
float yPosition;
int highlightNum;
float speed;
float curlInX;
Letter myLetters[];
Line(String s, float i, float j)
{
myString = s;
xPosition = i;
yPosition = j;
myLetters = new Letter[s.length()];
float f1 = 0.0;
for(int k = 0; k < s.length(); k++)
{
char c = s.charAt(k);
f1 += textWidth(c);
Letter letter = new Letter(c, f1, 0.0);
myLetters[k] = letter;
}
curlInX = 0.1;
}
}
class Letter
{
char myChar;
float x;
float y;
Letter(char c, float f, float f1)
{
myChar = c;
x = f;
y = f1;
}
}
class Word
{
String myName;
int x;
Word(String s)
{
myName = s;
}
}
Random generator;
// A simple Particle class, renders the particle as an image
class Particle {
PVector loc;
PVector vel;
PVector acc;
float timer;
PImage img;
// One constructor
Particle(PVector a, PVector v, PVector l, PImage img_) {
acc = a.get();
vel = v.get();
loc = l.get();
timer = 100.0;
img = img_;
}
// Another constructor (the one we are using here)
Particle(PVector l,PImage img_) {
acc = new PVector(0.0,0.0,0.0);
float x = (float) generator.nextGaussian()*0.3f;
float y = (float) generator.nextGaussian()*0.3f - 1.0f;
vel = new PVector(x,y,0);
loc = l.get();
timer = 100.0;
img = img_;
}
void run() {
update();
render();
}
// Method to apply a force vector to the Particle object
// Note we are ignoring "mass" here
void add_force(PVector f) {
acc.add(f);
}
// Method to update location
void update() {
vel.add(acc);
loc.add(vel);
timer -= 2.5;
acc.mult(0);
}
// Method to display
void render() {
imageMode(CORNER);
tint(255,timer);
image(img,loc.x-img.width/2,loc.y-img.height/2);
}
// Is the particle still useful?
boolean dead() {
if (timer <= 0.0) {
return true;
} else {
return false;
}
}
}
PImage bg;
PImage word;
PImage lines;
PGraphics pg;
int centerX = 328;
int centerY = 238;
float bigRadius = 189f;
Line seconds[];
Line minutes[];
Line mseconds[];
Line hours[];
Color sColor;
Color mColor;
Color bColor;
Color msColor;
Color hColor;
ArrayList cityColors;
ArrayList cityImages;
float sradius = 185;
float mradius = 160;
float msradius = 210;
float isradius = 74;
float imradius = 58;
float imsradius = 90;
float detectradius = 40;
long initMills;
int initSecond;
float sSize = 18f;
float mSize = 24f;
float msSize = 12f;
float hSize = 21.6f;
int hourt = 0;
int secondt = 0;
int minutet = 0;
float tmpCX = 0;
float tmpCY = 0;
float angleMS;
float angleS;
float angleM;
float angleDelta = PI / 360;
float radius = 112;
boolean millisBegin = false;
//for display state
//0: display big map
//1: change to small timer
//2: display small timer
//3: change to big map
int showType = 0;
int changeCount = 20;
int changeMax = 20;
int displayCount = 0;
int displayMax = 20;
Boolean displayCityNames = false;
ArrayList cityNames;
PFont cityFont;
PFont numberFont;
int continueTime = 25;
int continueFrame = 0;
int citySelect = 0;
void setup() {
frameRate(60);
smooth();
//hint(ENABLE_OPENGL_4X_SMOOTH);
bg = loadImage("clock.png");
word = loadImage("word.png");
lines = loadImage("lines.png");
size(640, 480, P3D);
colorMode(RGB, 255, 255, 255, 60);
pg = createGraphics(640, 480, P2D);
//pg.smooth();
seconds = new Line[60];
minutes = new Line[60];
mseconds = new Line[60];
hours = new Line[6];
cityImages = new ArrayList();
cityImages.add(loadImage("la.png"));
cityImages.add(loadImage("london.png"));
cityImages.add(loadImage("beijing.png"));
cityImages.add(loadImage("sp.png"));
cityImages.add(loadImage("tokyo.png"));
cityImages.add(loadImage("helsinki.png"));
cityColors = new ArrayList();
cityColors.add(new Color(103,120,119));
cityColors.add(new Color(164,87,147));
cityColors.add(new Color(166,61,53));
cityColors.add(new Color(229,114,35));
cityColors.add(new Color(242,146,21));
cityColors.add(new Color(98,131,92));
cityNames = new ArrayList();
ArrayList tempL = new ArrayList();
tempL.add("Casablanca");
tempL.add("Dublin");
tempL.add("Lisban");
tempL.add("London");
tempL.add("Liverpool");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Amsterdam");
tempL.add("Berlin");
tempL.add("Budapest");
tempL.add("Copenhagen");
tempL.add("Madrid");
tempL.add("Paris");
tempL.add("Praque");
tempL.add("Rome");
tempL.add("Sarajewo");
tempL.add("Stockholm");
tempL.add("Vienna");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Amman");
tempL.add("Alhens");
tempL.add("Beinut");
tempL.add("Bucharest");
tempL.add("Cairo");
tempL.add("Helsinki");
tempL.add("Istanbul");
tempL.add("Jerusalem");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Baghdad");
tempL.add("Kuwait");
tempL.add("Moscow");
tempL.add("St.Pertersburg");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Abu Dubai");
tempL.add("Baku");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Islamabad");
tempL.add("Karachi");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Almaty");
tempL.add("Astana");
tempL.add("Dhaka");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Bangkok");
tempL.add("Hanoi");
tempL.add("Jakarta");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Beijing");
tempL.add("Chongqing");
tempL.add("Hong Kong");
tempL.add("Irkutsk");
tempL.add("Kuala Lumpur");
tempL.add("Makassar");
tempL.add("Perth");
tempL.add("Singapore");
tempL.add("Taipei");
tempL.add("Ulaan Bataar");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Osaka");
tempL.add("Sapporo");
tempL.add("Seoul");
tempL.add("Tokyo");
tempL.add("Yakutsk");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Brisbane");
tempL.add("Canberra");
tempL.add("Quam");
tempL.add("Hobart");
tempL.add("Melhourne");
tempL.add("Port Moresby");
tempL.add("Sydney");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Magadan");
tempL.add("New Caledonia");
tempL.add("Solomon Is.");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Auckland");
tempL.add("Fiji");
tempL.add("Marshall Is.");
tempL.add("Wellington");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Samoa");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Hawaii");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Alaska");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Paciffic time(US&Canada)");
tempL.add("Tijuana");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Arizona");
tempL.add("Chihuahua");
tempL.add("Mountain time(US&Canada)");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Central America");
tempL.add("Central time(US&Canada)");
tempL.add("Mexico City");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Bogota");
tempL.add("Eastern time(US&Canada)");
tempL.add("Indiana");
tempL.add("Lima");
tempL.add("Quito");
tempL.add("Rio Branco");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Atlantic time(Canada)");
tempL.add("Caracas");
tempL.add("Santiago");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Brasilia");
tempL.add("Buenos Aires");
tempL.add("Georgetown");
tempL.add("Greenland");
tempL.add("Montevideo");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Mid-Atlantic");
cityNames.add(tempL);
tempL = new ArrayList();
tempL.add("Azores");
tempL.add("Cape Verde Is.");
cityNames.add(tempL);
angleMS = random(0,TWO_PI);
angleM = random(0,TWO_PI);
angleS = random(0,TWO_PI);
initMills = millis();
initSecond = second();
bColor = new Color(0,0,0);
numberFont = loadFont("BatmanForeverAlternate-48.vlw");
cityFont = loadFont("Arial-BoldMT-48.vlw");
textFont(numberFont,1.0);
sColor = new Color(26, 170, 234);
mColor = new Color(240, 15, 18);
msColor = new Color(255,223,36);
hColor = new Color(255,255,255);
hours[0] = new Line(" Los Angeles", 0, 0);
hours[1] = new Line(" London", 0, 0);
hours[2] = new Line(" Beijing", 0, 0);
hours[3] = new Line(" St.Petersburg", 0, 0);
hours[4] = new Line(" Tokyo", 0, 0);
hours[5] = new Line(" Helsinki", 0, 0);
Line tmpL;
for(int i=0; i<60; i++) {
tmpL = new Line(""+i, cos( - i * TWO_PI / 60 + PI / 2) * sradius,
- sin( - i * TWO_PI / 60 + PI / 2) * sradius);
seconds[i] = tmpL;
tmpL = new Line(""+i, cos( - i * TWO_PI / 60 + PI / 2) * mradius,
- sin( - i * TWO_PI / 60 + PI / 2) * mradius);
minutes[i] = tmpL;
tmpL = new Line(""+i, cos( - i * TWO_PI / 60 + PI / 2) * msradius,
- sin( - i * TWO_PI / 60 + PI / 2) * msradius);
mseconds[i] = tmpL;
}
bigRadius = random(-20,20) + 195f;
}
int timezone(int index){
switch(index){
case 0: return 0;
case 1: return 8;
case 2: return 16;
case 3: return 11;
case 4: return 17;
case 5: return 10;
default: return 0;
}
}
void draw() {
//background(bColor.getRed(), bColor.getGreen(),bColor.getBlue());
Line tmp;
long msecondsl = 0;
float angle = 0;
Color tmpC = new Color(0,0,0);
secondt = second() + 1; // Values from 0 - 59
minutet = minute() + 1; // Values from 0 - 59
if((hour() + timezone(citySelect)) % 24 != hourt) {
hourt = (hour() + timezone(citySelect)) % 24;
bigRadius = random(-20,20) + 195f;
} // Values from 0 - 23
tmpCX = centerX + cos(HALF_PI - hourt * TWO_PI / 24) * bigRadius;
tmpCY = centerY - sin(HALF_PI - hourt * TWO_PI / 24) * bigRadius;
if(showType == 0 || showType == 1) {
//background(bg);
pg.beginDraw();
pg.smooth();
if(showType == 0) {
pg.background(60);
pg.tint(255, 255);
pg.strokeWeight(3);
tmpC = (Color)(cityColors.get(hourt % 6));
pg.stroke(tmpC.getRed(),tmpC.getGreen(),tmpC.getBlue());
pg.line(centerX, centerY, tmpCX, tmpCY);
pg.image(bg, 0, 0);
pg.image((PImage)cityImages.get(citySelect), 0, 0);
}
else {
pg.tint(255, 255 * changeCount / changeMax);
pg.background(30 + 30 * changeCount / changeMax,
30 + 30 * changeCount / changeMax,
38 + 22 * changeCount / changeMax);
}
if(showType == 0)
pg.translate(tmpCX, tmpCY);
else {
pg.image(bg, (changeMax - changeCount) * ( - tmpCX + centerX) / changeMax,
(changeMax - changeCount) * ( - tmpCY + centerY) / changeMax,
((changeMax - changeCount) * 0.1 + 1) * 640,
((changeMax - changeCount) * 0.1 + 1) * 480);
pg.translate(centerX + changeCount * (tmpCX - centerX) / changeMax,
centerY + changeCount * (tmpCY - centerY) / changeMax);
pg.scale( (changeMax - changeCount) * 0.1 + 1);
changeCount--;
if(changeCount < 0) {
showType = 2;
changeCount = changeMax;
}
}
}
if(secondt != initSecond && !millisBegin) {
initMills = millis();
millisBegin = true;
}
if(millisBegin) {
msecondsl = millis() - initMills;
msecondsl = (msecondsl % 1000) * 60 / 1000;
}
if(showType == 0 || showType == 1) {
//pg.hint(ENABLE_OPENGL_4X_SMOOTH);
//pg.smooth();
//pg.background(bg);
pg.noFill();
pg.strokeWeight(7);
pg.stroke(sColor.getRed(), sColor.getGreen(), sColor.getBlue(), 255 * changeCount / changeMax);
angle = secondt * TWO_PI / 60;
pg.pushMatrix();
pg.rotate(-PI/2);
pg.arc(0,0,isradius,isradius,0,angle);
pg.strokeWeight(9);
pg.stroke(mColor.getRed(), mColor.getGreen(), mColor.getBlue(), 255 * changeCount / changeMax);
angle = minutet * TWO_PI / 60;
pg.arc(0,0,imradius,imradius,0,angle);
if(millisBegin) {
pg.strokeWeight(5);
pg.stroke(msColor.getRed(), msColor.getGreen(), msColor.getBlue(), 255 * changeCount / changeMax);
angle = msecondsl * TWO_PI / 60;
pg.arc(0,0,imsradius,imsradius,0,angle);
}
pg.noStroke();
tmpC = (Color)(cityColors.get(hourt % 6));
pg.fill(tmpC.getRed(),tmpC.getGreen(),tmpC.getBlue());
pg.ellipse(0,0,detectradius,detectradius);
pg.popMatrix();
smooth();
image(pg,0,0);
strokeWeight(15);
stroke(167,255,75);
fill(167,255,75);
if(hourt > 11){
line(500,0,640,0);
}else{
line(0,0,140,0);
}
if(continueFrame != 0){
textSize(14);
if(hourt > 11){
text(hours[0].myString, 490, 20);
text(hours[1].myString, 490, 34);
text(hours[2].myString, 490, 48);
text(hours[3].myString, 490, 62);
text(hours[4].myString, 490, 76);
text(hours[5].myString, 490, 90);
if(mousePressed && mouseX > 505 && mouseY < 20 && mouseY > 10){
citySelect = 0;
}else if(mousePressed && mouseX > 505 && mouseY < 34 && mouseY > 20){
citySelect = 1;
}else if(mousePressed && mouseX > 505 && mouseY < 48 && mouseY > 34){
citySelect = 2;
}else if(mousePressed && mouseX > 505 && mouseY < 62 && mouseY > 48){
citySelect = 3;
}else if(mousePressed && mouseX > 505 && mouseY < 76 && mouseY > 62){
citySelect = 4;
}else if(mousePressed && mouseX > 505 && mouseY < 90 && mouseY > 76){
citySelect = 5;
}
fill(255,255,255);
text(hours[citySelect].myString, 490, 20 + citySelect * 14);
}else{
text(hours[0].myString, -10, 20);
text(hours[1].myString, -10, 34);
text(hours[2].myString, -10, 48);
text(hours[3].myString, -10, 62);
text(hours[4].myString, -10, 76);
text(hours[5].myString, -10, 90);
if(mousePressed && mouseX < 130 && mouseY < 20 && mouseY > 10){
citySelect = 0;
}else if(mousePressed && mouseX < 130 && mouseY < 34 && mouseY > 20){
citySelect = 1;
}else if(mousePressed && mouseX < 130 && mouseY < 48 && mouseY > 34){
citySelect = 2;
}else if(mousePressed && mouseX < 130 && mouseY < 62 && mouseY > 48){
citySelect = 3;
}else if(mousePressed && mouseX < 130 && mouseY < 76 && mouseY > 62){
citySelect = 4;
}else if(mousePressed && mouseX < 130 && mouseY < 90 && mouseY > 76){
citySelect = 5;
}
fill(255,255,255);
text(hours[citySelect].myString, -10, 20 + citySelect * 14);
}
hourt = (hour() + timezone(citySelect)) % 24;
continueFrame++;
if(continueFrame == continueTime) continueFrame = 0;
}else if(hourt>11 && mouseX < 640 && mouseX > 500 && mouseY < 15){
continueFrame++;
}else if(hourt<12 && mouseX < 140 && mouseY < 15){
continueFrame++;
}
}
else if(showType == 2 || showType == 3) {
background(30,30,38);
//background(40);
if(showType == 2) {
image(lines,0,0);
translate(320, 240, -50);
}
else {
tint(255, 255 * changeCount / changeMax);
image(lines,0,0);
translate(320 + (changeMax - changeCount) * (tmpCX - 320) / changeMax,
240 + (changeMax - changeCount) * (tmpCY - 240) / changeMax,
-50 - (changeMax - changeCount) * 10);
changeCount--;
if(changeCount < 0) {
showType = 0;
changeCount = changeMax;
tint(255, 255);
}
}
if(millisBegin) {
for(int i=0; i< msecondsl; i++) {
tmp = mseconds[i];
pushMatrix();
rotateY(angleMS);
translate(tmp.xPosition, tmp.yPosition, 0.0);
for(int j = 0; j < tmp.myLetters.length; j++) {
if(j != 0) {
translate(textWidth(tmp.myLetters[j - 1].myChar) * (msSize) * (i+1) / msecondsl, 0.0, 0.0);
}
pushMatrix();
scale(msSize * (i+1) / msecondsl);
fill(msColor.getRed(), msColor.getGreen(), msColor.getBlue(), 60 * (i+1) / msecondsl);
text(tmp.myLetters[j].myChar, 0.0, 0.0);
popMatrix();
}
popMatrix();
}
}
for(int i=0; i< secondt;i++) {
tmp = seconds[i];
pushMatrix();
rotateY(angleS);
translate(tmp.xPosition, tmp.yPosition, 0.0);
for(int j = 0; j < tmp.myLetters.length; j++) {
if(j != 0) {
translate(textWidth(tmp.myLetters[j - 1].myChar) * sSize * (i+1) / secondt, 0.0, 0.0);
}
pushMatrix();
scale(sSize * (i+1) / secondt);
fill(sColor.getRed(), sColor.getGreen(), sColor.getBlue(), 60 * (i+1) / secondt);
text(tmp.myLetters[j].myChar, 0.0, 0.0);
popMatrix();
}
popMatrix();
}
for(int i=0; i< minutet;i++) {
tmp = minutes[i];
pushMatrix();
rotateY(angleM);
translate(tmp.xPosition, tmp.yPosition, 0.0);
for(int j = 0; j < tmp.myLetters.length; j++) {
if(j != 0) {
translate(textWidth(tmp.myLetters[j - 1].myChar) * mSize * (i+1) / minutet, 0.0, 0.0);
}
pushMatrix();
scale(mSize * (i+1) / minutet);
fill(mColor.getRed(), mColor.getGreen(), mColor.getBlue(), 60 * (i+1) / minutet);
text(tmp.myLetters[j].myChar, 0.0, 0.0);
popMatrix();
}
popMatrix();
}
angleM += angleDelta / 3;
angleMS += angleDelta;
angleS += angleDelta / 2;
tmpC = (Color)(cityColors.get(hourt % 6));
fill(tmpC.getRed(),tmpC.getGreen(),tmpC.getBlue());
noStroke();
lights();
sphereDetail(32);
sphere(detectradius);
tmp = hours[citySelect];
pushMatrix();
angle = abs(hourt + 8) % 12 + 1 + (float)minutet / 60;
angle = angle * TWO_PI / 12;
//translate( - 2 * detectradius * cos(HALF_PI - angle), - 1 * detectradius * sin(HALF_PI - angle));
rotate( angle );
//translate( - detectradius * cos(angle), - detectradius * sin(angle));
scale(hSize);
fill(tmpC.getRed(), tmpC.getGreen(), tmpC.getBlue());
//fill(230);
//text(tmp.myString, - detectradius * cos(HALF_PI - angle) * 0.065,
// detectradius * sin(HALF_PI - angle) * 0.065, 0);
text(tmp.myString, 0, 0, 0);
popMatrix();
}
float moveX,moveY;
moveX = - radius * sin(HALF_PI - hourt * TWO_PI / 24);
moveY = radius * cos(HALF_PI - hourt * TWO_PI / 24);
if(hourt < 11) moveX = -moveX;
if(hourt == 8 || hourt == 9 || hourt == 10){ moveX*=-1; moveY = -200;}
if(hourt > 13){ moveX = -100; moveY = 55; }
if(showType == 0 && (mouseX - tmpCX) * (mouseX - tmpCX) + (tmpCY - mouseY) * (tmpCY - mouseY) < detectradius * detectradius) {
String tmpS;
scale(1.0);
if(showType == 0) {
strokeWeight(2);
stroke(tmpC.getRed(),tmpC.getGreen(),tmpC.getBlue(), displayCount * 255 / displayMax);
line(tmpCX,tmpCY,tmpCX + moveX,tmpCY);
line(tmpCX + moveX,tmpCY,tmpCX + moveX,tmpCY + moveY);
}
textFont(cityFont,1.0);
fill(tmpC.getRed(),tmpC.getGreen(),tmpC.getBlue(), displayCount * 255 / displayMax);
textSize(12);
int tlength = ((ArrayList)cityNames.get(hourt)).size();
for(int i=0;i < tlength;i++) {
tmpS = (String)((ArrayList)cityNames.get(hourt)).get(i);
if(showType == 0)
text(tmpS, tmpCX + moveX, tmpCY + 12 * i + moveY);
else
text(tmpS, tmpCX + moveX, tmpCY + 12 * i + moveY, 255 * changeCount / changeMax);
}
textFont(numberFont,1.0);
if(displayCount < displayMax)
displayCount++;
displayCityNames = true;
}
else if(displayCityNames && showType == 0) {
String tmpS;
strokeWeight(2);
stroke(tmpC.getRed(),tmpC.getGreen(),tmpC.getBlue(), displayCount * 255 / displayMax);
line(tmpCX,tmpCY,tmpCX+moveX,tmpCY);
line(tmpCX+moveX,tmpCY,tmpCX+moveX,tmpCY+moveY);
textFont(cityFont,1.0);
fill(tmpC.getRed(),tmpC.getGreen(),tmpC.getBlue(), displayCount * 255 / displayMax);
textSize(12);
int tlength = ((ArrayList)cityNames.get(hourt)).size();
for(int i=0;i < tlength;i++) {
tmpS = (String)((ArrayList)cityNames.get(hourt)).get(i);
text(tmpS, tmpCX + moveX, tmpCY + 12 * i + moveY);
}
textFont(numberFont,1.0);
if(displayCount > 0)
displayCount--;
else {
displayCityNames = false;
displayCount = displayMax;
}
}
}
void mouseClicked() {
if(showType == 0 && (mouseX - tmpCX) * (mouseX - tmpCX) + (tmpCY - mouseY) * (tmpCY - mouseY) < detectradius * detectradius) {
showType = 1;
continueFrame = 0;
}
else if(showType == 2 && (mouseX - centerX) * (mouseX - centerX) +
(centerY - mouseY) * (centerY - mouseY) < detectradius * detectradius) {
showType = 3;
continueFrame = 0;
}
}
move your mouse to the center of the circle and click to the 3d mode.