PFont gFont; // display font //Slider slide; ColorSet csStart; ColorSet csEnd; ColorSet csMid; Button recenter; float yang=0; void setup() { size(600, 420, P3D); frameRate(50); //slide = new Slider(new PVector(100,100), 200, 10, "R", color(200,50,50)); csStart = new ColorSet(new PVector(10, 100), 200); csMid = new ColorSet(new PVector(10, 200), 200); csEnd = new ColorSet(new PVector(10, 300), 200); csMid.setColor(color(127,127,127)); csEnd.setColor(color(255,255,255)); recenter = new Button(new PVector(20,400), "Center Midpoint"); gFont = createFont("FFScala", 25); textFont(gFont, 25); } void drawCube(color a, color b, color c) { pushMatrix(); translate(3*width/4, height/2, -30); if (keyPressed) { if (key == CODED) { if (keyCode == LEFT) { yang -= .1; } else if (keyCode == RIGHT) { yang += .1; } } } rotateY(-1*PI/5+yang); scale(90,-90,90); strokeWeight(3); beginShape(LINES); for (float u = 0; u <= 1.0-.05; u += .1) { color cc = bezInterp(a,b,c,u); PVector p = colorToVec(cc); stroke(cc); vertex(p.x,p.y,p.z); cc = bezInterp(a,b,c,u+.1); p = colorToVec(cc); stroke(cc); vertex(p.x,p.y,p.z); } endShape(); colorMode(RGB, 1); beginShape(QUADS); noFill(); stroke(0, 1, 1); vertex(-1, 1, 1); stroke(1, 1, 1); vertex( 1, 1, 1); stroke(1, 0, 1); vertex( 1, -1, 1); stroke(0, 0, 1); vertex(-1, -1, 1); stroke(1, 1, 1); vertex( 1, 1, 1); stroke(1, 1, 0); vertex( 1, 1, -1); stroke(1, 0, 0); vertex( 1, -1, -1); stroke(1, 0, 1); vertex( 1, -1, 1); stroke(1, 1, 0); vertex( 1, 1, -1); stroke(0, 1, 0); vertex(-1, 1, -1); stroke(0, 0, 0); vertex(-1, -1, -1); stroke(1, 0, 0); vertex( 1, -1, -1); stroke(0, 1, 0); vertex(-1, 1, -1); stroke(0, 1, 1); vertex(-1, 1, 1); stroke(0, 0, 1); vertex(-1, -1, 1); stroke(0, 0, 0); vertex(-1, -1, -1); stroke(0, 1, 0); vertex(-1, 1, -1); stroke(1, 1, 0); vertex( 1, 1, -1); stroke(1, 1, 1); vertex( 1, 1, 1); stroke(0, 1, 1); vertex(-1, 1, 1); stroke(0, 0, 0); vertex(-1, -1, -1); stroke(255, 0, 0); vertex( 1, -1, -1); stroke(255, 0, 255); vertex( 1, -1, 1); stroke(0, 0, 255); vertex(-1, -1, 1); endShape(); colorMode(RGB,255); popMatrix(); } void draw() { background(153); csStart.update(); csMid.update(); csEnd.update(); int numSlices = 30; noStroke(); int xs = 10, ymin = 10, ymax = 60; int sw = 580 / numSlices; color a = csStart.getColor(); color b = csMid.getColor(); color c = csEnd.getColor(); beginShape(QUAD_STRIP); for (int i = 0; i <= numSlices; i++) { fill(bezInterp(a,b,c,float(i)/float(numSlices))); vertex(xs+sw*i,ymin); vertex(xs+sw*i,ymax); } endShape(); if (recenter.update()) { csMid.setColor(cLerp(a,c,.5)); } drawCube(a,b,c); } color cLerp(color a, color b, float u) { return color( red(a)*(1-u)+red(b)*u, blue(a)*(1-u)+blue(b)*u, green(a)*(1-u)+green(b)*u ); } color bezInterp(color a, color b, color c, float u) { return cLerp(cLerp(a,b,u),cLerp(b,c,u),u); } PVector colorToVec(color a) { return new PVector(2 * red(a) / 255 - 1, 2 * green(a) / 255 - 1, 2 * blue(a) / 255 - 1); } class ColorSet { Slider[] sliders; String[] names; color[] colors; PVector p; void setColor(color c) { sliders[0].setColor(red(c)); sliders[1].setColor(blue(c)); sliders[2].setColor(green(c)); } color getColor() { return color(sliders[0].getColor(), sliders[1].getColor(), sliders[2].getColor()); } ColorSet(PVector pos, int len) { p = pos; sliders = new Slider[3]; names = new String[3]; names[0] = "R"; names[1] = "G"; names[2] = "B"; colors = new color[3]; colors[0] = color(200,50,50); colors[1] = color(50,200,50); colors[2] = color(50,50,200); for (int i = 0; i < 3; i++) { sliders[i] = new Slider(new PVector(pos.x, pos.y + i*22), len, 10, names[i], colors[i]); } } void update() { for (int i = 0; i < 3; i++) { sliders[i].update(); } strokeWeight(1); fill(getColor()); stroke(255); rect(p.x + sliders[0].len + 5, p.y - 11, 22*3, 22*3); } } class Slider { PVector pos; float value; float len, offset, radius; boolean locked; String name; int range; color col; float clamp(float x) { if (x < 0) return 0; if (x > len) return len; return x; } int getValue(int _min, int _max) { return (int)((_max - _min) * (value / len) + _min); } int getColor() { return getValue(0, 255); } void setColor(float c) { value = len*c/255.0; } Slider(PVector p, float l, float r, String n, color c) { pos = p; len = l; locked = false; radius = r; name = n; value = 0; col = c; } void update() { boolean mouse = mousePressed; if (!mouse && locked) { locked = false; } if (locked) { value = clamp(mouseX + offset - pos.x); } else { boolean over = overCirc(pos.x + value, pos.y, radius); if (over && mousePressed) { locked = true; offset = pos.x + value - mouseX; //print("offset = " + offset + "\n"); } } stroke(col); strokeWeight(2); line(pos.x, pos.y, pos.x + len, pos.y); fill(255); stroke(0); // strokeWeight(1); ellipse(pos.x + value, pos.y, radius, radius); } } boolean overRect(float x, float y, float width, float height) { if (mouseX >= x && mouseX <= x+width && mouseY >= y && mouseY <= y+height) { return true; } else { return false; } } boolean overCirc(float x, float y, float rad) { float dx = x - mouseX; float dy = y - mouseY; return (dx*dx + dy*dy < rad*rad); } // simple button class class Button { PVector pos; String msg; boolean locked; Button(PVector p, String m) { pos = p; msg = m; locked = false; } boolean update() { stroke(0); if (locked) fill(200); else fill(255); rect(pos.x-2, pos.y-textAscent()-2, textWidth(msg)+4, textDescent()+textAscent()+4); fill(0); text(msg, pos.x, pos.y); boolean toRet = false; boolean over = overRect(pos.x-2, pos.y-textAscent()-2, textWidth(msg)+4, textDescent()+textAscent()+4); if (locked && !mousePressed) { if (over) { toRet = true; } locked = false; } else if (mousePressed && over) { locked = true; } return toRet; } }