mirror of
https://github.com/dataarts/dat.gui.git
synced 2024-12-12 04:08:27 +00:00
0.5
This commit is contained in:
parent
5207fed918
commit
b531665963
@ -1,5 +0,0 @@
|
||||
**dat.gui** is a lightweight controller library for JavaScript. It allows you to easily manipulate variables and fire functions on the fly.
|
||||
|
||||
Check the [index page](http://dataarts.github.com/dat.gui/) for usage.
|
||||
|
||||
Initiated by [George Michael Brower](http://georgemichaelbrower.com/) and [Jono Brandel](http://jonobr1.com/) of the Data Arts Team, Google Creative Lab.
|
@ -1,22 +0,0 @@
|
||||
/**
|
||||
* Provides requestAnimationFrame in a cross browser way.
|
||||
* http://paulirish.com/2011/requestanimationframe-for-smart-animating/
|
||||
*/
|
||||
|
||||
if ( !window.requestAnimationFrame ) {
|
||||
|
||||
window.requestAnimationFrame = ( function() {
|
||||
|
||||
return window.webkitRequestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
window.oRequestAnimationFrame ||
|
||||
window.msRequestAnimationFrame ||
|
||||
function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) {
|
||||
|
||||
window.setTimeout( callback, 1000 / 60 );
|
||||
|
||||
};
|
||||
|
||||
} )();
|
||||
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 3.3 KiB |
File diff suppressed because one or more lines are too long
Binary file not shown.
Before Width: | Height: | Size: 183 B |
Binary file not shown.
Before Width: | Height: | Size: 8.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 670 B |
231
docs/demo.js
231
docs/demo.js
@ -1,231 +0,0 @@
|
||||
function FizzyText(message) {
|
||||
|
||||
var that = this;
|
||||
|
||||
// These are the variables that we manipulate with gui-dat.
|
||||
// Notice they're all defined with "this". That makes them public.
|
||||
// Otherwise, gui-dat can't see them.
|
||||
|
||||
this.growthSpeed = 0.2; // how fast do particles change size?
|
||||
this.maxSize = 5.59; // how big can they get?
|
||||
this.noiseStrength = 10; // how turbulent is the flow?
|
||||
this.speed = 0.4; // how fast do particles move?
|
||||
this.displayOutline = false; // should we draw the message as a stroke?
|
||||
this.framesRendered = 0;
|
||||
|
||||
// __defineGetter__ and __defineSetter__ makes JavaScript believe that
|
||||
// we've defined a variable 'this.message'. This way, whenever we
|
||||
// change the message variable, we can call some more functions.
|
||||
|
||||
this.__defineGetter__("message", function () {
|
||||
return message;
|
||||
});
|
||||
|
||||
this.__defineSetter__("message", function (m) {
|
||||
message = m;
|
||||
createBitmap(message);
|
||||
});
|
||||
|
||||
// We can even add functions to the DAT.GUI! As long as they have
|
||||
// 0 arguments, we can call them from the dat-gui panel.
|
||||
|
||||
this.explode = function() {
|
||||
var mag = Math.random() * 30 + 30;
|
||||
for (var i in particles) {
|
||||
var angle = Math.random() * Math.PI * 2;
|
||||
particles[i].vx = Math.cos(angle) * mag;
|
||||
particles[i].vy = Math.sin(angle) * mag;
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
var _this = this;
|
||||
|
||||
var width = 550;
|
||||
var height = 200;
|
||||
var textAscent = 101;
|
||||
var textOffsetLeft = 80;
|
||||
var noiseScale = 300;
|
||||
var frameTime = 30;
|
||||
|
||||
var colors = ["#00aeff", "#0fa954", "#54396e", "#e61d5f"];
|
||||
|
||||
// This is the context we use to get a bitmap of text using
|
||||
// the getImageData function.
|
||||
var r = document.createElement('canvas');
|
||||
var s = r.getContext('2d');
|
||||
|
||||
// This is the context we actually use to draw.
|
||||
var c = document.createElement('canvas');
|
||||
var g = c.getContext('2d');
|
||||
|
||||
r.setAttribute('width', width);
|
||||
c.setAttribute('width', width);
|
||||
r.setAttribute('height', height);
|
||||
c.setAttribute('height', height);
|
||||
|
||||
// Add our demo to the HTML
|
||||
document.getElementById('helvetica-demo').appendChild(c);
|
||||
|
||||
// Stores bitmap image
|
||||
var pixels = [];
|
||||
|
||||
// Stores a list of particles
|
||||
var particles = [];
|
||||
|
||||
// Set g.font to the same font as the bitmap canvas, incase we
|
||||
// want to draw some outlines.
|
||||
s.font = g.font = "800 82px helvetica, arial, sans-serif";
|
||||
|
||||
// Instantiate some particles
|
||||
for (var i = 0; i < 1000; i++) {
|
||||
particles.push(new Particle(Math.random() * width, Math.random() * height));
|
||||
}
|
||||
|
||||
// This function creates a bitmap of pixels based on your message
|
||||
// It's called every time we change the message property.
|
||||
var createBitmap = function (msg) {
|
||||
|
||||
s.fillStyle = "#fff";
|
||||
s.fillRect(0, 0, width, height);
|
||||
|
||||
s.fillStyle = "#222";
|
||||
s.fillText(msg, textOffsetLeft, textAscent);
|
||||
|
||||
// Pull reference
|
||||
var imageData = s.getImageData(0, 0, width, height);
|
||||
pixels = imageData.data;
|
||||
|
||||
};
|
||||
|
||||
// Called once per frame, updates the animation.
|
||||
var render = function () {
|
||||
|
||||
that.framesRendered ++;
|
||||
|
||||
g.clearRect(0, 0, width, height);
|
||||
|
||||
if (_this.displayOutline) {
|
||||
g.globalCompositeOperation = "source-over";
|
||||
g.strokeStyle = "#000";
|
||||
g.lineWidth = .5;
|
||||
g.strokeText(message, textOffsetLeft, textAscent);
|
||||
}
|
||||
|
||||
g.globalCompositeOperation = "darker";
|
||||
|
||||
for (var i = 0; i < particles.length; i++) {
|
||||
g.fillStyle = colors[i % colors.length];
|
||||
particles[i].render();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Returns x, y coordinates for a given index in the pixel array.
|
||||
var getPosition = function (i) {
|
||||
return {
|
||||
x: (i - (width * 4) * Math.floor(i / (width * 4))) / 4,
|
||||
y: Math.floor(i / (width * 4))
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a color for a given pixel in the pixel array.
|
||||
var getColor = function (x, y) {
|
||||
var base = (Math.floor(y) * width + Math.floor(x)) * 4;
|
||||
var c = {
|
||||
r: pixels[base + 0],
|
||||
g: pixels[base + 1],
|
||||
b: pixels[base + 2],
|
||||
a: pixels[base + 3]
|
||||
};
|
||||
|
||||
return "rgb(" + c.r + "," + c.g + "," + c.b + ")";
|
||||
};
|
||||
|
||||
// This calls the setter we've defined above, so it also calls
|
||||
// the createBitmap function.
|
||||
this.message = message;
|
||||
|
||||
var loop = function() {
|
||||
|
||||
requestAnimationFrame(loop);
|
||||
|
||||
// Don't render if we don't see it.
|
||||
// Would be cleaner if I dynamically acquired the top of the canvas.
|
||||
if (document.body.scrollTop < height + 20) {
|
||||
render();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// This calls the render function every 30 milliseconds.
|
||||
loop();
|
||||
|
||||
// This class is responsible for drawing and moving those little
|
||||
// colored dots.
|
||||
function Particle(x, y, c) {
|
||||
|
||||
// Position
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
|
||||
// Size of particle
|
||||
this.r = 0;
|
||||
|
||||
// This velocity is used by the explode function.
|
||||
this.vx = 0;
|
||||
this.vy = 0;
|
||||
|
||||
// Called every frame
|
||||
this.render = function () {
|
||||
|
||||
// What color is the pixel we're sitting on top of?
|
||||
var c = getColor(this.x, this.y);
|
||||
|
||||
// Where should we move?
|
||||
var angle = noise(this.x / noiseScale, this.y / noiseScale) * _this.noiseStrength;
|
||||
|
||||
// Are we within the boundaries of the image?
|
||||
var onScreen = this.x > 0 && this.x < width &&
|
||||
this.y > 0 && this.y < height;
|
||||
|
||||
var isBlack = c != "rgb(255,255,255)" && onScreen;
|
||||
|
||||
// If we're on top of a black pixel, grow.
|
||||
// If not, shrink.
|
||||
if (isBlack) {
|
||||
this.r += _this.growthSpeed;
|
||||
} else {
|
||||
this.r -= _this.growthSpeed;
|
||||
}
|
||||
|
||||
// This velocity is used by the explode function.
|
||||
this.vx *= 0.5;
|
||||
this.vy *= 0.5;
|
||||
|
||||
// Change our position based on the flow field and our
|
||||
// explode velocity.
|
||||
this.x += Math.cos(angle) * _this.speed + this.vx;
|
||||
this.y += -Math.sin(angle) * _this.speed + this.vy;
|
||||
|
||||
this.r = DAT.GUI.constrain(this.r, 0, _this.maxSize);
|
||||
|
||||
// If we're tiny, keep moving around until we find a black
|
||||
// pixel.
|
||||
if (this.r <= 0) {
|
||||
this.x = Math.random() * width;
|
||||
this.y = Math.random() * height;
|
||||
return; // Don't draw!
|
||||
}
|
||||
|
||||
// Draw the circle.
|
||||
g.beginPath();
|
||||
g.arc(this.x, this.y, this.r, 0, Math.PI * 2, false);
|
||||
g.fill();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
265
docs/docs.css
265
docs/docs.css
@ -1,265 +0,0 @@
|
||||
* {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
body {
|
||||
font: 9.5px/13px Lucida Grande, sans-serif;
|
||||
padding: 0 20px 20px 20px;
|
||||
}
|
||||
|
||||
#container {
|
||||
max-width: 530px;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-family: "Helvetica Neue", helvetica, arial, sans-serif;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 0;
|
||||
height: 0;
|
||||
border-top: 1px dotted #ccc;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 80px;
|
||||
font-weight: 800;
|
||||
text-transform: lowercase;
|
||||
line-height: 80px;
|
||||
margin: 39px 0 20px 0;
|
||||
}
|
||||
|
||||
h1 a:link, h1 a:visited, h1 a:hover, h1 a:active {
|
||||
text-decoration: none;
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
h1 img {
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 30px;
|
||||
font-size: 18px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
h2.section {
|
||||
margin: 0;
|
||||
padding: 20px 0px 20px 0px;
|
||||
cursor: pointer;
|
||||
border-top: 1px dotted #ccc;
|
||||
-webkit-transition: color 0.15s linear;
|
||||
}
|
||||
|
||||
h2.section:hover {
|
||||
color: #00aeff;
|
||||
}
|
||||
|
||||
div.collapsed h2, div.expanded h2 {
|
||||
|
||||
float: left;
|
||||
clear: both;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.last {
|
||||
margin-bottom: 0px !important;
|
||||
}
|
||||
|
||||
.first {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
div.trans {
|
||||
border-top: 1px dotted #ccc;
|
||||
margin: 0px 0px 20px 0px;
|
||||
}
|
||||
|
||||
ol#secrets {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
div.expanded h2:before {
|
||||
content: '-';
|
||||
}
|
||||
|
||||
div.collapsed h2:before {
|
||||
content: '+';
|
||||
}
|
||||
|
||||
div.expanded h2:before, div.collapsed h2:before {
|
||||
font-weight: normal;
|
||||
line-height: 2px;
|
||||
float: left;
|
||||
margin-top: 6px;
|
||||
margin-right: 6px;
|
||||
font-size: 9px;
|
||||
font-family: Monaco, monospace;
|
||||
}
|
||||
|
||||
div.collapsable>div {
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
div.collapsable {
|
||||
overflow: hidden;
|
||||
clear: both;
|
||||
-moz-transition: height .2s ease-out;
|
||||
-webkit-transition: height .2s ease-out;
|
||||
transition: height .2s ease-out;
|
||||
}
|
||||
|
||||
div.collapsable div {
|
||||
padding-bottom: 20px;
|
||||
margin-bottom: -20px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
div.collapsed .collapsable {
|
||||
overflow: hidden;
|
||||
clear: both;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
div.expanded {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#helvetica-demo {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 800;
|
||||
height: 300;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
#notifier {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 230px;
|
||||
width: 271px;
|
||||
height: 142px;
|
||||
background: url("assets/itgivesyouthis.jpg") center 0 no-repeat;
|
||||
z-index: -2;
|
||||
margin: 30px 22px 0 0;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 20px 0 20px 0;
|
||||
padding: 15px;
|
||||
background-color: #222;
|
||||
max-width: 500px;
|
||||
font: 10px Monaco, monospace;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
p, ul, ol {
|
||||
font-size: 125%;
|
||||
clear: both;
|
||||
line-height: 18px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-left: 22px;
|
||||
}
|
||||
|
||||
ul#desc {
|
||||
list-style: circle;
|
||||
font-size: 100%;
|
||||
max-width: 380px;
|
||||
}
|
||||
|
||||
a:link {
|
||||
color: #00aeff;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: #0fa954;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #e61d5f;
|
||||
}
|
||||
|
||||
a:active {
|
||||
color: #54396e;
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 20px;
|
||||
background-color: #eee;
|
||||
width: 510px;
|
||||
padding: 10px;
|
||||
clear: both;
|
||||
color: #444;
|
||||
|
||||
}
|
||||
|
||||
pre a:link,
|
||||
pre a:visited,
|
||||
pre a:active,
|
||||
pre a:hover {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
code {
|
||||
font: 10px Monaco, monospace;
|
||||
}
|
||||
|
||||
code strong {
|
||||
font-weight: normal;
|
||||
color: #e61d5f;
|
||||
}
|
||||
|
||||
.str {
|
||||
color: #0fa954;
|
||||
}
|
||||
|
||||
.kwd {
|
||||
color: #e61d5f;
|
||||
}
|
||||
|
||||
.com {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.typ {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.lit {
|
||||
color: #00aeff;
|
||||
}
|
||||
|
||||
.pun, .opn, .clo {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.pln {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.tag {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.atn {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.atv {
|
||||
color: #777;
|
||||
}
|
||||
|
||||
.dec {
|
||||
color: #606;
|
||||
}
|
@ -1,181 +0,0 @@
|
||||
// http://mrl.nyu.edu/~perlin/noise/
|
||||
|
||||
var ImprovedNoise = function () {
|
||||
|
||||
var p = [151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,
|
||||
23,190,6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,88,237,149,56,87,
|
||||
174,20,125,136,171,168,68,175,74,165,71,134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,
|
||||
133,230,220,105,92,41,55,46,245,40,244,102,143,54,65,25,63,161,1,216,80,73,209,76,132,187,208,
|
||||
89,18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,186,3,64,52,217,226,250,124,123,5,
|
||||
202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,223,183,170,213,119,
|
||||
248,152,2,44,154,163,70,221,153,101,155,167,43,172,9,129,22,39,253,19,98,108,110,79,113,224,232,
|
||||
178,185,112,104,218,246,97,228,251,34,242,193,238,210,144,12,191,179,162,241,81,51,145,235,249,
|
||||
14,239,107,49,192,214,31,181,199,106,157,184,84,204,176,115,121,50,45,127,4,150,254,138,236,205,
|
||||
93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180];
|
||||
|
||||
for ( var i = 0; i < 256 ; i++ ) {
|
||||
|
||||
p[ 256 + i ] = p[ i ];
|
||||
|
||||
}
|
||||
|
||||
function fade( t ) {
|
||||
|
||||
return t * t * t * ( t * ( t * 6 - 15 ) + 10 );
|
||||
|
||||
}
|
||||
|
||||
function lerp( t, a, b ) {
|
||||
|
||||
return a + t * ( b - a );
|
||||
|
||||
}
|
||||
|
||||
function grad( hash, x, y, z ) {
|
||||
|
||||
var h = hash & 15;
|
||||
var u = h < 8 ? x : y, v = h < 4 ? y : h == 12 || h == 14 ? x : z;
|
||||
return ( ( h & 1 ) == 0 ? u : -u ) + ( ( h & 2 ) == 0 ? v : -v );
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
noise: function ( x, y, z ) {
|
||||
|
||||
var floorX = Math.floor( x ), floorY = Math.floor( y ), floorZ = Math.floor( z );
|
||||
|
||||
var X = floorX & 255, Y = floorY & 255, Z = floorZ & 255;
|
||||
|
||||
x -= floorX;
|
||||
y -= floorY;
|
||||
z -= floorZ;
|
||||
|
||||
var xMinus1 = x -1, yMinus1 = y - 1, zMinus1 = z - 1;
|
||||
|
||||
var u = fade( x ), v = fade( y ), w = fade( z );
|
||||
|
||||
var A = p[ X ] + Y, AA = p[ A ] + Z, AB = p[ A + 1 ] + Z, B = p[ X + 1 ] + Y, BA = p[ B ] + Z, BB = p[ B + 1 ] + Z;
|
||||
|
||||
return lerp( w, lerp( v, lerp( u, grad( p[ AA ], x, y, z ),
|
||||
grad( p[ BA ], xMinus1, y, z ) ),
|
||||
lerp( u, grad( p[ AB ], x, yMinus1, z ),
|
||||
grad( p[ BB ], xMinus1, yMinus1, z ) ) ),
|
||||
lerp( v, lerp( u, grad( p[ AA + 1 ], x, y, zMinus1 ),
|
||||
grad( p[ BA + 1 ], xMinus1, y, z - 1 ) ),
|
||||
lerp( u, grad( p[ AB + 1 ], x, yMinus1, zMinus1 ),
|
||||
grad( p[ BB + 1 ], xMinus1, yMinus1, zMinus1 ) ) ) );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var currentRandom = Math.random;
|
||||
|
||||
// Pseudo-random generator
|
||||
function Marsaglia(i1, i2) {
|
||||
// from http://www.math.uni-bielefeld.de/~sillke/ALGORITHMS/random/marsaglia-c
|
||||
var z=i1 || 362436069, w= i2 || 521288629;
|
||||
var nextInt = function() {
|
||||
z=(36969*(z&65535)+(z>>>16)) & 0xFFFFFFFF;
|
||||
w=(18000*(w&65535)+(w>>>16)) & 0xFFFFFFFF;
|
||||
return (((z&0xFFFF)<<16) | (w&0xFFFF)) & 0xFFFFFFFF;
|
||||
};
|
||||
|
||||
this.nextDouble = function() {
|
||||
var i = nextInt() / 4294967296;
|
||||
return i < 0 ? 1 + i : i;
|
||||
};
|
||||
this.nextInt = nextInt;
|
||||
}
|
||||
Marsaglia.createRandomized = function() {
|
||||
var now = new Date();
|
||||
return new Marsaglia((now / 60000) & 0xFFFFFFFF, now & 0xFFFFFFFF);
|
||||
};
|
||||
|
||||
// Noise functions and helpers
|
||||
function PerlinNoise(seed) {
|
||||
var rnd = seed !== undefined ? new Marsaglia(seed) : Marsaglia.createRandomized();
|
||||
var i, j;
|
||||
// http://www.noisemachine.com/talk1/17b.html
|
||||
// http://mrl.nyu.edu/~perlin/noise/
|
||||
// generate permutation
|
||||
var p = new Array(512);
|
||||
for(i=0;i<256;++i) { p[i] = i; }
|
||||
for(i=0;i<256;++i) { var t = p[j = rnd.nextInt() & 0xFF]; p[j] = p[i]; p[i] = t; }
|
||||
// copy to avoid taking mod in p[0];
|
||||
for(i=0;i<256;++i) { p[i + 256] = p[i]; }
|
||||
|
||||
function grad3d(i,x,y,z) {
|
||||
var h = i & 15; // convert into 12 gradient directions
|
||||
var u = h<8 ? x : y,
|
||||
v = h<4 ? y : h===12||h===14 ? x : z;
|
||||
return ((h&1) === 0 ? u : -u) + ((h&2) === 0 ? v : -v);
|
||||
}
|
||||
|
||||
function grad2d(i,x,y) {
|
||||
var v = (i & 1) === 0 ? x : y;
|
||||
return (i&2) === 0 ? -v : v;
|
||||
}
|
||||
|
||||
function grad1d(i,x) {
|
||||
return (i&1) === 0 ? -x : x;
|
||||
}
|
||||
|
||||
function lerp(t,a,b) { return a + t * (b - a); }
|
||||
|
||||
this.noise3d = function(x, y, z) {
|
||||
var X = Math.floor(x)&255, Y = Math.floor(y)&255, Z = Math.floor(z)&255;
|
||||
x -= Math.floor(x); y -= Math.floor(y); z -= Math.floor(z);
|
||||
var fx = (3-2*x)*x*x, fy = (3-2*y)*y*y, fz = (3-2*z)*z*z;
|
||||
var p0 = p[X]+Y, p00 = p[p0] + Z, p01 = p[p0 + 1] + Z, p1 = p[X + 1] + Y, p10 = p[p1] + Z, p11 = p[p1 + 1] + Z;
|
||||
return lerp(fz,
|
||||
lerp(fy, lerp(fx, grad3d(p[p00], x, y, z), grad3d(p[p10], x-1, y, z)),
|
||||
lerp(fx, grad3d(p[p01], x, y-1, z), grad3d(p[p11], x-1, y-1,z))),
|
||||
lerp(fy, lerp(fx, grad3d(p[p00 + 1], x, y, z-1), grad3d(p[p10 + 1], x-1, y, z-1)),
|
||||
lerp(fx, grad3d(p[p01 + 1], x, y-1, z-1), grad3d(p[p11 + 1], x-1, y-1,z-1))));
|
||||
};
|
||||
|
||||
this.noise2d = function(x, y) {
|
||||
var X = Math.floor(x)&255, Y = Math.floor(y)&255;
|
||||
x -= Math.floor(x); y -= Math.floor(y);
|
||||
var fx = (3-2*x)*x*x, fy = (3-2*y)*y*y;
|
||||
var p0 = p[X]+Y, p1 = p[X + 1] + Y;
|
||||
return lerp(fy,
|
||||
lerp(fx, grad2d(p[p0], x, y), grad2d(p[p1], x-1, y)),
|
||||
lerp(fx, grad2d(p[p0 + 1], x, y-1), grad2d(p[p1 + 1], x-1, y-1)));
|
||||
};
|
||||
|
||||
this.noise1d = function(x) {
|
||||
var X = Math.floor(x)&255;
|
||||
x -= Math.floor(x);
|
||||
var fx = (3-2*x)*x*x;
|
||||
return lerp(fx, grad1d(p[X], x), grad1d(p[X+1], x-1));
|
||||
};
|
||||
}
|
||||
|
||||
// these are lifted from Processing.js
|
||||
// processing defaults
|
||||
var noiseProfile = { generator: undefined, octaves: 4, fallout: 0.5, seed: undefined};
|
||||
|
||||
function noise(x, y, z) {
|
||||
if(noiseProfile.generator === undefined) {
|
||||
// caching
|
||||
noiseProfile.generator = new PerlinNoise(noiseProfile.seed);
|
||||
}
|
||||
var generator = noiseProfile.generator;
|
||||
var effect = 1, k = 1, sum = 0;
|
||||
for(var i=0; i<noiseProfile.octaves; ++i) {
|
||||
effect *= noiseProfile.fallout;
|
||||
switch (arguments.length) {
|
||||
case 1:
|
||||
sum += effect * (1 + generator.noise1d(k*x))/2; break;
|
||||
case 2:
|
||||
sum += effect * (1 + generator.noise2d(k*x, k*y))/2; break;
|
||||
case 3:
|
||||
sum += effect * (1 + generator.noise3d(k*x, k*y, k*z))/2; break;
|
||||
}
|
||||
k *= 2;
|
||||
}
|
||||
return sum;
|
||||
};
|
1538
docs/prettify.js
1538
docs/prettify.js
File diff suppressed because it is too large
Load Diff
13
example.html
Normal file
13
example.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript" src="build/dat.gui.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
var obj = { x: 5 };
|
||||
var gui = new dat.GUI();
|
||||
gui.add(obj, 'x', 0, 10);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
402
index.html
402
index.html
@ -1,402 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<title>dat.gui</title>
|
||||
|
||||
<link rel='icon' type='image/png' href='docs/assets/favicon.png'/>
|
||||
|
||||
<!--Minified build-->
|
||||
<!--<script type='text/javascript' src='build/DAT.GUI.min.js'></script>-->
|
||||
|
||||
<!--Build--->
|
||||
<!--<script type='text/javascript' src='build/DAT.GUI.js'></script>-->
|
||||
|
||||
<!--All source-->
|
||||
<link href='src/DAT/GUI/GUI.css' media='screen' rel='stylesheet' type='text/css'/>
|
||||
<script type='text/javascript' src='src/DAT/GUI/GUI.js'></script>
|
||||
<script type='text/javascript' src='src/DAT/GUI/ControllerNumberSlider.js'></script>
|
||||
<script type='text/javascript' src='src/DAT/GUI/Controller.js'></script>
|
||||
<script type='text/javascript' src='src/DAT/GUI/ControllerBoolean.js'></script>
|
||||
<script type='text/javascript' src='src/DAT/GUI/ControllerString.js'></script>
|
||||
<script type='text/javascript' src='src/DAT/GUI/ControllerFunction.js'></script>
|
||||
<script type='text/javascript' src='src/DAT/GUI/ControllerNumber.js'></script>
|
||||
|
||||
<!--Demo-->
|
||||
<link href='docs/docs.css' media='screen' rel='stylesheet' type='text/css'/>
|
||||
<script type='text/javascript' src='docs/RequestAnimationFrame.js'></script>
|
||||
<script type='text/javascript' src='docs/improvedNoise.js'></script>
|
||||
<script type='text/javascript' src='docs/prettify.js'></script>
|
||||
<script type='text/javascript' src='docs/demo.js'></script>
|
||||
|
||||
<script type='text/javascript'>
|
||||
//<![CDATA[
|
||||
|
||||
window.onload = function() {
|
||||
|
||||
prettyPrint();
|
||||
|
||||
var fizzyText = new FizzyText('dat.gui');
|
||||
var gui = new DAT.GUI();
|
||||
|
||||
// Text field
|
||||
gui.add(fizzyText, 'message');
|
||||
|
||||
// Sliders with min + max
|
||||
gui.add(fizzyText, 'maxSize').min(0.5).max(7);
|
||||
gui.add(fizzyText, 'growthSpeed').min(0.01).max(1).step(0.05);
|
||||
gui.add(fizzyText, 'speed', 0.1, 2, 0.05); // shorthand for min/max/step
|
||||
|
||||
// Sliders with min, max and increment.
|
||||
gui.add(fizzyText, 'noiseStrength', 10, 100, 5);
|
||||
|
||||
// Boolean checkbox
|
||||
gui.add(fizzyText, 'displayOutline');
|
||||
|
||||
// Fires a function called 'explode'
|
||||
gui.add(fizzyText, 'explode').name('Explode!'); // Specify a custom name.
|
||||
|
||||
// Javascript for documentation
|
||||
getCollapsables();
|
||||
handleListening();
|
||||
};
|
||||
|
||||
function toggle(e) {
|
||||
|
||||
var collapsable = this.childNodes[3],
|
||||
wrapper = collapsable.childNodes[1];
|
||||
|
||||
if (this.className === 'collapsed') {
|
||||
this.className = 'expanded';
|
||||
collapsable.style.height = wrapper.clientHeight + 'px';
|
||||
} else {
|
||||
this.className = 'collapsed';
|
||||
collapsable.style.height = '0px';
|
||||
}
|
||||
}
|
||||
|
||||
function getCollapsables() {
|
||||
|
||||
if (document.getElementsByClassName == undefined) {
|
||||
document.getElementsByClassName = function(className) {
|
||||
var hasClassName = new RegExp('(?:^|\\s)' + className + '(?:$|\\s)');
|
||||
var allElements = document.getElementsByTagName('*');
|
||||
var results = [];
|
||||
|
||||
var element;
|
||||
for (var i = 0; (element = allElements[i]) != null; i++) {
|
||||
var elementClass = element.className;
|
||||
if (elementClass && elementClass.indexOf(className) != -1 &&
|
||||
hasClassName.test(elementClass))
|
||||
results.push(element);
|
||||
}
|
||||
|
||||
return results;
|
||||
};
|
||||
}
|
||||
|
||||
collapsed = document.getElementsByClassName('collapsed');
|
||||
expanded = document.getElementsByClassName('expanded');
|
||||
}
|
||||
|
||||
function handleListening() {
|
||||
|
||||
for (var i = 0; i < collapsed.length; i++) {
|
||||
collapsed[i].addEventListener('click', toggle, false);
|
||||
}
|
||||
|
||||
for (var j = 0; j < expanded.length; j++) {
|
||||
expanded[i].addEventListener('click', toggle, false);
|
||||
}
|
||||
}
|
||||
|
||||
//]]>
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id='container'>
|
||||
|
||||
<!-- GUIDAT logo -->
|
||||
<div id='helvetica-demo'></div>
|
||||
|
||||
<!-- It gives you this! -->
|
||||
<div id='notifier'></div>
|
||||
|
||||
<h1><a href='http://twitter.com/guidat'><img src='docs/assets/profile.png'
|
||||
border='0' alt='dat.gui flag'/></a>
|
||||
</h1>
|
||||
|
||||
<p><strong>dat.gui</strong> is a lightweight controller library for JavaScript.
|
||||
It allows you to easily manipulate variables and fire functions on the fly.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href='https://github.com/dataarts/dat.gui/raw/build/DAT.GUI.min.js'><strong>Download the minified source</strong></a>
|
||||
<small id='buildsizemin'>[19.7kb]
|
||||
</small>
|
||||
</li>
|
||||
<li>
|
||||
<a href='https://github.com/dataarts/dat.gui/raw/build/DAT.GUI.js'><strong>Download the uncompressed source</strong></a>
|
||||
<small id='buildsize'>[34.1kb]
|
||||
</small>
|
||||
</li>
|
||||
|
||||
<li><a href='http://github.com/dataarts/dat.gui'>Contribute on GitHub!</a></li>
|
||||
</ul>
|
||||
|
||||
<h2>Basic Usage</h2>
|
||||
<pre id='demo-pre' class='prettyprint'>
|
||||
<script type='text/javascript' src='DAT.GUI.min.js'></script>
|
||||
<script type='text/javascript'>
|
||||
|
||||
window.onload = function() {
|
||||
|
||||
var fizzyText = new <a href='docs/demo.js'>FizzyText</a>('dat.gui');
|
||||
|
||||
var gui = new DAT.GUI();
|
||||
|
||||
// Text field
|
||||
gui.add(fizzyText, 'message');
|
||||
|
||||
// Sliders with min + max
|
||||
gui.add(fizzyText, 'maxSize').min(0.5).max(7);
|
||||
gui.add(fizzyText, 'growthSpeed').min(0.01).max(1).step(0.05);
|
||||
gui.add(fizzyText, 'speed', 0.1, 2, 0.05); // shorthand for min/max/step
|
||||
|
||||
gui.add(fizzyText, 'noiseStrength', 10, 100, 5);
|
||||
|
||||
// Boolean checkbox
|
||||
gui.add(fizzyText, 'displayOutline');
|
||||
|
||||
// Fires a function called 'explode'
|
||||
gui.add(fizzyText, 'explode').name('Explode!'); // Specify a custom name.
|
||||
|
||||
};
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
||||
<ul id='desc'>
|
||||
<li><code>DAT.GUI</code> will infer the type of the property you're trying
|
||||
to add<br/>
|
||||
(based on its initial value) and create the corresponding control.
|
||||
</li>
|
||||
|
||||
<li>The properties must be public, i.e. defined by <code><strong>this</strong>.prop
|
||||
= value</code>.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!--
|
||||
<h2 class='collapsed'>Fire a function when someone uses a control</h2>
|
||||
<pre class='prettyprint'>gui.add(obj, 'propName').onChange(function(n) {
|
||||
alert('You changed me to ' + n);
|
||||
});</pre>-->
|
||||
|
||||
<!--<div class='collapsed'>-->
|
||||
<!---->
|
||||
<!--<h2 class='section'>Saving your parameters</h2>-->
|
||||
|
||||
<!--<div class='collapsable'>-->
|
||||
<!--<div>-->
|
||||
<!--<p>The simplest way to save your parameters is via-->
|
||||
<!--<code>DAT.GUI.saveURL()</code>. This method directs your browser to a-->
|
||||
<!--URL containing the current GUI settings.</p>-->
|
||||
<!--<pre class='prettyprint last'>-->
|
||||
<!--// Make a button for the url function-->
|
||||
<!--gui.add(DAT.GUI, 'saveURL');</pre>-->
|
||||
<!--</div>-->
|
||||
<!--</div>-->
|
||||
<!--</div>-->
|
||||
<!--<div class='collapsed'>-->
|
||||
<!--<h2 class='section'>Advanced saving</h2>-->
|
||||
|
||||
<!--<div class='collapsable'>-->
|
||||
<!--<div>-->
|
||||
<!--<p>Let's say you'd like to share your settings with someone. Instead of-->
|
||||
<!--sending a long link with lots of parameters stored in it, you can make-->
|
||||
<!--your saved settings the defaults.</p>-->
|
||||
|
||||
<!--<p>First, add the method <code>DAT.GUI.showSaveString()</code> to a gui-->
|
||||
<!--object:</p>-->
|
||||
<!--<pre class='prettyprint'>var gui = new DAT.GUI();-->
|
||||
|
||||
<!--// Add some stuff (and pretend I change their values);-->
|
||||
<!--gui.add(someObject, 'someProperty');-->
|
||||
<!--gui.add(someObject, 'someOtherProperty');-->
|
||||
|
||||
<!--// Make a save button.-->
|
||||
<!--gui.add(DAT.GUI, 'showSaveString');</pre>-->
|
||||
|
||||
<!--<p>Clicking the 'showSaveString' button bring up an alert with a string.-->
|
||||
<!--Copy and paste that string into the method <code>DAT.GUI.load()</code>-->
|
||||
<!--before you instantiate any gui objects.</p>-->
|
||||
<!--<pre class='prettyprint'>-->
|
||||
<!--// Replace COPIED STRING with the value you got from showSaveString()-->
|
||||
<!--DAT.GUI.load('COPIED STRING');-->
|
||||
|
||||
<!--var gui = new DAT.GUI();-->
|
||||
|
||||
<!--// Now these properties will be set to the values you just saved.-->
|
||||
<!--gui.add(someObject, 'someProperty');-->
|
||||
<!--gui.add(someObject, 'someOtherProperty');</pre>-->
|
||||
|
||||
<!--<p class='last'><strong>Save strings won't work if you change the order in-->
|
||||
<!--which you've added properties to your gui objects, or the order of the-->
|
||||
<!--gui objects themselves.</strong>. If you want to add more parameters to-->
|
||||
<!--your gui and use an old save string, make sure they're added after the-->
|
||||
<!--properties whose values you've saved.</p>-->
|
||||
<!--</div>-->
|
||||
<!--</div>-->
|
||||
<!--</div>-->
|
||||
|
||||
|
||||
<div class='collapsed'>
|
||||
<h2 class='section'>Choosing from a list of values</h2>
|
||||
|
||||
<div class='collapsable'>
|
||||
<div>
|
||||
<pre class='prettyprint first last'>gui.add(obj, 'propertyName').options(1, 2, 3, 5, 8);
|
||||
|
||||
// Alternatively, you can specify custom labels using object syntax
|
||||
gui.add(obj, 'propertyName').options({'Small': 1, 'Medium': 2, 'Large': 3});
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='collapsed'>
|
||||
<h2 class='section'>Listen for variable changes inside the GUI</h2>
|
||||
|
||||
<div class='collapsable'>
|
||||
<div>
|
||||
<p>To fire a function whenever a user changes a variable via the GUI, use
|
||||
the following syntax:</p>
|
||||
<pre class='prettyprint'>gui.add(obj, 'propertyName').onChange(function(newValue) {
|
||||
alert('You changed me to ' + newValue);
|
||||
});</pre>
|
||||
<p>This can be slightly annoying for types like number or string. You may
|
||||
not want to fire a function while the user is sliding, or while they're
|
||||
typing. To fire a function when the user has <em>finished</em> making
|
||||
changes, use the following:</p>
|
||||
<pre class='prettyprint'>gui.add(obj, 'propertyName').onFinishChange(function(newValue) {
|
||||
alert('You just finished changing me to ' + newValue);
|
||||
});</pre>
|
||||
<p>Finally, if you'd like to do a little something extra when a function
|
||||
is called, use the following:</p>
|
||||
<pre class='prettyprint last'>gui.add(obj, 'functionName').onFire(function() {
|
||||
alert('You called a function with dat.gui');
|
||||
});</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='collapsed'>
|
||||
<h2 class='section'>Listen for variable changes outside of the GUI</h2>
|
||||
|
||||
<div class='collapsable'>
|
||||
<div>
|
||||
<p>Let's say you have a variable that changes by itself from time to time.
|
||||
If you'd like the GUI to reflect those changes, use the <code>listen()</code>
|
||||
method.</p>
|
||||
<pre
|
||||
class='prettyprint last'>gui.add(obj, 'changingProperty').listen();</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='collapsed'>
|
||||
<h2 class='section'>Advanced listening</h2>
|
||||
|
||||
<div class='collapsable'>
|
||||
<div>
|
||||
<p>By default, <code>DAT.GUI</code> will create an internal interval
|
||||
that checks for changes in the values you've marked with
|
||||
<code>listen()</code>. If you'd like to check for these changes in an
|
||||
interval of your own definition, use the following:</p>
|
||||
<pre class='prettyprint'>
|
||||
gui.autoListen = false; // disables internal interval
|
||||
gui.add(obj, 'changingProperty').listen();
|
||||
|
||||
// Make your own loop
|
||||
setInterval(function() {
|
||||
gui.listen(); // updates values you've marked with listen()
|
||||
}, 1000 / 60);</pre>
|
||||
|
||||
<p>Alternatively, you can forego calling <code>listen()</code> on
|
||||
individual controllers, and instead choose to monitor changes in
|
||||
<em>all</em> values controlled by your gui.</p>
|
||||
<pre class='prettyprint last'>
|
||||
gui.autoListen = false; // disables internal interval
|
||||
gui.add(obj, 'add');
|
||||
gui.add(obj, 'lotsa');
|
||||
gui.add(obj, 'properties');
|
||||
|
||||
// Make your own loop
|
||||
setInterval(function() {
|
||||
gui.listenAll(); // updates ALL values managed by this gui
|
||||
}, 1000 / 60);</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='collapsed'>
|
||||
<h2 class='section'>Multiple panels and custom placement</h2>
|
||||
|
||||
<div class='collapsable'>
|
||||
<div>
|
||||
<p>You can instantiate multiple <code>DAT.GUI</code> objects and name them
|
||||
however you'd like.</p>
|
||||
<pre class='prettyprint'>var gui1 = new DAT.GUI();
|
||||
var gui2 = new DAT.GUI();
|
||||
|
||||
// The name function overwrites the 'Show Controls' text.
|
||||
gui1.name('Utilities');
|
||||
gui2.name('Camera Placement');</pre>
|
||||
|
||||
<p>By default, <code>DAT.GUI</code> panels will be automatically added
|
||||
to the HTML document and fixed to the top of the screen from right to
|
||||
left. You can disable this behavior and append the gui DOM element to
|
||||
a container of your choosing.</p>
|
||||
<pre class='prettyprint last'>
|
||||
// Notice this belongs to the DAT.GUI class (uppercase)
|
||||
// and not an instance thereof.
|
||||
DAT.GUI.autoPlace = false;
|
||||
|
||||
var gui = new DAT.GUI();
|
||||
|
||||
// Do some custom styles ...
|
||||
gui.domElement.style.position = 'absolute';
|
||||
gui.domElement.style.top = '20px';
|
||||
gui.domElement.style.left = '20px';
|
||||
|
||||
document.getElementById('my-gui-container').appendChild( gui.domElement );</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='collapsed'>
|
||||
<h2 class='section'>Pro tips.</h2>
|
||||
|
||||
<div class='collapsable'>
|
||||
<div>
|
||||
<ol id='secrets'>
|
||||
<li><code>DAT.GUI</code> panels are resizeable. Drag the open/close
|
||||
button.
|
||||
</li>
|
||||
|
||||
<li>Press 'H' to show/hide GUI's.</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='trans'> </div>
|
||||
|
||||
<footer class='trans'>Initiated by <a href='http://georgemichaelbrower.com/'>George
|
||||
Michael Brower</a> and <a href='http://jonobr1.com/'>Jono Brandel</a> of the
|
||||
Data Arts Team, Google Creative Lab.
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
89
readme.wiki
Normal file
89
readme.wiki
Normal file
@ -0,0 +1,89 @@
|
||||
=dat.GUI=
|
||||
A lightweight graphical user interface for changing variables in JavaScript.
|
||||
|
||||
Get started with dat.GUI by reading the tutorial at [http://workshop.chromeexperiments.com/examples/gui].
|
||||
|
||||
----
|
||||
|
||||
==Packaged Builds==
|
||||
The easiest way to use dat.GUI in your code is by using the built source at {{{build/dat.gui.min.js}}}. These built JavaScript files bundle all the necessary dependencies to run dat.GUI.
|
||||
|
||||
In your {{{head}}} tag, include the following code:
|
||||
{{{
|
||||
<script type="text/javascript" src="dat.gui.min.js"></script>
|
||||
}}}
|
||||
|
||||
----
|
||||
|
||||
==Using dat.GUI with require.js==
|
||||
Internally, dat.GUI uses [http://requirejs.org/ require.js] to handle dependency management. If you're making changes to the source and want to see the effects of your changes without building, use require js.
|
||||
|
||||
In your {{{head}}} tag, include the following code:
|
||||
{{{
|
||||
<script data-main="path/to/main" src="path/to/requirejs/require.js"></script>
|
||||
}}}
|
||||
|
||||
Then, in {{{path/to/main.js}}}:
|
||||
{{{
|
||||
require([
|
||||
'path/to/gui/module/GUI'
|
||||
], function(GUI) {
|
||||
|
||||
// No namespace necessary
|
||||
var gui = new GUI();
|
||||
|
||||
});
|
||||
}}}
|
||||
|
||||
----
|
||||
|
||||
==Directory Contents==
|
||||
* build: Concatenated source code.
|
||||
* src: Modular code in [http://requirejs.org/ require.js] format. Also includes css, [http://sass-lang.com/ scss], and html, some of which is included during build.
|
||||
* tests: [https://github.com/jquery/qunit QUnit] test suite.
|
||||
* utils: [http://nodejs.org/ node.js] utility scripts for compiling source.
|
||||
|
||||
----
|
||||
|
||||
==Building your own dat.GUI==
|
||||
|
||||
In the terminal, enter the following:
|
||||
|
||||
{{{
|
||||
$ cd utils
|
||||
$ node build_gui.js
|
||||
}}}
|
||||
|
||||
This will create a namespaced, unminified build of dat.GUI at {{{build/dat.gui.js}}}
|
||||
|
||||
_To export minified source using Closure Compiler, open {{{utils/build_gui.js}}} and set the {{{minify}}} parameter to {{{true}}}._
|
||||
|
||||
----
|
||||
|
||||
==Change log==
|
||||
|
||||
===0.5===
|
||||
* Moved to requirejs for dependency management.
|
||||
* Changed global namespace from *DAT* to *dat* (lowercase).
|
||||
* Added support for color controllers. See [http://workshop.chromeexperiments.com/examples/gui/#4--Color-Controllers Color Controllers].
|
||||
* Added support for folders. See [http://workshop.chromeexperiments.com/examples/gui/#3--Folders Folders].
|
||||
* Added support for saving named presets. See [http://workshop.chromeexperiments.com/examples/gui/examples/gui/#6--Presets Presets].
|
||||
* Removed `height` parameter from GUI constructor. Scrollbar automatically induced when window is too short.
|
||||
* `dat.GUI.autoPlace` parameter removed. Use `new dat.GUI( { autoPlace: false } )`. See [http://workshop.chromeexperiments.com/examples/gui/#9--Custom-Placement Custom Placement].
|
||||
* `gui.autoListen` and `gui.listenAll()` removed. See [http://workshop.chromeexperiments.com/examples/gui/#11--Updating-the-Display-Manually Updating The Display Manually].
|
||||
* `dat.GUI.load` removed. See [http://workshop.chromeexperiments.com/examples/gui/#5--Saving-Values Saving Values].
|
||||
* Made Controller code completely agnostic of GUI. Controllers can easily be created independent of a GUI panel.
|
||||
|
||||
|
||||
===0.4===
|
||||
|
||||
* Migrated from GitHub to Google Code.
|
||||
|
||||
----
|
||||
|
||||
==Thanks==
|
||||
The following libraries and open-source projects were used in the development of dat.GUI.
|
||||
* [http://requirejs.org/ require.js]
|
||||
* [http://sass-lang.com/ Sass]
|
||||
* [http://nodejs.org/ node.js]
|
||||
* [https://github.com/jquery/qunit QUnit] / [http://jquery.com jquery]
|
@ -1,114 +0,0 @@
|
||||
DAT.GUI.Controller = function() {
|
||||
|
||||
this.parent = arguments[0];
|
||||
this.object = arguments[1];
|
||||
this.propertyName = arguments[2];
|
||||
|
||||
//if (arguments.length > 0) this.initialValue = this.propertyName[this.object];
|
||||
if (arguments.length > 0) this.initialValue = this.object[this.propertyName];
|
||||
|
||||
this.domElement = document.createElement('div');
|
||||
this.domElement.setAttribute('class', 'guidat-controller ' + this.type);
|
||||
|
||||
this.propertyNameElement = document.createElement('span');
|
||||
this.propertyNameElement.setAttribute('class', 'guidat-propertyname');
|
||||
this.name(this.propertyName);
|
||||
this.domElement.appendChild(this.propertyNameElement);
|
||||
|
||||
DAT.GUI.makeUnselectable(this.domElement);
|
||||
|
||||
};
|
||||
|
||||
DAT.GUI.Controller.prototype.changeFunction = null;
|
||||
DAT.GUI.Controller.prototype.finishChangeFunction = null;
|
||||
|
||||
DAT.GUI.Controller.prototype.name = function(n) {
|
||||
this.propertyNameElement.innerHTML = n;
|
||||
return this;
|
||||
};
|
||||
|
||||
DAT.GUI.Controller.prototype.reset = function() {
|
||||
this.setValue(this.initialValue);
|
||||
return this;
|
||||
};
|
||||
|
||||
DAT.GUI.Controller.prototype.listen = function() {
|
||||
this.parent.listenTo(this);
|
||||
return this;
|
||||
};
|
||||
|
||||
DAT.GUI.Controller.prototype.unlisten = function() {
|
||||
this.parent.unlistenTo(this); // <--- hasn't been tested yet
|
||||
return this;
|
||||
};
|
||||
|
||||
DAT.GUI.Controller.prototype.setValue = function(n) {
|
||||
if(this.object[this.propertyName] != undefined){
|
||||
this.object[this.propertyName] = n;
|
||||
}else{
|
||||
var o = new Object();
|
||||
o[this.propertyName] = n;
|
||||
this.object.set(o);
|
||||
}
|
||||
if (this.changeFunction != null) {
|
||||
this.changeFunction.call(this, n);
|
||||
}
|
||||
this.updateDisplay();
|
||||
return this;
|
||||
};
|
||||
|
||||
DAT.GUI.Controller.prototype.getValue = function() {
|
||||
var val = this.object[this.propertyName];
|
||||
if(val == undefined) val = this.object.get(this.propertyName);
|
||||
return val;
|
||||
};
|
||||
|
||||
DAT.GUI.Controller.prototype.updateDisplay = function() {
|
||||
|
||||
};
|
||||
|
||||
DAT.GUI.Controller.prototype.onChange = function(fnc) {
|
||||
this.changeFunction = fnc;
|
||||
return this;
|
||||
};
|
||||
|
||||
DAT.GUI.Controller.prototype.onFinishChange = function(fnc) {
|
||||
this.finishChangeFunction = fnc;
|
||||
return this;
|
||||
};
|
||||
|
||||
DAT.GUI.Controller.prototype.options = function() {
|
||||
var _this = this;
|
||||
var select = document.createElement('select');
|
||||
if (arguments.length == 1) {
|
||||
var arr = arguments[0];
|
||||
for (var i in arr) {
|
||||
var opt = document.createElement('option');
|
||||
opt.innerHTML = i;
|
||||
opt.setAttribute('value', arr[i]);
|
||||
if (arguments[i] == this.getValue()) {
|
||||
opt.selected = true;
|
||||
}
|
||||
select.appendChild(opt);
|
||||
}
|
||||
} else {
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
var opt = document.createElement('option');
|
||||
opt.innerHTML = arguments[i];
|
||||
opt.setAttribute('value', arguments[i]);
|
||||
if (arguments[i] == this.getValue()) {
|
||||
opt.selected = true;
|
||||
}
|
||||
select.appendChild(opt);
|
||||
}
|
||||
}
|
||||
|
||||
select.addEventListener('change', function() {
|
||||
_this.setValue(this.value);
|
||||
if (_this.finishChangeFunction != null) {
|
||||
_this.finishChangeFunction.call(this, _this.getValue());
|
||||
}
|
||||
}, false);
|
||||
_this.domElement.appendChild(select);
|
||||
return this;
|
||||
};
|
@ -1,43 +0,0 @@
|
||||
DAT.GUI.ControllerBoolean = function() {
|
||||
|
||||
this.type = "boolean";
|
||||
DAT.GUI.Controller.apply(this, arguments);
|
||||
|
||||
var _this = this;
|
||||
var input = document.createElement('input');
|
||||
input.setAttribute('type', 'checkbox');
|
||||
|
||||
input.checked = this.getValue();
|
||||
this.setValue(this.getValue());
|
||||
|
||||
this.domElement.addEventListener('click', function(e) {
|
||||
input.checked = !input.checked;
|
||||
e.preventDefault();
|
||||
_this.setValue(input.checked);
|
||||
}, false);
|
||||
|
||||
input.addEventListener('mouseup', function(e) {
|
||||
input.checked = !input.checked; // counteracts default.
|
||||
}, false);
|
||||
|
||||
this.domElement.style.cursor = "pointer";
|
||||
this.propertyNameElement.style.cursor = "pointer";
|
||||
this.domElement.appendChild(input);
|
||||
|
||||
this.updateDisplay = function() {
|
||||
input.checked = _this.getValue();
|
||||
};
|
||||
|
||||
|
||||
this.setValue = function(val) {
|
||||
if (typeof val != "boolean") {
|
||||
try {
|
||||
val = eval(val);
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
return DAT.GUI.Controller.prototype.setValue.call(this, val);
|
||||
};
|
||||
|
||||
};
|
||||
DAT.GUI.extendController(DAT.GUI.ControllerBoolean);
|
@ -1,30 +0,0 @@
|
||||
DAT.GUI.ControllerFunction = function() {
|
||||
|
||||
this.type = "function";
|
||||
|
||||
var _this = this;
|
||||
|
||||
DAT.GUI.Controller.apply(this, arguments);
|
||||
|
||||
this.domElement.addEventListener('click', function() {
|
||||
_this.fire();
|
||||
}, false);
|
||||
|
||||
this.domElement.style.cursor = "pointer";
|
||||
this.propertyNameElement.style.cursor = "pointer";
|
||||
|
||||
var fireFunction = null;
|
||||
this.onFire = function(fnc) {
|
||||
fireFunction = fnc;
|
||||
return this;
|
||||
}
|
||||
|
||||
this.fire = function() {
|
||||
if (fireFunction != null) {
|
||||
fireFunction.call(this);
|
||||
}
|
||||
_this.object[_this.propertyName].call(_this.object);
|
||||
};
|
||||
|
||||
};
|
||||
DAT.GUI.extendController(DAT.GUI.ControllerFunction);
|
@ -1,243 +0,0 @@
|
||||
DAT.GUI.ControllerNumber = function() {
|
||||
|
||||
this.type = "number";
|
||||
|
||||
DAT.GUI.Controller.apply(this, arguments);
|
||||
|
||||
var _this = this;
|
||||
|
||||
// If we simply click and release a number field, we want to highlight it.
|
||||
// This variable keeps track of whether or not we've dragged
|
||||
var draggedNumberField = false;
|
||||
|
||||
var clickedNumberField = false;
|
||||
var draggingHorizontal = false;
|
||||
var draggingVertical = false;
|
||||
|
||||
var y = 0, py = 0;
|
||||
|
||||
var min = arguments[3];
|
||||
var max = arguments[4];
|
||||
var step = arguments[5];
|
||||
|
||||
var defaultStep = function() {
|
||||
step = (max - min) * 0.01;
|
||||
};
|
||||
|
||||
this.min = function() {
|
||||
var needsSlider = false;
|
||||
if (min == undefined && max != undefined) {
|
||||
needsSlider = true;
|
||||
}
|
||||
if (arguments.length == 0) {
|
||||
return min;
|
||||
} else {
|
||||
min = arguments[0];
|
||||
}
|
||||
if (needsSlider) {
|
||||
addSlider();
|
||||
if (step == undefined) {
|
||||
defaultStep();
|
||||
}
|
||||
}
|
||||
return _this;
|
||||
};
|
||||
|
||||
this.max = function() {
|
||||
var needsSlider = false;
|
||||
if (min != undefined && max == undefined) {
|
||||
needsSlider = true;
|
||||
}
|
||||
if (arguments.length == 0) {
|
||||
return max;
|
||||
} else {
|
||||
max = arguments[0];
|
||||
}
|
||||
if (needsSlider) {
|
||||
addSlider();
|
||||
if (step == undefined) {
|
||||
defaultStep();
|
||||
}
|
||||
}
|
||||
return _this;
|
||||
};
|
||||
|
||||
this.step = function() {
|
||||
if (arguments.length == 0) {
|
||||
return step;
|
||||
} else {
|
||||
step = arguments[0];
|
||||
}
|
||||
return _this;
|
||||
};
|
||||
|
||||
this.getMin = function() {
|
||||
return min;
|
||||
};
|
||||
|
||||
this.getMax = function() {
|
||||
return max;
|
||||
};
|
||||
|
||||
this.getStep = function() {
|
||||
if (step == undefined) {
|
||||
if (max != undefined && min != undefined) {
|
||||
return (max-min)/100;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
return step;
|
||||
}
|
||||
}
|
||||
|
||||
var numberField = document.createElement('input');
|
||||
numberField.setAttribute('id', this.propertyName);
|
||||
numberField.setAttribute('type', 'text');
|
||||
numberField.setAttribute('value', this.getValue());
|
||||
|
||||
if (step) numberField.setAttribute('step', step);
|
||||
|
||||
this.domElement.appendChild(numberField);
|
||||
|
||||
var slider;
|
||||
|
||||
var addSlider = function() {
|
||||
slider = new DAT.GUI.ControllerNumberSlider(_this, min, max, step, _this.getValue());
|
||||
_this.domElement.appendChild(slider.domElement);
|
||||
};
|
||||
|
||||
if (min != undefined && max != undefined) {
|
||||
addSlider();
|
||||
}
|
||||
|
||||
numberField.addEventListener('blur', function() {
|
||||
var val = parseFloat(this.value);
|
||||
if (slider) {
|
||||
DAT.GUI.removeClass(_this.domElement, 'active');
|
||||
}
|
||||
if (!isNaN(val)) {
|
||||
_this.setValue(val);
|
||||
}
|
||||
}, false);
|
||||
|
||||
|
||||
numberField.addEventListener('mousewheel', function(e) {
|
||||
e.preventDefault();
|
||||
_this.setValue(_this.getValue() + Math.abs(e.wheelDeltaY) / e.wheelDeltaY * _this.getStep());
|
||||
return false;
|
||||
}, false);
|
||||
|
||||
numberField.addEventListener('mousedown', function(e) {
|
||||
py = y = e.pageY;
|
||||
clickedNumberField = true;
|
||||
DAT.GUI.makeSelectable(numberField);
|
||||
document.addEventListener('mousemove', dragNumberField, false);
|
||||
document.addEventListener('mouseup', mouseup, false);
|
||||
}, false);
|
||||
|
||||
// Handle up arrow and down arrow
|
||||
numberField.addEventListener('keydown', function(e) {
|
||||
var newVal;
|
||||
switch (e.keyCode) {
|
||||
case 13: // enter
|
||||
newVal = parseFloat(this.value);
|
||||
_this.setValue(newVal);
|
||||
break;
|
||||
case 38: // up
|
||||
newVal = _this.getValue() + _this.getStep();
|
||||
_this.setValue(newVal);
|
||||
break;
|
||||
case 40: // down
|
||||
newVal = _this.getValue() - _this.getStep();
|
||||
_this.setValue(newVal);
|
||||
break;
|
||||
}
|
||||
}, false);
|
||||
|
||||
var mouseup = function(e) {
|
||||
document.removeEventListener('mousemove', dragNumberField, false);
|
||||
|
||||
DAT.GUI.makeSelectable(numberField);
|
||||
if (clickedNumberField && !draggedNumberField) {
|
||||
//numberField.focus();
|
||||
//numberField.select();
|
||||
}
|
||||
draggedNumberField = false;
|
||||
clickedNumberField = false;
|
||||
if (_this.finishChangeFunction != null) {
|
||||
_this.finishChangeFunction.call(this, _this.getValue());
|
||||
}
|
||||
draggingHorizontal = false;
|
||||
draggingVertical = false;
|
||||
document.removeEventListener('mouseup', mouseup, false);
|
||||
};
|
||||
|
||||
var dragNumberField = function(e) {
|
||||
|
||||
py = y;
|
||||
y = e.pageY;
|
||||
var dy = py - y;
|
||||
|
||||
|
||||
|
||||
if (!draggingHorizontal && !draggingVertical) {
|
||||
if (dy == 0) {
|
||||
draggingHorizontal = true;
|
||||
} else {
|
||||
draggingVertical = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (draggingHorizontal) {
|
||||
return true;
|
||||
}
|
||||
|
||||
DAT.GUI.addClass(_this.domElement, 'active');
|
||||
|
||||
DAT.GUI.makeUnselectable(_this.parent.domElement);
|
||||
DAT.GUI.makeUnselectable(numberField);
|
||||
|
||||
draggedNumberField = true;
|
||||
e.preventDefault();
|
||||
|
||||
var newVal = _this.getValue() + dy * _this.getStep();
|
||||
_this.setValue(newVal);
|
||||
return false;
|
||||
|
||||
};
|
||||
|
||||
this.options = function() {
|
||||
_this.noSlider();
|
||||
_this.domElement.removeChild(numberField);
|
||||
return DAT.GUI.Controller.prototype.options.apply(this, arguments);
|
||||
};
|
||||
|
||||
this.noSlider = function() {
|
||||
if (slider) {
|
||||
_this.domElement.removeChild(slider.domElement);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
this.setValue = function(val) {
|
||||
|
||||
val = parseFloat(val);
|
||||
|
||||
if (min != undefined && val <= min) {
|
||||
val = min;
|
||||
} else if (max != undefined && val >= max) {
|
||||
val = max;
|
||||
}
|
||||
|
||||
return DAT.GUI.Controller.prototype.setValue.call(this, val);
|
||||
|
||||
};
|
||||
|
||||
this.updateDisplay = function() {
|
||||
numberField.value = DAT.GUI.roundToDecimal(_this.getValue(), 4);
|
||||
if (slider) slider.value = _this.getValue();
|
||||
};
|
||||
};
|
||||
|
||||
DAT.GUI.extendController(DAT.GUI.ControllerNumber);
|
@ -1,64 +0,0 @@
|
||||
DAT.GUI.ControllerNumberSlider = function(numberController, min, max, step, initValue) {
|
||||
|
||||
var clicked = false;
|
||||
var _this = this;
|
||||
|
||||
var x, px;
|
||||
|
||||
this.domElement = document.createElement('div');
|
||||
this.domElement.setAttribute('class', 'guidat-slider-bg');
|
||||
|
||||
this.fg = document.createElement('div');
|
||||
this.fg.setAttribute('class', 'guidat-slider-fg');
|
||||
|
||||
this.domElement.appendChild(this.fg);
|
||||
|
||||
var onDrag = function(e) {
|
||||
if (!clicked) return;
|
||||
var pos = findPos(_this.domElement);
|
||||
var val = DAT.GUI.map(e.pageX, pos[0], pos[0] + _this.domElement
|
||||
.offsetWidth, numberController.getMin(), numberController.getMax());
|
||||
val = Math.round(val / numberController.getStep()) * numberController
|
||||
.getStep();
|
||||
numberController.setValue(val);
|
||||
};
|
||||
|
||||
this.domElement.addEventListener('mousedown', function(e) {
|
||||
clicked = true;
|
||||
x = px = e.pageX;
|
||||
DAT.GUI.addClass(numberController.domElement, 'active');
|
||||
onDrag(e);
|
||||
document.addEventListener('mouseup', mouseup, false);
|
||||
}, false);
|
||||
|
||||
var mouseup = function(e) {
|
||||
DAT.GUI.removeClass(numberController.domElement, 'active');
|
||||
clicked = false;
|
||||
if (numberController.finishChangeFunction != null) {
|
||||
numberController.finishChangeFunction.call(this,
|
||||
numberController.getValue());
|
||||
}
|
||||
document.removeEventListener('mouseup', mouseup, false);
|
||||
};
|
||||
|
||||
var findPos = function(obj) {
|
||||
var curleft = 0, curtop = 0;
|
||||
if (obj.offsetParent) {
|
||||
do {
|
||||
curleft += obj.offsetLeft;
|
||||
curtop += obj.offsetTop;
|
||||
} while ((obj = obj.offsetParent));
|
||||
return [curleft,curtop];
|
||||
}
|
||||
};
|
||||
|
||||
this.__defineSetter__('value', function(e) {
|
||||
this.fg.style.width = DAT.GUI.map(e, numberController.getMin(),
|
||||
numberController.getMax(), 0, 100) + "%";
|
||||
});
|
||||
|
||||
document.addEventListener('mousemove', onDrag, false);
|
||||
|
||||
this.value = initValue;
|
||||
|
||||
};
|
@ -1,57 +0,0 @@
|
||||
DAT.GUI.ControllerString = function() {
|
||||
|
||||
this.type = "string";
|
||||
|
||||
var _this = this;
|
||||
DAT.GUI.Controller.apply(this, arguments);
|
||||
|
||||
var input = document.createElement('input');
|
||||
|
||||
var initialValue = this.getValue();
|
||||
|
||||
input.setAttribute('value', initialValue);
|
||||
input.setAttribute('spellcheck', 'false');
|
||||
|
||||
this.domElement.addEventListener('mouseup', function() {
|
||||
input.focus();
|
||||
input.select();
|
||||
}, false);
|
||||
|
||||
// TODO: getting messed up on ctrl a
|
||||
input.addEventListener('keyup', function(e) {
|
||||
if (e.keyCode == 13 && _this.finishChangeFunction != null) {
|
||||
_this.finishChangeFunction.call(this, _this.getValue());
|
||||
input.blur();
|
||||
}
|
||||
_this.setValue(input.value);
|
||||
}, false);
|
||||
|
||||
input.addEventListener('mousedown', function(e) {
|
||||
DAT.GUI.makeSelectable(input);
|
||||
}, false);
|
||||
|
||||
input.addEventListener('blur', function() {
|
||||
DAT.GUI.supressHotKeys = false;
|
||||
if (_this.finishChangeFunction != null) {
|
||||
_this.finishChangeFunction.call(this, _this.getValue());
|
||||
}
|
||||
}, false);
|
||||
|
||||
input.addEventListener('focus', function() {
|
||||
DAT.GUI.supressHotKeys = true;
|
||||
}, false);
|
||||
|
||||
this.updateDisplay = function() {
|
||||
input.value = _this.getValue();
|
||||
};
|
||||
|
||||
this.options = function() {
|
||||
_this.domElement.removeChild(input);
|
||||
return DAT.GUI.Controller.prototype.options.apply(this, arguments);
|
||||
};
|
||||
|
||||
this.domElement.appendChild(input);
|
||||
|
||||
};
|
||||
|
||||
DAT.GUI.extendController(DAT.GUI.ControllerString);
|
@ -1,168 +0,0 @@
|
||||
#guidat {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: auto;
|
||||
z-index: 1001;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.guidat {
|
||||
color: #fff;
|
||||
opacity: 0.97;
|
||||
text-align: left;
|
||||
float: right;
|
||||
margin-right: 20px;
|
||||
margin-bottom: 20px;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.guidat,
|
||||
.guidat input {
|
||||
font: 9.5px Lucida Grande, sans-serif;
|
||||
}
|
||||
|
||||
.guidat-controllers {
|
||||
height: 300px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
a.guidat-toggle:link,
|
||||
a.guidat-toggle:visited,
|
||||
a.guidat-toggle:active {
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
color: #fff;
|
||||
background-color: #222;
|
||||
text-align: center;
|
||||
display: block;
|
||||
padding: 5px;
|
||||
|
||||
}
|
||||
|
||||
a.guidat-toggle:hover {
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.guidat-controller {
|
||||
padding: 3px;
|
||||
height: 25px;
|
||||
clear: left;
|
||||
border-bottom: 1px solid #222;
|
||||
background-color: #111;
|
||||
}
|
||||
|
||||
.guidat-controller,
|
||||
.guidat-controller input,
|
||||
.guidat-slider-bg,
|
||||
.guidat-slider-fg {
|
||||
-moz-transition: background-color 0.15s linear;
|
||||
-webkit-transition: background-color 0.15s linear;
|
||||
transition: background-color 0.15s linear;
|
||||
}
|
||||
|
||||
.guidat-controller.boolean:hover,
|
||||
.guidat-controller.function:hover {
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.guidat-controller input {
|
||||
float: right;
|
||||
outline: none;
|
||||
border: 0;
|
||||
padding: 4px;
|
||||
margin-top: 2px;
|
||||
background-color: #222;
|
||||
}
|
||||
|
||||
.guidat-controller select {
|
||||
margin-top: 4px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.guidat-controller input:hover {
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
.guidat-controller input:focus,
|
||||
.guidat-controller.active input {
|
||||
background-color: #555;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.guidat-controller.number {
|
||||
border-left: 5px solid #00aeff;
|
||||
}
|
||||
|
||||
.guidat-controller.string {
|
||||
border-left: 5px solid #1ed36f;
|
||||
}
|
||||
|
||||
.guidat-controller.string input {
|
||||
border: 0;
|
||||
color: #1ed36f;
|
||||
margin-right: 2px;
|
||||
width: 148px;
|
||||
}
|
||||
|
||||
.guidat-controller.boolean {
|
||||
border-left: 5px solid #54396e;
|
||||
}
|
||||
|
||||
.guidat-controller.function {
|
||||
border-left: 5px solid #e61d5f;
|
||||
}
|
||||
|
||||
.guidat-controller.number input[type=text] {
|
||||
width: 35px;
|
||||
margin-left: 5px;
|
||||
margin-right: 2px;
|
||||
color: #00aeff;
|
||||
}
|
||||
|
||||
.guidat .guidat-controller.boolean input {
|
||||
margin-top: 6px;
|
||||
margin-right: 2px;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.guidat-controller:last-child {
|
||||
border-bottom: none;
|
||||
-webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.5);
|
||||
-moz-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.5);
|
||||
box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.guidat-propertyname {
|
||||
padding: 5px;
|
||||
padding-top: 7px;
|
||||
cursor: default;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.guidat-controller .guidat-slider-bg:hover,
|
||||
.guidat-controller.active .guidat-slider-bg {
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
.guidat-controller .guidat-slider-bg .guidat-slider-fg:hover,
|
||||
.guidat-controller.active .guidat-slider-bg .guidat-slider-fg {
|
||||
background-color: #52c8ff;
|
||||
}
|
||||
|
||||
.guidat-slider-bg {
|
||||
background-color: #222;
|
||||
cursor: ew-resize;
|
||||
width: 40%;
|
||||
margin-top: 2px;
|
||||
float: right;
|
||||
height: 21px;
|
||||
}
|
||||
|
||||
.guidat-slider-fg {
|
||||
cursor: ew-resize;
|
||||
background-color: #00aeff;
|
||||
height: 21px;
|
||||
}
|
1861
src/DAT/GUI/GUI.js
1861
src/DAT/GUI/GUI.js
File diff suppressed because it is too large
Load Diff
189
src/dat/color/Color.js
Normal file
189
src/dat/color/Color.js
Normal file
@ -0,0 +1,189 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
define([
|
||||
'dat/color/interpret',
|
||||
'dat/color/math',
|
||||
'dat/color/toString',
|
||||
'dat/utils/common'
|
||||
], function(interpret, math, toString, common) {
|
||||
|
||||
var Color = function() {
|
||||
|
||||
this.__state = interpret.apply(this, arguments);
|
||||
|
||||
if (this.__state === false) {
|
||||
throw 'Failed to interpret color arguments';
|
||||
}
|
||||
|
||||
this.__state.a = this.__state.a || 1;
|
||||
|
||||
|
||||
};
|
||||
|
||||
Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];
|
||||
|
||||
common.extend(Color.prototype, {
|
||||
|
||||
toString: function() {
|
||||
return toString(this);
|
||||
},
|
||||
|
||||
toOriginal: function() {
|
||||
return this.__state.conversion.write(this);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
defineRGBComponent(Color.prototype, 'r', 2);
|
||||
defineRGBComponent(Color.prototype, 'g', 1);
|
||||
defineRGBComponent(Color.prototype, 'b', 0);
|
||||
|
||||
defineHSVComponent(Color.prototype, 'h');
|
||||
defineHSVComponent(Color.prototype, 's');
|
||||
defineHSVComponent(Color.prototype, 'v');
|
||||
|
||||
Object.defineProperty(Color.prototype, 'a', {
|
||||
|
||||
get: function() {
|
||||
return this.__state.a;
|
||||
},
|
||||
|
||||
set: function(v) {
|
||||
this.__state.a = v;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
Object.defineProperty(Color.prototype, 'hex', {
|
||||
|
||||
get: function() {
|
||||
|
||||
if (!this.__state.space !== 'HEX') {
|
||||
this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);
|
||||
}
|
||||
|
||||
return this.__state.hex;
|
||||
|
||||
},
|
||||
|
||||
set: function(v) {
|
||||
|
||||
this.__state.space = 'HEX';
|
||||
this.__state.hex = v;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
function defineRGBComponent(target, component, componentHexIndex) {
|
||||
|
||||
Object.defineProperty(target, component, {
|
||||
|
||||
get: function() {
|
||||
|
||||
if (this.__state.space === 'RGB') {
|
||||
return this.__state[component];
|
||||
}
|
||||
|
||||
recalculateRGB(this, component, componentHexIndex);
|
||||
|
||||
return this.__state[component];
|
||||
|
||||
},
|
||||
|
||||
set: function(v) {
|
||||
|
||||
if (this.__state.space !== 'RGB') {
|
||||
recalculateRGB(this, component, componentHexIndex);
|
||||
this.__state.space = 'RGB';
|
||||
}
|
||||
|
||||
this.__state[component] = v;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function defineHSVComponent(target, component) {
|
||||
|
||||
Object.defineProperty(target, component, {
|
||||
|
||||
get: function() {
|
||||
|
||||
if (this.__state.space === 'HSV')
|
||||
return this.__state[component];
|
||||
|
||||
recalculateHSV(this);
|
||||
|
||||
return this.__state[component];
|
||||
|
||||
},
|
||||
|
||||
set: function(v) {
|
||||
|
||||
if (this.__state.space !== 'HSV') {
|
||||
recalculateHSV(this);
|
||||
this.__state.space = 'HSV';
|
||||
}
|
||||
|
||||
this.__state[component] = v;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function recalculateRGB(color, component, componentHexIndex) {
|
||||
|
||||
if (color.__state.space === 'HEX') {
|
||||
|
||||
color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);
|
||||
|
||||
} else if (color.__state.space === 'HSV') {
|
||||
|
||||
common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));
|
||||
|
||||
} else {
|
||||
|
||||
throw 'Corrupted color state';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function recalculateHSV(color) {
|
||||
|
||||
var result = math.rgb_to_hsv(color.r, color.g, color.b);
|
||||
|
||||
common.extend(color.__state,
|
||||
{
|
||||
s: result.s,
|
||||
v: result.v
|
||||
}
|
||||
);
|
||||
|
||||
if (!common.isNaN(result.h)) {
|
||||
color.__state.h = result.h;
|
||||
} else if (common.isUndefined(color.__state.h)) {
|
||||
color.__state.h = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Color;
|
||||
|
||||
});
|
340
src/dat/color/interpret.js
Normal file
340
src/dat/color/interpret.js
Normal file
@ -0,0 +1,340 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
define([
|
||||
'dat/color/toString',
|
||||
'dat/utils/common'
|
||||
], function(toString, common) {
|
||||
|
||||
var result, toReturn;
|
||||
|
||||
var interpret = function() {
|
||||
|
||||
toReturn = false;
|
||||
|
||||
var original = arguments.length > 1 ? common.toArray(arguments) : arguments[0];
|
||||
|
||||
common.each(INTERPRETATIONS, function(family) {
|
||||
|
||||
if (family.litmus(original)) {
|
||||
|
||||
common.each(family.conversions, function(conversion, conversionName) {
|
||||
|
||||
result = conversion.read(original);
|
||||
|
||||
if (toReturn === false && result !== false) {
|
||||
toReturn = result;
|
||||
result.conversionName = conversionName;
|
||||
result.conversion = conversion;
|
||||
return common.BREAK;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return common.BREAK;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return toReturn;
|
||||
|
||||
};
|
||||
|
||||
var INTERPRETATIONS = [
|
||||
|
||||
// Strings
|
||||
{
|
||||
|
||||
litmus: common.isString,
|
||||
|
||||
conversions: {
|
||||
|
||||
THREE_CHAR_HEX: {
|
||||
|
||||
read: function(original) {
|
||||
|
||||
var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);
|
||||
if (test === null) return false;
|
||||
|
||||
return {
|
||||
space: 'HEX',
|
||||
hex: parseInt(
|
||||
'0x' +
|
||||
test[1].toString() + test[1].toString() +
|
||||
test[2].toString() + test[2].toString() +
|
||||
test[3].toString() + test[3].toString())
|
||||
};
|
||||
|
||||
},
|
||||
|
||||
write: toString
|
||||
|
||||
},
|
||||
|
||||
SIX_CHAR_HEX: {
|
||||
|
||||
read: function(original) {
|
||||
|
||||
var test = original.match(/^#([A-F0-9]{6})$/i);
|
||||
if (test === null) return false;
|
||||
|
||||
return {
|
||||
space: 'HEX',
|
||||
hex: parseInt('0x' + test[1].toString())
|
||||
};
|
||||
|
||||
},
|
||||
|
||||
write: toString
|
||||
|
||||
},
|
||||
|
||||
CSS_RGB: {
|
||||
|
||||
read: function(original) {
|
||||
|
||||
var test = original.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/);
|
||||
if (test === null) return false;
|
||||
|
||||
return {
|
||||
space: 'RGB',
|
||||
r: parseFloat(test[1]),
|
||||
g: parseFloat(test[2]),
|
||||
b: parseFloat(test[3])
|
||||
};
|
||||
|
||||
},
|
||||
|
||||
write: toString
|
||||
|
||||
},
|
||||
|
||||
CSS_RGBA: {
|
||||
|
||||
read: function(original) {
|
||||
|
||||
var test = original.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\,\s*(.+)\s*\)/);
|
||||
if (test === null) return false;
|
||||
|
||||
return {
|
||||
space: 'RGB',
|
||||
r: parseFloat(test[1]),
|
||||
g: parseFloat(test[2]),
|
||||
b: parseFloat(test[3]),
|
||||
a: parseFloat(test[4])
|
||||
};
|
||||
|
||||
},
|
||||
|
||||
write: toString
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
// Numbers
|
||||
{
|
||||
|
||||
litmus: common.isNumber,
|
||||
|
||||
conversions: {
|
||||
|
||||
HEX: {
|
||||
read: function(original) {
|
||||
return {
|
||||
space: 'HEX',
|
||||
hex: original,
|
||||
conversionName: 'HEX'
|
||||
}
|
||||
},
|
||||
|
||||
write: function(color) {
|
||||
return color.hex;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
// Arrays
|
||||
{
|
||||
|
||||
litmus: common.isArray,
|
||||
|
||||
conversions: {
|
||||
|
||||
RGB_ARRAY: {
|
||||
read: function(original) {
|
||||
if (original.length != 3) return false;
|
||||
return {
|
||||
space: 'RGB',
|
||||
r: original[0],
|
||||
g: original[1],
|
||||
b: original[2]
|
||||
};
|
||||
},
|
||||
|
||||
write: function(color) {
|
||||
return [color.r, color.g, color.b];
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
RGBA_ARRAY: {
|
||||
read: function(original) {
|
||||
if (original.length != 4) return false;
|
||||
return {
|
||||
space: 'RGB',
|
||||
r: original[0],
|
||||
g: original[1],
|
||||
b: original[2],
|
||||
a: original[3]
|
||||
};
|
||||
},
|
||||
|
||||
write: function(color) {
|
||||
return [color.r, color.g, color.b, color.a];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
// Objects
|
||||
{
|
||||
|
||||
litmus: common.isObject,
|
||||
|
||||
conversions: {
|
||||
|
||||
RGBA_OBJ: {
|
||||
read: function(original) {
|
||||
if (common.isNumber(original.r) &&
|
||||
common.isNumber(original.g) &&
|
||||
common.isNumber(original.b) &&
|
||||
common.isNumber(original.a)) {
|
||||
return {
|
||||
space: 'RGB',
|
||||
r: original.r,
|
||||
g: original.g,
|
||||
b: original.b,
|
||||
a: original.a
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
write: function(color) {
|
||||
return {
|
||||
r: color.r,
|
||||
g: color.g,
|
||||
b: color.b,
|
||||
a: color.a
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
RGB_OBJ: {
|
||||
read: function(original) {
|
||||
if (common.isNumber(original.r) &&
|
||||
common.isNumber(original.g) &&
|
||||
common.isNumber(original.b)) {
|
||||
return {
|
||||
space: 'RGB',
|
||||
r: original.r,
|
||||
g: original.g,
|
||||
b: original.b
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
write: function(color) {
|
||||
return {
|
||||
r: color.r,
|
||||
g: color.g,
|
||||
b: color.b
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
HSVA_OBJ: {
|
||||
read: function(original) {
|
||||
if (common.isNumber(original.h) &&
|
||||
common.isNumber(original.s) &&
|
||||
common.isNumber(original.v) &&
|
||||
common.isNumber(original.a)) {
|
||||
return {
|
||||
space: 'HSV',
|
||||
h: original.h,
|
||||
s: original.s,
|
||||
v: original.v,
|
||||
a: original.a
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
write: function(color) {
|
||||
return {
|
||||
h: color.h,
|
||||
s: color.s,
|
||||
v: color.v,
|
||||
a: color.a
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
HSV_OBJ: {
|
||||
read: function(original) {
|
||||
if (common.isNumber(original.h) &&
|
||||
common.isNumber(original.s) &&
|
||||
common.isNumber(original.v)) {
|
||||
return {
|
||||
space: 'HSV',
|
||||
h: original.h,
|
||||
s: original.s,
|
||||
v: original.v
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
write: function(color) {
|
||||
return {
|
||||
h: color.h,
|
||||
s: color.s,
|
||||
v: color.v
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
];
|
||||
|
||||
return interpret;
|
||||
|
||||
|
||||
});
|
100
src/dat/color/math.js
Normal file
100
src/dat/color/math.js
Normal file
@ -0,0 +1,100 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
define([
|
||||
|
||||
], function() {
|
||||
|
||||
var tmpComponent;
|
||||
|
||||
return {
|
||||
|
||||
hsv_to_rgb: function(h, s, v) {
|
||||
|
||||
var hi = Math.floor(h / 60) % 6;
|
||||
|
||||
var f = h / 60 - Math.floor(h / 60);
|
||||
var p = v * (1.0 - s);
|
||||
var q = v * (1.0 - (f * s));
|
||||
var t = v * (1.0 - ((1.0 - f) * s));
|
||||
var c = [
|
||||
[v, t, p],
|
||||
[q, v, p],
|
||||
[p, v, t],
|
||||
[p, q, v],
|
||||
[t, p, v],
|
||||
[v, p, q]
|
||||
][hi];
|
||||
|
||||
return {
|
||||
r: c[0] * 255,
|
||||
g: c[1] * 255,
|
||||
b: c[2] * 255
|
||||
};
|
||||
|
||||
},
|
||||
|
||||
rgb_to_hsv: function(r, g, b) {
|
||||
|
||||
var min = Math.min(r, g, b),
|
||||
max = Math.max(r, g, b),
|
||||
delta = max - min,
|
||||
h, s;
|
||||
|
||||
if (max != 0) {
|
||||
s = delta / max;
|
||||
} else {
|
||||
return {
|
||||
h: NaN,
|
||||
s: 0,
|
||||
v: 0
|
||||
};
|
||||
}
|
||||
|
||||
if (r == max) {
|
||||
h = (g - b) / delta;
|
||||
} else if (g == max) {
|
||||
h = 2 + (b - r) / delta;
|
||||
} else {
|
||||
h = 4 + (r - g) / delta;
|
||||
}
|
||||
h /= 6;
|
||||
if (h < 0) {
|
||||
h += 1;
|
||||
}
|
||||
|
||||
return {
|
||||
h: h * 360,
|
||||
s: s,
|
||||
v: max / 255
|
||||
};
|
||||
},
|
||||
|
||||
rgb_to_hex: function(r, g, b) {
|
||||
var hex = this.hex_with_component(0, 2, r);
|
||||
hex = this.hex_with_component(hex, 1, g);
|
||||
hex = this.hex_with_component(hex, 0, b);
|
||||
return hex;
|
||||
},
|
||||
|
||||
component_from_hex: function(hex, componentIndex) {
|
||||
return (hex >> (componentIndex * 8)) & 0xFF;
|
||||
},
|
||||
|
||||
hex_with_component: function(hex, componentIndex, value) {
|
||||
return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
37
src/dat/color/toString.js
Normal file
37
src/dat/color/toString.js
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
define([
|
||||
'dat/utils/common'
|
||||
], function(common) {
|
||||
|
||||
return function(color) {
|
||||
|
||||
if (color.a == 1 || common.isUndefined(color.a)) {
|
||||
|
||||
var s = color.hex.toString(16);
|
||||
while (s.length < 6) {
|
||||
s = '0' + s;
|
||||
}
|
||||
|
||||
return '#' + s;
|
||||
|
||||
} else {
|
||||
|
||||
return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
96
src/dat/controllers/BooleanController.js
Normal file
96
src/dat/controllers/BooleanController.js
Normal file
@ -0,0 +1,96 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
define([
|
||||
'dat/controllers/Controller',
|
||||
'dat/dom/dom',
|
||||
'dat/utils/common'
|
||||
], function(Controller, dom, common) {
|
||||
|
||||
/**
|
||||
* @class Provides a checkbox input to alter the boolean property of an object.
|
||||
* @extends dat.controllers.Controller
|
||||
*
|
||||
* @param {Object} object The object to be manipulated
|
||||
* @param {string} property The name of the property to be manipulated
|
||||
*
|
||||
* @member dat.controllers
|
||||
*/
|
||||
var BooleanController = function(object, property) {
|
||||
|
||||
BooleanController.superclass.call(this, object, property);
|
||||
|
||||
var _this = this;
|
||||
var _prev = this.getValue();
|
||||
|
||||
this.__checkbox = document.createElement('input');
|
||||
this.__checkbox.setAttribute('type', 'checkbox');
|
||||
|
||||
|
||||
dom.bind(this.__checkbox, 'change', onChange, false);
|
||||
|
||||
this.domElement.appendChild(this.__checkbox);
|
||||
|
||||
// Match original value
|
||||
this.updateDisplay();
|
||||
|
||||
function onChange() {
|
||||
var cur = !_this.getValue();
|
||||
if (cur !== _prev) {
|
||||
_this.setValue(cur);
|
||||
} else {
|
||||
_this.setValue(!cur);
|
||||
}
|
||||
_prev = cur;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
BooleanController.superclass = Controller;
|
||||
|
||||
common.extend(
|
||||
|
||||
BooleanController.prototype,
|
||||
Controller.prototype,
|
||||
|
||||
{
|
||||
|
||||
setValue: function(v) {
|
||||
var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);
|
||||
if (this.__onFinishChange) {
|
||||
this.__onFinishChange.call(this, this.getValue());
|
||||
}
|
||||
this.__prev = this.getValue();
|
||||
return toReturn;
|
||||
},
|
||||
|
||||
updateDisplay: function() {
|
||||
|
||||
if (this.getValue() === true) {
|
||||
this.__checkbox.setAttribute('checked', 'checked');
|
||||
} else {
|
||||
this.__checkbox.removeAttribute('checked');
|
||||
}
|
||||
|
||||
return BooleanController.superclass.prototype.updateDisplay.call(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
return BooleanController;
|
||||
|
||||
});
|
324
src/dat/controllers/ColorController.js
Normal file
324
src/dat/controllers/ColorController.js
Normal file
@ -0,0 +1,324 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
define([
|
||||
'dat/controllers/Controller',
|
||||
'dat/dom/dom',
|
||||
'dat/color/Color',
|
||||
'dat/color/interpret',
|
||||
'dat/utils/common'
|
||||
], function(Controller, dom, Color, interpret, common) {
|
||||
|
||||
var ColorController = function(object, property) {
|
||||
|
||||
ColorController.superclass.call(this, object, property);
|
||||
|
||||
this.__color = new Color(this.getValue());
|
||||
this.__temp = new Color(0);
|
||||
|
||||
var _this = this;
|
||||
|
||||
this.domElement = document.createElement('div');
|
||||
|
||||
dom.makeSelectable(this.domElement, false);
|
||||
|
||||
this.__selector = document.createElement('div');
|
||||
this.__selector.className = 'selector';
|
||||
|
||||
this.__saturation_field = document.createElement('div');
|
||||
this.__saturation_field.className = 'saturation-field';
|
||||
|
||||
this.__field_knob = document.createElement('div');
|
||||
this.__field_knob.className = 'field-knob';
|
||||
this.__field_knob_border = '2px solid ';
|
||||
|
||||
this.__hue_knob = document.createElement('div');
|
||||
this.__hue_knob.className = 'hue-knob';
|
||||
|
||||
this.__hue_field = document.createElement('div');
|
||||
this.__hue_field.className = 'hue-field';
|
||||
|
||||
this.__input = document.createElement('input');
|
||||
this.__input.type = 'text';
|
||||
this.__input_textShadow = '0 1px 1px ';
|
||||
|
||||
dom.bind(this.__input, 'keydown', function(e) {
|
||||
if (e.keyCode === 13) { // on enter
|
||||
onBlur.call(this);
|
||||
}
|
||||
});
|
||||
|
||||
dom.bind(this.__input, 'blur', onBlur);
|
||||
|
||||
dom.bind(this.__selector, 'mousedown', function(e) {
|
||||
|
||||
dom
|
||||
.addClass(this, 'drag')
|
||||
.bind(window, 'mouseup', function(e) {
|
||||
dom.removeClass(_this.__selector, 'drag');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
var value_field = document.createElement('div');
|
||||
|
||||
common.extend(this.__selector.style, {
|
||||
width: '122px',
|
||||
height: '102px',
|
||||
padding: '3px',
|
||||
backgroundColor: '#222',
|
||||
boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'
|
||||
});
|
||||
|
||||
common.extend(this.__field_knob.style, {
|
||||
position: 'absolute',
|
||||
width: '12px',
|
||||
height: '12px',
|
||||
border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),
|
||||
boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',
|
||||
borderRadius: '12px',
|
||||
zIndex: 1
|
||||
});
|
||||
|
||||
common.extend(this.__hue_knob.style, {
|
||||
position: 'absolute',
|
||||
width: '15px',
|
||||
height: '2px',
|
||||
borderRight: '4px solid #fff',
|
||||
zIndex: 1
|
||||
});
|
||||
|
||||
common.extend(this.__saturation_field.style, {
|
||||
width: '100px',
|
||||
height: '100px',
|
||||
border: '1px solid #555',
|
||||
marginRight: '3px',
|
||||
display: 'inline-block',
|
||||
cursor: 'pointer'
|
||||
});
|
||||
|
||||
common.extend(value_field.style, {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
background: 'none'
|
||||
});
|
||||
|
||||
linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');
|
||||
|
||||
common.extend(this.__hue_field.style, {
|
||||
width: '15px',
|
||||
height: '100px',
|
||||
display: 'inline-block',
|
||||
border: '1px solid #555',
|
||||
cursor: 'ns-resize'
|
||||
});
|
||||
|
||||
hueGradient(this.__hue_field);
|
||||
|
||||
common.extend(this.__input.style, {
|
||||
outline: 'none',
|
||||
// width: '120px',
|
||||
textAlign: 'center',
|
||||
// padding: '4px',
|
||||
// marginBottom: '6px',
|
||||
color: '#fff',
|
||||
border: 0,
|
||||
fontWeight: 'bold',
|
||||
textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'
|
||||
});
|
||||
|
||||
dom.bind(this.__saturation_field, 'mousedown', fieldDown);
|
||||
dom.bind(this.__field_knob, 'mousedown', fieldDown);
|
||||
|
||||
dom.bind(this.__hue_field, 'mousedown', function(e) {
|
||||
setH(e);
|
||||
dom.bind(window, 'mousemove', setH);
|
||||
dom.bind(window, 'mouseup', unbindH);
|
||||
});
|
||||
|
||||
function fieldDown(e) {
|
||||
setSV(e);
|
||||
// document.body.style.cursor = 'none';
|
||||
dom.bind(window, 'mousemove', setSV);
|
||||
dom.bind(window, 'mouseup', unbindSV);
|
||||
}
|
||||
|
||||
function unbindSV() {
|
||||
dom.unbind(window, 'mousemove', setSV);
|
||||
dom.unbind(window, 'mouseup', unbindSV);
|
||||
// document.body.style.cursor = 'default';
|
||||
}
|
||||
|
||||
function onBlur() {
|
||||
var i = interpret(this.value);
|
||||
if (i !== false) {
|
||||
_this.__color.__state = i;
|
||||
_this.setValue(_this.__color.toOriginal());
|
||||
} else {
|
||||
this.value = _this.__color.toString();
|
||||
}
|
||||
}
|
||||
|
||||
function unbindH() {
|
||||
dom.unbind(window, 'mousemove', setH);
|
||||
dom.unbind(window, 'mouseup', unbindH);
|
||||
}
|
||||
|
||||
this.__saturation_field.appendChild(value_field);
|
||||
this.__selector.appendChild(this.__field_knob);
|
||||
this.__selector.appendChild(this.__saturation_field);
|
||||
this.__selector.appendChild(this.__hue_field);
|
||||
this.__hue_field.appendChild(this.__hue_knob);
|
||||
|
||||
this.domElement.appendChild(this.__input);
|
||||
this.domElement.appendChild(this.__selector);
|
||||
|
||||
this.updateDisplay();
|
||||
|
||||
function setSV(e) {
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
var w = dom.getWidth(_this.__saturation_field);
|
||||
var o = dom.getOffset(_this.__saturation_field);
|
||||
var s = (e.clientX - o.left + document.body.scrollLeft) / w;
|
||||
var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w;
|
||||
|
||||
if (v > 1) v = 1;
|
||||
else if (v < 0) v = 0;
|
||||
|
||||
if (s > 1) s = 1;
|
||||
else if (s < 0) s = 0;
|
||||
|
||||
_this.__color.v = v;
|
||||
_this.__color.s = s;
|
||||
|
||||
_this.setValue(_this.__color.toOriginal());
|
||||
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
function setH(e) {
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
var s = dom.getHeight(_this.__hue_field);
|
||||
var o = dom.getOffset(_this.__hue_field);
|
||||
var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s;
|
||||
|
||||
if (h > 1) h = 1;
|
||||
else if (h < 0) h = 0;
|
||||
|
||||
_this.__color.h = h * 360;
|
||||
|
||||
_this.setValue(_this.__color.toOriginal());
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
ColorController.superclass = Controller;
|
||||
|
||||
common.extend(
|
||||
|
||||
ColorController.prototype,
|
||||
Controller.prototype,
|
||||
|
||||
{
|
||||
|
||||
updateDisplay: function() {
|
||||
|
||||
var i = interpret(this.getValue());
|
||||
|
||||
if (i !== false) {
|
||||
|
||||
var mismatch = false;
|
||||
|
||||
// Check for mismatch on the interpreted value.
|
||||
|
||||
common.each(Color.COMPONENTS, function(component) {
|
||||
if (!common.isUndefined(i[component]) &&
|
||||
!common.isUndefined(this.__color.__state[component]) &&
|
||||
i[component] !== this.__color.__state[component]) {
|
||||
mismatch = true;
|
||||
return {}; // break
|
||||
}
|
||||
}, this);
|
||||
|
||||
// If nothing diverges, we keep our previous values
|
||||
// for statefulness, otherwise we recalculate fresh
|
||||
if (mismatch) {
|
||||
common.extend(this.__color.__state, i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
common.extend(this.__temp.__state, this.__color.__state);
|
||||
|
||||
this.__temp.a = 1;
|
||||
|
||||
var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;
|
||||
var _flip = 255 - flip;
|
||||
|
||||
common.extend(this.__field_knob.style, {
|
||||
marginLeft: 100 * this.__color.s - 7 + 'px',
|
||||
marginTop: 100 * (1 - this.__color.v) - 7 + 'px',
|
||||
backgroundColor: this.__temp.toString(),
|
||||
border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')'
|
||||
});
|
||||
|
||||
this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'
|
||||
|
||||
this.__temp.s = 1;
|
||||
this.__temp.v = 1;
|
||||
|
||||
linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());
|
||||
|
||||
common.extend(this.__input.style, {
|
||||
backgroundColor: this.__input.value = this.__color.toString(),
|
||||
color: 'rgb(' + flip + ',' + flip + ',' + flip +')',
|
||||
textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)'
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
var vendors = ['-moz-','-o-','-webkit-','-ms-',''];
|
||||
|
||||
function linearGradient(elem, x, a, b) {
|
||||
elem.style.background = '';
|
||||
common.each(vendors, function(vendor) {
|
||||
elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); ';
|
||||
});
|
||||
}
|
||||
|
||||
function hueGradient(elem) {
|
||||
elem.style.background = '';
|
||||
elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'
|
||||
elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'
|
||||
elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'
|
||||
elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'
|
||||
elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'
|
||||
}
|
||||
|
||||
|
||||
return ColorController;
|
||||
|
||||
});
|
144
src/dat/controllers/Controller.js
Normal file
144
src/dat/controllers/Controller.js
Normal file
@ -0,0 +1,144 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
define([
|
||||
'dat/utils/common'
|
||||
], function(common) {
|
||||
|
||||
/**
|
||||
* @class An "abstract" class that represents a given property of an object.
|
||||
*
|
||||
* @param {Object} object The object to be manipulated
|
||||
* @param {string} property The name of the property to be manipulated
|
||||
*
|
||||
* @member dat.controllers
|
||||
*/
|
||||
var Controller = function(object, property) {
|
||||
|
||||
this.initialValue = object[property];
|
||||
|
||||
/**
|
||||
* Those who extend this class will put their DOM elements in here.
|
||||
* @type {DOMElement}
|
||||
*/
|
||||
this.domElement = document.createElement('div');
|
||||
|
||||
/**
|
||||
* The object to manipulate
|
||||
* @type {Object}
|
||||
*/
|
||||
this.object = object;
|
||||
|
||||
/**
|
||||
* The name of the property to manipulate
|
||||
* @type {String}
|
||||
*/
|
||||
this.property = property;
|
||||
|
||||
/**
|
||||
* The function to be called on change.
|
||||
* @type {Function}
|
||||
* @ignore
|
||||
*/
|
||||
this.__onChange = undefined;
|
||||
|
||||
/**
|
||||
* The function to be called on finishing change.
|
||||
* @type {Function}
|
||||
* @ignore
|
||||
*/
|
||||
this.__onFinishChange = undefined;
|
||||
|
||||
};
|
||||
|
||||
common.extend(
|
||||
|
||||
Controller.prototype,
|
||||
|
||||
/** @lends dat.controllers.Controller.prototype */
|
||||
{
|
||||
|
||||
/**
|
||||
* Specify that a function fire every time someone changes the value with
|
||||
* this Controller.
|
||||
*
|
||||
* @param {Function} fnc This function will be called whenever the value
|
||||
* is modified via this Controller.
|
||||
* @returns {dat.controllers.Controller} this
|
||||
*/
|
||||
onChange: function(fnc) {
|
||||
this.__onChange = fnc;
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Specify that a function fire every time someone "finishes" changing
|
||||
* the value wih this Controller. Useful for values that change
|
||||
* incrementally like numbers or strings.
|
||||
*
|
||||
* @param {Function} fnc This function will be called whenever
|
||||
* someone "finishes" changing the value via this Controller.
|
||||
* @returns {dat.controllers.Controller} this
|
||||
*/
|
||||
onFinishChange: function(fnc) {
|
||||
this.__onFinishChange = fnc;
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Change the value of <code>object[property]</code>
|
||||
*
|
||||
* @param {Object} newValue The new value of <code>object[property]</code>
|
||||
*/
|
||||
setValue: function(newValue) {
|
||||
this.object[this.property] = newValue;
|
||||
if (this.__onChange) {
|
||||
this.__onChange.call(this, newValue);
|
||||
}
|
||||
this.updateDisplay();
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the value of <code>object[property]</code>
|
||||
*
|
||||
* @returns {Object} The current value of <code>object[property]</code>
|
||||
*/
|
||||
getValue: function() {
|
||||
return this.object[this.property];
|
||||
},
|
||||
|
||||
/**
|
||||
* Refreshes the visual display of a Controller in order to keep sync
|
||||
* with the object's current value.
|
||||
* @returns {dat.controllers.Controller} this
|
||||
*/
|
||||
updateDisplay: function() {
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* @returns {Boolean} true if the value has deviated from initialValue
|
||||
*/
|
||||
isModified: function() {
|
||||
return this.initialValue !== this.getValue()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
return Controller;
|
||||
|
||||
|
||||
});
|
72
src/dat/controllers/FunctionController.js
Normal file
72
src/dat/controllers/FunctionController.js
Normal file
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
define([
|
||||
'dat/controllers/Controller',
|
||||
'dat/dom/dom',
|
||||
'dat/utils/common'
|
||||
], function(Controller, dom, common) {
|
||||
|
||||
/**
|
||||
* @class Provides a GUI interface to fire a specified method, a property of an object.
|
||||
*
|
||||
* @extends dat.controllers.Controller
|
||||
*
|
||||
* @param {Object} object The object to be manipulated
|
||||
* @param {string} property The name of the property to be manipulated
|
||||
*
|
||||
* @member dat.controllers
|
||||
*/
|
||||
var FunctionController = function(object, property, text) {
|
||||
|
||||
FunctionController.superclass.call(this, object, property);
|
||||
|
||||
var _this = this;
|
||||
|
||||
this.__button = document.createElement('div');
|
||||
this.__button.innerHTML = text === undefined ? 'Fire' : text;
|
||||
dom.bind(this.__button, 'click', function() {
|
||||
_this.fire();
|
||||
});
|
||||
|
||||
dom.addClass(this.__button, 'button');
|
||||
|
||||
this.domElement.appendChild(this.__button);
|
||||
|
||||
|
||||
};
|
||||
|
||||
FunctionController.superclass = Controller;
|
||||
|
||||
common.extend(
|
||||
|
||||
FunctionController.prototype,
|
||||
Controller.prototype,
|
||||
{
|
||||
|
||||
fire: function() {
|
||||
if (this.__onChange) {
|
||||
this.__onChange.call(this);
|
||||
}
|
||||
if (this.__onFinishChange) {
|
||||
this.__onFinishChange.call(this, this.getValue());
|
||||
}
|
||||
this.getValue().call(this.object);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
return FunctionController;
|
||||
|
||||
});
|
143
src/dat/controllers/NumberController.js
Normal file
143
src/dat/controllers/NumberController.js
Normal file
@ -0,0 +1,143 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
define([
|
||||
'dat/controllers/Controller',
|
||||
'dat/utils/common'
|
||||
], function(Controller, common) {
|
||||
|
||||
/**
|
||||
* @class Represents a given property of an object that is a number.
|
||||
*
|
||||
* @extends dat.controllers.Controller
|
||||
*
|
||||
* @param {Object} object The object to be manipulated
|
||||
* @param {string} property The name of the property to be manipulated
|
||||
* @param {Object} [params] Optional parameters
|
||||
* @param {Number} [params.min] Minimum allowed value
|
||||
* @param {Number} [params.max] Maximum allowed value
|
||||
* @param {Number} [params.step] Increment by which to change value
|
||||
*
|
||||
* @member dat.controllers
|
||||
*/
|
||||
var NumberController = function(object, property, params) {
|
||||
|
||||
NumberController.superclass.call(this, object, property);
|
||||
|
||||
params = params || {};
|
||||
|
||||
this.__min = params.min;
|
||||
this.__max = params.max;
|
||||
this.__step = params.step;
|
||||
|
||||
if (common.isUndefined(this.__step)) {
|
||||
|
||||
if (this.initialValue == 0) {
|
||||
this.__impliedStep = 1; // What are we, psychics?
|
||||
} else {
|
||||
// Hey Doug, check this out.
|
||||
this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
this.__impliedStep = this.__step;
|
||||
|
||||
}
|
||||
|
||||
this.__precision = numDecimals(this.__impliedStep);
|
||||
|
||||
|
||||
};
|
||||
|
||||
NumberController.superclass = Controller;
|
||||
|
||||
common.extend(
|
||||
|
||||
NumberController.prototype,
|
||||
Controller.prototype,
|
||||
|
||||
/** @lends dat.controllers.NumberController.prototype */
|
||||
{
|
||||
|
||||
setValue: function(v) {
|
||||
|
||||
if (this.__min !== undefined && v < this.__min) {
|
||||
v = this.__min;
|
||||
} else if (this.__max !== undefined && v > this.__max) {
|
||||
v = this.__max;
|
||||
}
|
||||
|
||||
if (this.__step !== undefined && v % this.__step != 0) {
|
||||
v = Math.round(v / this.__step) * this.__step;
|
||||
}
|
||||
|
||||
return NumberController.superclass.prototype.setValue.call(this, v);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Specify a minimum value for <code>object[property]</code>.
|
||||
*
|
||||
* @param {Number} minValue The minimum value for
|
||||
* <code>object[property]</code>
|
||||
* @returns {dat.controllers.NumberController} this
|
||||
*/
|
||||
min: function(v) {
|
||||
this.__min = v;
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Specify a maximum value for <code>object[property]</code>.
|
||||
*
|
||||
* @param {Number} maxValue The maximum value for
|
||||
* <code>object[property]</code>
|
||||
* @returns {dat.controllers.NumberController} this
|
||||
*/
|
||||
max: function(v) {
|
||||
this.__max = v;
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Specify a step value that dat.controllers.NumberController
|
||||
* increments by.
|
||||
*
|
||||
* @param {Number} stepValue The step value for
|
||||
* dat.controllers.NumberController
|
||||
* @default if minimum and maximum specified increment is 1% of the
|
||||
* difference otherwise stepValue is 1
|
||||
* @returns {dat.controllers.NumberController} this
|
||||
*/
|
||||
step: function(v) {
|
||||
this.__step = v;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
function numDecimals(x) {
|
||||
x = x.toString();
|
||||
if (x.indexOf('.') > -1) {
|
||||
return x.length - x.indexOf('.') - 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return NumberController;
|
||||
|
||||
});
|
134
src/dat/controllers/NumberControllerBox.js
Normal file
134
src/dat/controllers/NumberControllerBox.js
Normal file
@ -0,0 +1,134 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
define([
|
||||
'dat/controllers/NumberController',
|
||||
'dat/dom/dom',
|
||||
'dat/utils/common'
|
||||
], function(NumberController, dom, common) {
|
||||
|
||||
/**
|
||||
* @class Represents a given property of an object that is a number and
|
||||
* provides an input element with which to manipulate it.
|
||||
*
|
||||
* @extends dat.controllers.Controller
|
||||
* @extends dat.controllers.NumberController
|
||||
*
|
||||
* @param {Object} object The object to be manipulated
|
||||
* @param {string} property The name of the property to be manipulated
|
||||
* @param {Object} [params] Optional parameters
|
||||
* @param {Number} [params.min] Minimum allowed value
|
||||
* @param {Number} [params.max] Maximum allowed value
|
||||
* @param {Number} [params.step] Increment by which to change value
|
||||
*
|
||||
* @member dat.controllers
|
||||
*/
|
||||
var NumberControllerBox = function(object, property, params) {
|
||||
|
||||
this.__truncationSuspended = false;
|
||||
|
||||
NumberControllerBox.superclass.call(this, object, property, params);
|
||||
|
||||
var _this = this;
|
||||
|
||||
/**
|
||||
* {Number} Previous mouse y position
|
||||
* @ignore
|
||||
*/
|
||||
var prev_y;
|
||||
|
||||
this.__input = document.createElement('input');
|
||||
this.__input.setAttribute('type', 'text');
|
||||
|
||||
// Makes it so manually specified values are not truncated.
|
||||
|
||||
dom.bind(this.__input, 'change', onChange);
|
||||
dom.bind(this.__input, 'blur', onBlur);
|
||||
dom.bind(this.__input, 'mousedown', onMouseDown);
|
||||
dom.bind(this.__input, 'keydown', function(e) {
|
||||
|
||||
// When pressing entire, you can be as precise as you want.
|
||||
if (e.keyCode === 13) {
|
||||
_this.__truncationSuspended = true;
|
||||
this.blur();
|
||||
_this.__truncationSuspended = false;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
function onChange() {
|
||||
var attempted = parseFloat(_this.__input.value);
|
||||
if (!common.isNaN(attempted)) _this.setValue(attempted);
|
||||
}
|
||||
|
||||
function onBlur() {
|
||||
onChange();
|
||||
if (_this.__onFinishChange) {
|
||||
_this.__onFinishChange.call(_this, _this.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseDown(e) {
|
||||
dom.bind(window, 'mousemove', onMouseDrag);
|
||||
dom.bind(window, 'mouseup', onMouseUp);
|
||||
prev_y = e.clientY;
|
||||
}
|
||||
|
||||
function onMouseDrag(e) {
|
||||
|
||||
var diff = prev_y - e.clientY;
|
||||
_this.setValue(_this.getValue() + diff * _this.__impliedStep);
|
||||
|
||||
prev_y = e.clientY;
|
||||
|
||||
}
|
||||
|
||||
function onMouseUp() {
|
||||
dom.unbind(window, 'mousemove', onMouseDrag);
|
||||
dom.unbind(window, 'mouseup', onMouseUp);
|
||||
}
|
||||
|
||||
this.updateDisplay();
|
||||
|
||||
this.domElement.appendChild(this.__input);
|
||||
|
||||
};
|
||||
|
||||
NumberControllerBox.superclass = NumberController;
|
||||
|
||||
common.extend(
|
||||
|
||||
NumberControllerBox.prototype,
|
||||
NumberController.prototype,
|
||||
|
||||
{
|
||||
|
||||
updateDisplay: function() {
|
||||
|
||||
this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);
|
||||
return NumberControllerBox.superclass.prototype.updateDisplay.call(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
function roundToDecimal(value, decimals) {
|
||||
var tenTo = Math.pow(10, decimals);
|
||||
return Math.round(value * tenTo) / tenTo;
|
||||
}
|
||||
|
||||
return NumberControllerBox;
|
||||
|
||||
});
|
||||
|
43
src/dat/controllers/NumberControllerSlider.css
Normal file
43
src/dat/controllers/NumberControllerSlider.css
Normal file
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
.slider {
|
||||
box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);
|
||||
height: 1em;
|
||||
border-radius: 1em;
|
||||
background-color: #eee;
|
||||
padding: 0 0.5em;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.slider-fg {
|
||||
padding: 1px 0 2px 0;
|
||||
background-color: #aaa;
|
||||
height: 1em;
|
||||
margin-left: -0.5em;
|
||||
padding-right: 0.5em;
|
||||
border-radius: 1em 0 0 1em;
|
||||
}
|
||||
|
||||
.slider-fg:after {
|
||||
display: inline-block;
|
||||
border-radius: 1em;
|
||||
background-color: #fff;
|
||||
border: 1px solid #aaa;
|
||||
content: '';
|
||||
float: right;
|
||||
margin-right: -1em;
|
||||
margin-top: -1px;
|
||||
height: 0.9em;
|
||||
width: 0.9em;
|
||||
}
|
129
src/dat/controllers/NumberControllerSlider.js
Normal file
129
src/dat/controllers/NumberControllerSlider.js
Normal file
@ -0,0 +1,129 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
define([
|
||||
'dat/controllers/NumberController',
|
||||
'dat/dom/dom',
|
||||
'dat/utils/css',
|
||||
'dat/utils/common',
|
||||
'text!dat/controllers/NumberControllerSlider.css'
|
||||
],
|
||||
function(NumberController, dom, css, common, styleSheet) {
|
||||
|
||||
/**
|
||||
* @class Represents a given property of an object that is a number, contains
|
||||
* a minimum and maximum, and provides a slider element with which to
|
||||
* manipulate it. It should be noted that the slider element is made up of
|
||||
* <code><div></code> tags, <strong>not</strong> the html5
|
||||
* <code><slider></code> element.
|
||||
*
|
||||
* @extends dat.controllers.Controller
|
||||
* @extends dat.controllers.NumberController
|
||||
*
|
||||
* @param {Object} object The object to be manipulated
|
||||
* @param {string} property The name of the property to be manipulated
|
||||
* @param {Number} minValue Minimum allowed value
|
||||
* @param {Number} maxValue Maximum allowed value
|
||||
* @param {Number} stepValue Increment by which to change value
|
||||
*
|
||||
* @member dat.controllers
|
||||
*/
|
||||
var NumberControllerSlider = function(object, property, min, max, step) {
|
||||
|
||||
NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step });
|
||||
|
||||
var _this = this;
|
||||
|
||||
this.__background = document.createElement('div');
|
||||
this.__foreground = document.createElement('div');
|
||||
|
||||
|
||||
|
||||
dom.bind(this.__background, 'mousedown', onMouseDown);
|
||||
|
||||
dom.addClass(this.__background, 'slider');
|
||||
dom.addClass(this.__foreground, 'slider-fg');
|
||||
|
||||
function onMouseDown(e) {
|
||||
|
||||
dom.bind(window, 'mousemove', onMouseDrag);
|
||||
dom.bind(window, 'mouseup', onMouseUp);
|
||||
|
||||
onMouseDrag(e);
|
||||
}
|
||||
|
||||
function onMouseDrag(e) {
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
var offset = dom.getOffset(_this.__background);
|
||||
var width = dom.getWidth(_this.__background);
|
||||
|
||||
_this.setValue(
|
||||
map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)
|
||||
);
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
function onMouseUp() {
|
||||
dom.unbind(window, 'mousemove', onMouseDrag);
|
||||
dom.unbind(window, 'mouseup', onMouseUp);
|
||||
if (_this.__onFinishChange) {
|
||||
_this.__onFinishChange.call(_this, _this.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
this.updateDisplay();
|
||||
|
||||
this.__background.appendChild(this.__foreground);
|
||||
this.domElement.appendChild(this.__background);
|
||||
|
||||
};
|
||||
|
||||
NumberControllerSlider.superclass = NumberController;
|
||||
|
||||
/**
|
||||
* Injects default stylesheet for slider elements.
|
||||
*/
|
||||
NumberControllerSlider.useDefaultStyles = function() {
|
||||
css.inject(styleSheet);
|
||||
};
|
||||
|
||||
common.extend(
|
||||
|
||||
NumberControllerSlider.prototype,
|
||||
NumberController.prototype,
|
||||
|
||||
{
|
||||
|
||||
updateDisplay: function() {
|
||||
var pct = (this.getValue() - this.__min)/(this.__max - this.__min);
|
||||
this.__foreground.style.width = pct*100+'%';
|
||||
return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
);
|
||||
|
||||
function map(v, i1, i2, o1, o2) {
|
||||
return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));
|
||||
}
|
||||
|
||||
return NumberControllerSlider;
|
||||
|
||||
});
|
103
src/dat/controllers/OptionController.js
Normal file
103
src/dat/controllers/OptionController.js
Normal file
@ -0,0 +1,103 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
define([
|
||||
'dat/controllers/Controller',
|
||||
'dat/dom/dom',
|
||||
'dat/utils/common'
|
||||
],
|
||||
function(Controller, dom, common) {
|
||||
|
||||
/**
|
||||
* @class Provides a select input to alter the property of an object, using a
|
||||
* list of accepted values.
|
||||
*
|
||||
* @extends dat.controllers.Controller
|
||||
*
|
||||
* @param {Object} object The object to be manipulated
|
||||
* @param {string} property The name of the property to be manipulated
|
||||
* @param {Object|string[]} options A map of labels to acceptable values, or
|
||||
* a list of acceptable string values.
|
||||
*
|
||||
* @member dat.controllers
|
||||
*/
|
||||
var OptionController = function(object, property, options) {
|
||||
|
||||
OptionController.superclass.call(this, object, property);
|
||||
|
||||
var _this = this;
|
||||
|
||||
/**
|
||||
* The drop down menu
|
||||
* @ignore
|
||||
*/
|
||||
this.__select = document.createElement('select');
|
||||
|
||||
if (common.isArray(options)) {
|
||||
var map = {};
|
||||
common.each(options, function(element) {
|
||||
map[element] = element;
|
||||
});
|
||||
options = map;
|
||||
}
|
||||
|
||||
common.each(options, function(value, key) {
|
||||
|
||||
var opt = document.createElement('option');
|
||||
opt.innerHTML = key;
|
||||
opt.setAttribute('value', value);
|
||||
_this.__select.appendChild(opt);
|
||||
|
||||
});
|
||||
|
||||
// Acknowledge original value
|
||||
this.updateDisplay();
|
||||
|
||||
dom.bind(this.__select, 'change', function() {
|
||||
var desiredValue = this.options[this.selectedIndex].value;
|
||||
_this.setValue(desiredValue);
|
||||
});
|
||||
|
||||
this.domElement.appendChild(this.__select);
|
||||
|
||||
};
|
||||
|
||||
OptionController.superclass = Controller;
|
||||
|
||||
common.extend(
|
||||
|
||||
OptionController.prototype,
|
||||
Controller.prototype,
|
||||
|
||||
{
|
||||
|
||||
setValue: function(v) {
|
||||
var toReturn = OptionController.superclass.prototype.setValue.call(this, v);
|
||||
if (this.__onFinishChange) {
|
||||
this.__onFinishChange.call(this, this.getValue());
|
||||
}
|
||||
return toReturn;
|
||||
},
|
||||
|
||||
updateDisplay: function() {
|
||||
this.__select.value = this.getValue();
|
||||
return OptionController.superclass.prototype.updateDisplay.call(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
return OptionController;
|
||||
|
||||
});
|
89
src/dat/controllers/StringController.js
Normal file
89
src/dat/controllers/StringController.js
Normal file
@ -0,0 +1,89 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
define([
|
||||
'dat/controllers/Controller',
|
||||
'dat/dom/dom',
|
||||
'dat/utils/common'
|
||||
], function(Controller, dom, common) {
|
||||
|
||||
/**
|
||||
* @class Provides a text input to alter the string property of an object.
|
||||
*
|
||||
* @extends dat.controllers.Controller
|
||||
*
|
||||
* @param {Object} object The object to be manipulated
|
||||
* @param {string} property The name of the property to be manipulated
|
||||
*
|
||||
* @member dat.controllers
|
||||
*/
|
||||
var StringController = function(object, property) {
|
||||
|
||||
StringController.superclass.call(this, object, property);
|
||||
|
||||
var _this = this;
|
||||
|
||||
this.__input = document.createElement('input');
|
||||
this.__input.setAttribute('type', 'text');
|
||||
|
||||
dom.bind(this.__input, 'keyup', onChange);
|
||||
dom.bind(this.__input, 'change', onChange);
|
||||
dom.bind(this.__input, 'blur', onBlur);
|
||||
dom.bind(this.__input, 'keydown', function(e) {
|
||||
if (e.keyCode === 13) {
|
||||
this.blur();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function onChange() {
|
||||
_this.setValue(_this.__input.value);
|
||||
}
|
||||
|
||||
function onBlur() {
|
||||
if (_this.__onFinishChange) {
|
||||
_this.__onFinishChange.call(_this, _this.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
this.updateDisplay();
|
||||
|
||||
this.domElement.appendChild(this.__input);
|
||||
|
||||
};
|
||||
|
||||
StringController.superclass = Controller;
|
||||
|
||||
common.extend(
|
||||
|
||||
StringController.prototype,
|
||||
Controller.prototype,
|
||||
|
||||
{
|
||||
|
||||
updateDisplay: function() {
|
||||
// Stops the caret from moving on account of:
|
||||
// keyup -> setValue -> updateDisplay
|
||||
if (!dom.isActive(this.__input)) {
|
||||
this.__input.value = this.getValue();
|
||||
}
|
||||
return StringController.superclass.prototype.updateDisplay.call(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
return StringController;
|
||||
|
||||
});
|
65
src/dat/controllers/factory.js
Normal file
65
src/dat/controllers/factory.js
Normal file
@ -0,0 +1,65 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
define([
|
||||
'dat/controllers/OptionController',
|
||||
'dat/controllers/NumberControllerBox',
|
||||
'dat/controllers/NumberControllerSlider',
|
||||
'dat/controllers/StringController',
|
||||
'dat/controllers/FunctionController',
|
||||
'dat/controllers/BooleanController',
|
||||
'dat/utils/common'
|
||||
],
|
||||
function(OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) {
|
||||
|
||||
return function(object, property) {
|
||||
|
||||
var initialValue = object[property];
|
||||
|
||||
// Providing options?
|
||||
if (common.isArray(arguments[2]) || common.isObject(arguments[2])) {
|
||||
return new OptionController(object, property, arguments[2]);
|
||||
}
|
||||
|
||||
// Providing a map?
|
||||
|
||||
if (common.isNumber(initialValue)) {
|
||||
|
||||
if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {
|
||||
|
||||
// Has min and max.
|
||||
return new NumberControllerSlider(object, property, arguments[2], arguments[3]);
|
||||
|
||||
} else {
|
||||
|
||||
return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] });
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (common.isString(initialValue)) {
|
||||
return new StringController(object, property);
|
||||
}
|
||||
|
||||
if (common.isFunction(initialValue)) {
|
||||
return new FunctionController(object, property, '');
|
||||
}
|
||||
|
||||
if (common.isBoolean(initialValue)) {
|
||||
return new BooleanController(object, property);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
109
src/dat/dom/CenteredDiv.js
Normal file
109
src/dat/dom/CenteredDiv.js
Normal file
@ -0,0 +1,109 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
define([
|
||||
'dat/dom/dom',
|
||||
'dat/utils/common'
|
||||
], function(dom, common) {
|
||||
|
||||
var CenteredDiv = function() {
|
||||
|
||||
this.backgroundElement = document.createElement('div');
|
||||
common.extend(this.backgroundElement.style, {
|
||||
backgroundColor: 'rgba(0,0,0,0.5)',
|
||||
display: 'none',
|
||||
zIndex: '1000',
|
||||
opacity: 0,
|
||||
WebkitTransition: 'opacity 0.2s linear'
|
||||
});
|
||||
|
||||
dom.makeFullscreen(this.backgroundElement);
|
||||
|
||||
this.domElement = document.createElement('div');
|
||||
common.extend(this.domElement.style, {
|
||||
position: 'fixed',
|
||||
display: 'none',
|
||||
left: '50%',
|
||||
top: '50%',
|
||||
zIndex: '1001',
|
||||
opacity: 0,
|
||||
WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear'
|
||||
});
|
||||
|
||||
|
||||
document.body.appendChild(this.backgroundElement);
|
||||
document.body.appendChild(this.domElement);
|
||||
|
||||
var _this = this;
|
||||
dom.bind(this.backgroundElement, 'click', function() {
|
||||
_this.hide();
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
CenteredDiv.prototype.show = function() {
|
||||
|
||||
var _this = this;
|
||||
|
||||
this.backgroundElement.style.display = 'block';
|
||||
|
||||
this.domElement.style.display = 'block';
|
||||
this.domElement.style.opacity = 0;
|
||||
// this.domElement.style.top = '52%';
|
||||
this.domElement.style.webkitTransform = 'scale(1.1)';
|
||||
|
||||
this.layout();
|
||||
|
||||
common.defer(function() {
|
||||
_this.backgroundElement.style.opacity = 1;
|
||||
_this.domElement.style.opacity = 1;
|
||||
_this.domElement.style.webkitTransform = 'scale(1)';
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
CenteredDiv.prototype.hide = function() {
|
||||
|
||||
var _this = this;
|
||||
|
||||
var hide = function() {
|
||||
|
||||
_this.domElement.style.display = 'none';
|
||||
_this.backgroundElement.style.display = 'none';
|
||||
|
||||
dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);
|
||||
dom.unbind(_this.domElement, 'transitionend', hide);
|
||||
dom.unbind(_this.domElement, 'oTransitionEnd', hide);
|
||||
|
||||
};
|
||||
|
||||
dom.bind(this.domElement, 'webkitTransitionEnd', hide);
|
||||
dom.bind(this.domElement, 'transitionend', hide);
|
||||
dom.bind(this.domElement, 'oTransitionEnd', hide);
|
||||
|
||||
this.backgroundElement.style.opacity = 0;
|
||||
// this.domElement.style.top = '48%';
|
||||
this.domElement.style.opacity = 0;
|
||||
this.domElement.style.webkitTransform = 'scale(1.1)';
|
||||
|
||||
};
|
||||
|
||||
CenteredDiv.prototype.layout = function() {
|
||||
this.domElement.style.marginLeft = -dom.getWidth(this.domElement) / 2 + 'px';
|
||||
this.domElement.style.marginTop = -dom.getHeight(this.domElement) / 2 + 'px';
|
||||
};
|
||||
|
||||
return CenteredDiv;
|
||||
|
||||
});
|
287
src/dat/dom/dom.js
Normal file
287
src/dat/dom/dom.js
Normal file
@ -0,0 +1,287 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
define([
|
||||
'dat/utils/common'
|
||||
], function(common) {
|
||||
|
||||
var EVENT_MAP = {
|
||||
'HTMLEvents': ['change'],
|
||||
'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'],
|
||||
'KeyboardEvents': ['keydown']
|
||||
};
|
||||
|
||||
var EVENT_MAP_INV = {};
|
||||
common.each(EVENT_MAP, function(v, k) {
|
||||
common.each(v, function(e) {
|
||||
EVENT_MAP_INV[e] = k;
|
||||
});
|
||||
});
|
||||
|
||||
var CSS_VALUE_PIXELS = /(\d+(\.\d+)?)px/;
|
||||
|
||||
function cssValueToPixels(val) {
|
||||
|
||||
if (val === '0' || common.isUndefined(val)) return 0;
|
||||
|
||||
var match = val.match(CSS_VALUE_PIXELS);
|
||||
|
||||
if (!common.isNull(match)) {
|
||||
return parseFloat(match[1]);
|
||||
}
|
||||
|
||||
// TODO ...ems? %?
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @namespace
|
||||
* @member dat.dom
|
||||
*/
|
||||
var dom = {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param elem
|
||||
* @param selectable
|
||||
*/
|
||||
makeSelectable: function(elem, selectable) {
|
||||
|
||||
if (elem === undefined || elem.style === undefined) return;
|
||||
|
||||
elem.onselectstart = selectable ? function() {
|
||||
return false;
|
||||
} : function() {
|
||||
};
|
||||
|
||||
elem.style.MozUserSelect = selectable ? 'auto' : 'none';
|
||||
elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';
|
||||
elem.unselectable = selectable ? 'on' : 'off';
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param elem
|
||||
* @param horizontal
|
||||
* @param vertical
|
||||
*/
|
||||
makeFullscreen: function(elem, horizontal, vertical) {
|
||||
|
||||
if (common.isUndefined(horizontal)) horizontal = true;
|
||||
if (common.isUndefined(vertical)) vertical = true;
|
||||
|
||||
elem.style.position = 'absolute';
|
||||
|
||||
if (horizontal) {
|
||||
elem.style.left = 0;
|
||||
elem.style.right = 0;
|
||||
}
|
||||
if (vertical) {
|
||||
elem.style.top = 0;
|
||||
elem.style.bottom = 0;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param elem
|
||||
* @param eventType
|
||||
* @param params
|
||||
*/
|
||||
fakeEvent: function(elem, eventType, params, aux) {
|
||||
params = params || {};
|
||||
var className = EVENT_MAP_INV[eventType];
|
||||
if (!className) {
|
||||
throw new Error('Event type ' + eventType + ' not supported.');
|
||||
}
|
||||
var evt = document.createEvent(className);
|
||||
switch (className) {
|
||||
case 'MouseEvents':
|
||||
var clientX = params.x || params.clientX || 0;
|
||||
var clientY = params.y || params.clientY || 0;
|
||||
evt.initMouseEvent(eventType, params.bubbles || false,
|
||||
params.cancelable || true, window, params.clickCount || 1,
|
||||
0, //screen X
|
||||
0, //screen Y
|
||||
clientX, //client X
|
||||
clientY, //client Y
|
||||
false, false, false, false, 0, null);
|
||||
break;
|
||||
case 'KeyboardEvents':
|
||||
var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz
|
||||
common.defaults(params, {
|
||||
cancelable: true,
|
||||
ctrlKey: false,
|
||||
altKey: false,
|
||||
shiftKey: false,
|
||||
metaKey: false,
|
||||
keyCode: undefined,
|
||||
charCode: undefined
|
||||
});
|
||||
init(eventType, params.bubbles || false,
|
||||
params.cancelable, window,
|
||||
params.ctrlKey, params.altKey,
|
||||
params.shiftKey, params.metaKey,
|
||||
params.keyCode, params.charCode);
|
||||
break;
|
||||
default:
|
||||
evt.initEvent(eventType, params.bubbles || false,
|
||||
params.cancelable || true);
|
||||
break;
|
||||
}
|
||||
common.defaults(evt, aux);
|
||||
elem.dispatchEvent(evt);
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param elem
|
||||
* @param event
|
||||
* @param func
|
||||
* @param bool
|
||||
*/
|
||||
bind: function(elem, event, func, bool) {
|
||||
bool = bool || false;
|
||||
if (elem.addEventListener)
|
||||
elem.addEventListener(event, func, bool);
|
||||
else if (elem.attachEvent)
|
||||
elem.attachEvent('on' + event, func);
|
||||
return dom;
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param elem
|
||||
* @param event
|
||||
* @param func
|
||||
* @param bool
|
||||
*/
|
||||
unbind: function(elem, event, func, bool) {
|
||||
bool = bool || false;
|
||||
if (elem.removeEventListener)
|
||||
elem.removeEventListener(event, func, bool);
|
||||
else if (elem.detachEvent)
|
||||
elem.detachEvent('on' + event, func);
|
||||
return dom;
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param elem
|
||||
* @param className
|
||||
*/
|
||||
addClass: function(elem, className) {
|
||||
if (elem.className === undefined) {
|
||||
elem.className = className;
|
||||
} else if (elem.className !== className) {
|
||||
var classes = elem.className.split(/ +/);
|
||||
if (classes.indexOf(className) == -1) {
|
||||
classes.push(className);
|
||||
elem.className = classes.join(' ').replace(/^\s+/, '').replace(/\s+$/, '');
|
||||
}
|
||||
}
|
||||
return dom;
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param elem
|
||||
* @param className
|
||||
*/
|
||||
removeClass: function(elem, className) {
|
||||
if (className) {
|
||||
if (elem.className === undefined) {
|
||||
// elem.className = className;
|
||||
} else if (elem.className === className) {
|
||||
elem.removeAttribute('class');
|
||||
} else {
|
||||
var classes = elem.className.split(/ +/);
|
||||
var index = classes.indexOf(className);
|
||||
if (index != -1) {
|
||||
classes.splice(index, 1);
|
||||
elem.className = classes.join(' ');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
elem.className = undefined;
|
||||
}
|
||||
return dom;
|
||||
},
|
||||
|
||||
hasClass: function(elem, className) {
|
||||
return new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)').test(elem.className) || false;
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param elem
|
||||
*/
|
||||
getWidth: function(elem) {
|
||||
|
||||
var style = getComputedStyle(elem);
|
||||
|
||||
return cssValueToPixels(style['border-left-width']) +
|
||||
cssValueToPixels(style['border-right-width']) +
|
||||
cssValueToPixels(style['padding-left']) +
|
||||
cssValueToPixels(style['padding-right']) +
|
||||
cssValueToPixels(style['width']);
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param elem
|
||||
*/
|
||||
getHeight: function(elem) {
|
||||
|
||||
var style = getComputedStyle(elem);
|
||||
|
||||
return cssValueToPixels(style['border-top-width']) +
|
||||
cssValueToPixels(style['border-bottom-width']) +
|
||||
cssValueToPixels(style['padding-top']) +
|
||||
cssValueToPixels(style['padding-bottom']) +
|
||||
cssValueToPixels(style['height']);
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @param elem
|
||||
*/
|
||||
getOffset: function(elem) {
|
||||
var offset = {left: 0, top:0};
|
||||
if (elem.offsetParent) {
|
||||
do {
|
||||
offset.left += elem.offsetLeft;
|
||||
offset.top += elem.offsetTop;
|
||||
} while (elem = elem.offsetParent);
|
||||
}
|
||||
return offset;
|
||||
},
|
||||
|
||||
// http://stackoverflow.com/posts/2684561/revisions
|
||||
/**
|
||||
*
|
||||
* @param elem
|
||||
*/
|
||||
isActive: function(elem) {
|
||||
return elem === document.activeElement && ( elem.type || elem.href );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return dom;
|
||||
|
||||
});
|
221
src/dat/gui/_structure.scss
Normal file
221
src/dat/gui/_structure.scss
Normal file
@ -0,0 +1,221 @@
|
||||
$nest-margin: 4px;
|
||||
$row-height: 27px;
|
||||
|
||||
.dg {
|
||||
|
||||
/** Clear list styles */
|
||||
ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* Auto-place container */
|
||||
&.ac {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 0;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
&.main {
|
||||
@include transition(opacity, 0.1s, linear);
|
||||
/*overflow-y: hidden;*/
|
||||
&.taller-than-window {
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
/* Auto-placed GUI's */
|
||||
&.a {
|
||||
|
||||
float: right;
|
||||
margin-right: 15px;
|
||||
overflow-x: hidden;
|
||||
|
||||
&.has-save {
|
||||
margin-top: $row-height;
|
||||
}
|
||||
|
||||
.save-row {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
z-index: 1002;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Line items that don't contain folders. */
|
||||
li:not(.folder) {
|
||||
cursor: auto;
|
||||
height: $row-height;
|
||||
line-height: $row-height;
|
||||
overflow: hidden;
|
||||
padding: 0 4px 0 5px;
|
||||
@include transition(height, 0.1s, ease-out);
|
||||
}
|
||||
|
||||
li.folder {
|
||||
padding: 0;
|
||||
border-left: $nest-margin solid rgba(0,0,0,0);
|
||||
|
||||
}
|
||||
|
||||
/** Folder names */
|
||||
li.title {
|
||||
cursor: pointer;
|
||||
margin-left: -$nest-margin;
|
||||
}
|
||||
|
||||
/** Hides closed items */
|
||||
.closed li:not(.title),
|
||||
.closed ul li,
|
||||
.closed ul li > * {
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/** Controller row */
|
||||
.cr {
|
||||
clear: both;
|
||||
padding-left: 3px;
|
||||
height: $row-height;
|
||||
}
|
||||
|
||||
/** Name-half (left) */
|
||||
.property-name {
|
||||
cursor: default;
|
||||
float: left;
|
||||
clear: left;
|
||||
width: 40%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
/** Controller-half (right) */
|
||||
.c {
|
||||
float: left;
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
/** Controller placement */
|
||||
.c input[type=text] {
|
||||
border: 0;
|
||||
margin-top: 4px;
|
||||
padding: 3px;
|
||||
width: 100%;
|
||||
float: right;
|
||||
}
|
||||
|
||||
/** Shorter number boxes when slider is present. */
|
||||
.has-slider input[type=text] {
|
||||
width: 30%;
|
||||
/*display: none;*/
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.slider {
|
||||
float: left;
|
||||
width: 66%;
|
||||
margin-left: -5px;
|
||||
margin-right: 0;
|
||||
height: 19px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.slider-fg {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.c input[type=checkbox] {
|
||||
margin-top: 9px;
|
||||
}
|
||||
|
||||
.c select {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
/** Ensure the entire boolean and function row shows a hand */
|
||||
.cr.function,
|
||||
.cr.function .property-name, /* Don't know why I need to be this explicit */
|
||||
.cr.function *,
|
||||
.cr.boolean,
|
||||
.cr.boolean * {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
.selector {
|
||||
display: none;
|
||||
position: absolute;
|
||||
margin-left: -9px;
|
||||
margin-top: 23px;
|
||||
}
|
||||
|
||||
|
||||
.c:hover .selector,
|
||||
.selector.drag {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
li.save-row {
|
||||
|
||||
padding: 0;
|
||||
|
||||
.button {
|
||||
display: inline-block;
|
||||
padding: 0px 6px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&.dialogue {
|
||||
background-color: #222;
|
||||
width: 460px;
|
||||
padding: 15px;
|
||||
font-size: 13px;
|
||||
line-height: 15px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* TODO Separate style and structure */
|
||||
#dg-new-constructor {
|
||||
padding: 10px;
|
||||
color: #222;
|
||||
font-family: Monaco, monospace;
|
||||
font-size: 10px;
|
||||
border: 0;
|
||||
resize: none;
|
||||
box-shadow: inset 1px 1px 1px #888;
|
||||
word-wrap: break-word;
|
||||
margin: 12px 0;
|
||||
display: block;
|
||||
width: 440px;
|
||||
overflow-y: scroll;
|
||||
height: 100px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#dg-local-explain {
|
||||
display: none;
|
||||
font-size: 11px;
|
||||
line-height: 17px;
|
||||
border-radius: 3px;
|
||||
background-color: #333;
|
||||
padding: 8px;
|
||||
margin-top: 10px;
|
||||
code {
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
#dat-gui-save-locally {
|
||||
display: none;
|
||||
}
|
21
src/dat/gui/saveDialogue.html
Normal file
21
src/dat/gui/saveDialogue.html
Normal file
@ -0,0 +1,21 @@
|
||||
<div id="dg-save" class="dg dialogue">
|
||||
|
||||
Here's the new load parameter for your <code>GUI</code>'s constructor:
|
||||
|
||||
<textarea id="dg-new-constructor"></textarea>
|
||||
|
||||
<div id="dg-save-locally">
|
||||
|
||||
<input id="dg-local-storage" type="checkbox"/> Automatically save
|
||||
values to <code>localStorage</code> on exit.
|
||||
|
||||
<div id="dg-local-explain">The values saved to <code>localStorage</code> will
|
||||
override those passed to <code>dat.GUI</code>'s constructor. This makes it
|
||||
easier to work incrementally, but <code>localStorage</code> is fragile,
|
||||
and your friends may not see the same values you do.
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
261
src/dat/gui/style.css
Normal file
261
src/dat/gui/style.css
Normal file
@ -0,0 +1,261 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
.dg {
|
||||
/** Clear list styles */
|
||||
/* Auto-place container */
|
||||
/* Auto-placed GUI's */
|
||||
/* Line items that don't contain folders. */
|
||||
/** Folder names */
|
||||
/** Hides closed items */
|
||||
/** Controller row */
|
||||
/** Name-half (left) */
|
||||
/** Controller-half (right) */
|
||||
/** Controller placement */
|
||||
/** Shorter number boxes when slider is present. */
|
||||
/** Ensure the entire boolean and function row shows a hand */ }
|
||||
.dg ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
clear: both; }
|
||||
.dg.ac {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 0;
|
||||
z-index: 0; }
|
||||
.dg.main {
|
||||
-webkit-transition: opacity 0.1s linear;
|
||||
-o-transition: opacity 0.1s linear;
|
||||
-moz-transition: opacity 0.1s linear;
|
||||
transition: opacity 0.1s linear;
|
||||
/*overflow-y: hidden;*/ }
|
||||
.dg.main.taller-than-window {
|
||||
overflow-y: auto; }
|
||||
.dg.a {
|
||||
float: right;
|
||||
margin-right: 15px;
|
||||
overflow-x: hidden; }
|
||||
.dg.a.has-save {
|
||||
margin-top: 27px; }
|
||||
.dg.a .save-row {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
z-index: 1002; }
|
||||
.dg li:not(.folder) {
|
||||
cursor: auto;
|
||||
height: 27px;
|
||||
line-height: 27px;
|
||||
overflow: hidden;
|
||||
padding: 0 4px 0 5px;
|
||||
-webkit-transition: height 0.1s ease-out;
|
||||
-o-transition: height 0.1s ease-out;
|
||||
-moz-transition: height 0.1s ease-out;
|
||||
transition: height 0.1s ease-out; }
|
||||
.dg li.folder {
|
||||
padding: 0;
|
||||
border-left: 4px solid rgba(0, 0, 0, 0); }
|
||||
.dg li.title {
|
||||
cursor: pointer;
|
||||
margin-left: -4px; }
|
||||
.dg .closed li:not(.title),
|
||||
.dg .closed ul li,
|
||||
.dg .closed ul li > * {
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
border: 0; }
|
||||
.dg .cr {
|
||||
clear: both;
|
||||
padding-left: 3px;
|
||||
height: 27px; }
|
||||
.dg .property-name {
|
||||
cursor: default;
|
||||
float: left;
|
||||
clear: left;
|
||||
width: 40%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis; }
|
||||
.dg .c {
|
||||
float: left;
|
||||
width: 60%; }
|
||||
.dg .c input[type=text] {
|
||||
border: 0;
|
||||
margin-top: 4px;
|
||||
padding: 3px;
|
||||
width: 100%;
|
||||
float: right; }
|
||||
.dg .has-slider input[type=text] {
|
||||
width: 30%;
|
||||
/*display: none;*/
|
||||
margin-left: 0; }
|
||||
.dg .slider {
|
||||
float: left;
|
||||
width: 66%;
|
||||
margin-left: -5px;
|
||||
margin-right: 0;
|
||||
height: 19px;
|
||||
margin-top: 4px; }
|
||||
.dg .slider-fg {
|
||||
height: 100%; }
|
||||
.dg .c input[type=checkbox] {
|
||||
margin-top: 9px; }
|
||||
.dg .c select {
|
||||
margin-top: 5px; }
|
||||
.dg .cr.function,
|
||||
.dg .cr.function .property-name,
|
||||
.dg .cr.function *,
|
||||
.dg .cr.boolean,
|
||||
.dg .cr.boolean * {
|
||||
cursor: pointer; }
|
||||
.dg .selector {
|
||||
display: none;
|
||||
position: absolute;
|
||||
margin-left: -9px;
|
||||
margin-top: 23px; }
|
||||
.dg .c:hover .selector,
|
||||
.dg .selector.drag {
|
||||
display: block; }
|
||||
.dg li.save-row {
|
||||
padding: 0; }
|
||||
.dg li.save-row .button {
|
||||
display: inline-block;
|
||||
padding: 0px 6px; }
|
||||
.dg.dialogue {
|
||||
background-color: #222;
|
||||
width: 460px;
|
||||
padding: 15px;
|
||||
font-size: 13px;
|
||||
line-height: 15px; }
|
||||
|
||||
/* TODO Separate style and structure */
|
||||
#dg-new-constructor {
|
||||
padding: 10px;
|
||||
color: #222;
|
||||
font-family: Monaco, monospace;
|
||||
font-size: 10px;
|
||||
border: 0;
|
||||
resize: none;
|
||||
box-shadow: inset 1px 1px 1px #888;
|
||||
word-wrap: break-word;
|
||||
margin: 12px 0;
|
||||
display: block;
|
||||
width: 440px;
|
||||
overflow-y: scroll;
|
||||
height: 100px;
|
||||
position: relative; }
|
||||
|
||||
#dg-local-explain {
|
||||
display: none;
|
||||
font-size: 11px;
|
||||
line-height: 17px;
|
||||
border-radius: 3px;
|
||||
background-color: #333;
|
||||
padding: 8px;
|
||||
margin-top: 10px; }
|
||||
#dg-local-explain code {
|
||||
font-size: 10px; }
|
||||
|
||||
#dat-gui-save-locally {
|
||||
display: none; }
|
||||
|
||||
/** Main type */
|
||||
.dg {
|
||||
color: #eee;
|
||||
font: 11px 'Lucida Grande', sans-serif;
|
||||
text-shadow: 0 -1px 0 #111111;
|
||||
/** Auto place */
|
||||
/* Controller row, <li> */
|
||||
/** Controllers */ }
|
||||
.dg.main {
|
||||
/** Scrollbar */ }
|
||||
.dg.main::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
background: #1a1a1a; }
|
||||
.dg.main::-webkit-scrollbar-corner {
|
||||
height: 0;
|
||||
display: none; }
|
||||
.dg.main::-webkit-scrollbar-thumb {
|
||||
border-radius: 5px;
|
||||
background: #676767; }
|
||||
.dg li:not(.folder) {
|
||||
background: #1a1a1a;
|
||||
border-bottom: 1px solid #2c2c2c; }
|
||||
.dg li.save-row {
|
||||
line-height: 25px;
|
||||
background: #dad5cb;
|
||||
border: 0; }
|
||||
.dg li.save-row select {
|
||||
margin-left: 5px;
|
||||
width: 108px; }
|
||||
.dg li.save-row .button {
|
||||
margin-left: 5px;
|
||||
margin-top: 1px;
|
||||
border-radius: 2px;
|
||||
font-size: 9px;
|
||||
line-height: 7px;
|
||||
padding: 4px 4px 5px 4px;
|
||||
background: #c5bdad;
|
||||
color: #fff;
|
||||
text-shadow: 0 1px 0 #b0a58f;
|
||||
box-shadow: 0 -1px 0 #b0a58f;
|
||||
cursor: pointer; }
|
||||
.dg li.save-row .button.gears {
|
||||
background: #c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;
|
||||
height: 7px;
|
||||
width: 8px; }
|
||||
.dg li.save-row .button:hover {
|
||||
background-color: #bab19e;
|
||||
box-shadow: 0 -1px 0 #b0a58f; }
|
||||
.dg li.folder {
|
||||
border-bottom: 0; }
|
||||
.dg li.title {
|
||||
padding-left: 16px;
|
||||
background: black url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.2); }
|
||||
.dg .closed li.title {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==); }
|
||||
.dg .cr.boolean {
|
||||
border-left: 3px solid #806787; }
|
||||
.dg .cr.function {
|
||||
border-left: 3px solid #e61d5f; }
|
||||
.dg .cr.number {
|
||||
border-left: 3px solid #2fa1d6; }
|
||||
.dg .cr.number input[type=text] {
|
||||
color: #2fa1d6; }
|
||||
.dg .cr.string {
|
||||
border-left: 3px solid #1ed36f; }
|
||||
.dg .cr.string input[type=text] {
|
||||
color: #1ed36f; }
|
||||
.dg .cr.function:hover, .dg .cr.boolean:hover {
|
||||
background: #111; }
|
||||
.dg .c input[type=text] {
|
||||
background: #303030;
|
||||
outline: none; }
|
||||
.dg .c input[type=text]:hover {
|
||||
background: #3c3c3c; }
|
||||
.dg .c input[type=text]:focus {
|
||||
background: #494949;
|
||||
color: #fff; }
|
||||
.dg .c .slider {
|
||||
background: #303030;
|
||||
cursor: ew-resize; }
|
||||
.dg .c .slider-fg {
|
||||
background: #2fa1d6; }
|
||||
.dg .c .slider:hover {
|
||||
background: #3c3c3c; }
|
||||
.dg .c .slider:hover .slider-fg {
|
||||
background: #44abda; }
|
202
src/dat/gui/style.scss
Normal file
202
src/dat/gui/style.scss
Normal file
@ -0,0 +1,202 @@
|
||||
$background-color: #1a1a1a;
|
||||
|
||||
$hover-lighten: 5%;
|
||||
$border-lighten: 7%;
|
||||
$active-lighten: 10%;
|
||||
|
||||
$number-color: #2FA1D6;
|
||||
$boolean-color: #806787;
|
||||
$string-color: #1ed36f;
|
||||
$function-color: #e61d5f;
|
||||
$save-row-color: #dad5cb;
|
||||
$button-color: darken($save-row-color, 10%);
|
||||
|
||||
$input-color: lighten($background-color, 8.5%);
|
||||
|
||||
@mixin transition($prop, $time, $curve) {
|
||||
-webkit-transition: $prop $time $curve;
|
||||
-o-transition: $prop $time $curve;
|
||||
-moz-transition: $prop $time $curve;
|
||||
transition: $prop $time $curve;
|
||||
}
|
||||
|
||||
@mixin gradient($a, $b) {
|
||||
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from($a), to($b));
|
||||
background: -o-gradient(linear, 0% 0%, 0% 100%, from($a), to($b));
|
||||
background: -moz-gradient(linear, 0% 0%, 0% 100%, from($a), to($b));
|
||||
}
|
||||
|
||||
@mixin button() {
|
||||
margin-left: 5px;
|
||||
margin-top: 1px;
|
||||
border-radius: 2px;
|
||||
font-size: 9px;
|
||||
line-height: 7px;
|
||||
padding: 4px 4px 5px 4px;
|
||||
background: $button-color;
|
||||
color: #fff;
|
||||
text-shadow: 0 1px 0 darken($button-color, 10%);
|
||||
box-shadow: 0 -1px 0 darken($button-color, 10%);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@mixin gears() {
|
||||
background: $button-color url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;
|
||||
height: 7px;
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
@import "structure";
|
||||
|
||||
/** Main type */
|
||||
.dg {
|
||||
|
||||
|
||||
color: #eee;
|
||||
font: 11px 'Lucida Grande', sans-serif;
|
||||
text-shadow: 0 -1px 0 #111;
|
||||
|
||||
/** Auto place */
|
||||
&.main {
|
||||
|
||||
/** Scrollbar */
|
||||
&::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
background: $background-color;
|
||||
}
|
||||
&::-webkit-scrollbar-corner {
|
||||
height: 0;
|
||||
display: none;
|
||||
}
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 5px;
|
||||
background: lighten($background-color, 30%);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
li {
|
||||
|
||||
&:not(.folder) {
|
||||
background: $background-color;
|
||||
border-bottom: 1px solid lighten($background-color, $border-lighten);
|
||||
}
|
||||
|
||||
&.save-row {
|
||||
|
||||
line-height: 25px;
|
||||
background: $save-row-color;
|
||||
border: 0;
|
||||
|
||||
select {
|
||||
margin-left: 5px;
|
||||
width: 108px;
|
||||
|
||||
}
|
||||
|
||||
.button {
|
||||
|
||||
&.gears {
|
||||
@include gears;
|
||||
}
|
||||
|
||||
@include button;
|
||||
|
||||
&:hover {
|
||||
background-color: darken($button-color, 5%);
|
||||
box-shadow: 0 -1px 0 darken($button-color, 10%);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
&.folder {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
&.title {
|
||||
padding-left: 16px;
|
||||
background: #000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.closed li.title {
|
||||
background-image: url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==);
|
||||
}
|
||||
|
||||
/* Controller row, <li> */
|
||||
.cr {
|
||||
|
||||
&.boolean {
|
||||
border-left: 3px solid $boolean-color;
|
||||
}
|
||||
|
||||
&.function {
|
||||
border-left: 3px solid $function-color;
|
||||
}
|
||||
|
||||
&.number {
|
||||
border-left: 3px solid $number-color;
|
||||
input[type=text] {
|
||||
color: $number-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.string {
|
||||
border-left: 3px solid $string-color;
|
||||
input[type=text] {
|
||||
color: $string-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.function:hover ,
|
||||
&.boolean:hover {
|
||||
background: #111;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** Controllers */
|
||||
.c {
|
||||
|
||||
|
||||
|
||||
input[type=text] {
|
||||
|
||||
background: $input-color;
|
||||
outline: none;
|
||||
&:hover {
|
||||
background: lighten($input-color, $hover-lighten);
|
||||
}
|
||||
&:focus {
|
||||
background: lighten($input-color, $active-lighten);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
.slider {
|
||||
background: $input-color;
|
||||
cursor: ew-resize;
|
||||
}
|
||||
|
||||
.slider-fg {
|
||||
background: $number-color;
|
||||
}
|
||||
|
||||
.slider:hover {
|
||||
background: lighten($input-color, $hover-lighten);
|
||||
.slider-fg {
|
||||
background: lighten($number-color, $hover-lighten);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
139
src/dat/utils/common.js
Normal file
139
src/dat/utils/common.js
Normal file
@ -0,0 +1,139 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
define([
|
||||
], function() {
|
||||
|
||||
var ARR_EACH = Array.prototype.forEach;
|
||||
var ARR_SLICE = Array.prototype.slice;
|
||||
|
||||
/**
|
||||
* Band-aid methods for things that should be a lot easier in JavaScript.
|
||||
* Implementation and structure inspired by underscore.js
|
||||
* http://documentcloud.github.com/underscore/
|
||||
*/
|
||||
|
||||
return {
|
||||
|
||||
BREAK: {},
|
||||
|
||||
extend: function(target) {
|
||||
|
||||
this.each(ARR_SLICE.call(arguments, 1), function(obj) {
|
||||
|
||||
for (var key in obj)
|
||||
if (!this.isUndefined(obj[key]))
|
||||
target[key] = obj[key];
|
||||
|
||||
}, this);
|
||||
|
||||
return target;
|
||||
|
||||
},
|
||||
|
||||
defaults: function(target) {
|
||||
|
||||
this.each(ARR_SLICE.call(arguments, 1), function(obj) {
|
||||
|
||||
for (var key in obj)
|
||||
if (this.isUndefined(target[key]))
|
||||
target[key] = obj[key];
|
||||
|
||||
}, this);
|
||||
|
||||
return target;
|
||||
|
||||
},
|
||||
|
||||
compose: function() {
|
||||
var toCall = ARR_SLICE.call(arguments);
|
||||
return function() {
|
||||
var args = ARR_SLICE.call(arguments);
|
||||
for (var i = toCall.length -1; i >= 0; i--) {
|
||||
args = [toCall[i].apply(this, args)];
|
||||
}
|
||||
return args[0];
|
||||
}
|
||||
},
|
||||
|
||||
each: function(obj, itr, scope) {
|
||||
|
||||
|
||||
if (ARR_EACH && obj.forEach === ARR_EACH) {
|
||||
|
||||
obj.forEach(itr, scope);
|
||||
|
||||
} else if (obj.length === obj.length + 0) { // Is number but not NaN
|
||||
|
||||
for (var key = 0, l = obj.length; key < l; key++)
|
||||
if (key in obj && itr.call(scope, obj[key], key) === this.BREAK)
|
||||
return;
|
||||
|
||||
} else {
|
||||
|
||||
for (var key in obj)
|
||||
if (itr.call(scope, obj[key], key) === this.BREAK)
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
defer: function(fnc) {
|
||||
setTimeout(fnc, 0);
|
||||
},
|
||||
|
||||
toArray: function(obj) {
|
||||
if (obj.toArray) return obj.toArray();
|
||||
return ARR_SLICE.call(obj);
|
||||
},
|
||||
|
||||
isUndefined: function(obj) {
|
||||
return obj === undefined;
|
||||
},
|
||||
|
||||
isNull: function(obj) {
|
||||
return obj === null;
|
||||
},
|
||||
|
||||
isNaN: function(obj) {
|
||||
return obj !== obj;
|
||||
},
|
||||
|
||||
isArray: Array.isArray || function(obj) {
|
||||
return obj.constructor === Array;
|
||||
},
|
||||
|
||||
isObject: function(obj) {
|
||||
return obj === Object(obj);
|
||||
},
|
||||
|
||||
isNumber: function(obj) {
|
||||
return obj === obj+0;
|
||||
},
|
||||
|
||||
isString: function(obj) {
|
||||
return obj === obj+'';
|
||||
},
|
||||
|
||||
isBoolean: function(obj) {
|
||||
return obj === false || obj === true;
|
||||
},
|
||||
|
||||
isFunction: function(obj) {
|
||||
return Object.prototype.toString.call(obj) === '[object Function]';
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
});
|
33
src/dat/utils/css.js
Normal file
33
src/dat/utils/css.js
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
define([],
|
||||
function() {
|
||||
return {
|
||||
load: function (url, doc) {
|
||||
doc = doc || document;
|
||||
var link = doc.createElement('link');
|
||||
link.type = 'text/css';
|
||||
link.rel = 'stylesheet';
|
||||
link.href = url;
|
||||
doc.getElementsByTagName('head')[0].appendChild(link);
|
||||
},
|
||||
inject: function(css, doc) {
|
||||
doc = doc || document;
|
||||
var injected = document.createElement('style');
|
||||
injected.type = 'text/css';
|
||||
injected.innerHTML = css;
|
||||
doc.getElementsByTagName('head')[0].appendChild(injected);
|
||||
}
|
||||
}
|
||||
});
|
31
src/dat/utils/requestAnimationFrame.js
Normal file
31
src/dat/utils/requestAnimationFrame.js
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
define([
|
||||
], function() {
|
||||
|
||||
/**
|
||||
* requirejs version of Paul Irish's RequestAnimationFrame
|
||||
* http://paulirish.com/2011/requestanimationframe-for-smart-animating/
|
||||
*/
|
||||
|
||||
return window.webkitRequestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
window.oRequestAnimationFrame ||
|
||||
window.msRequestAnimationFrame ||
|
||||
function(callback, element) {
|
||||
|
||||
window.setTimeout(callback, 1000 / 60);
|
||||
|
||||
};
|
||||
});
|
1412
tests/index.html
Normal file
1412
tests/index.html
Normal file
File diff suppressed because it is too large
Load Diff
9046
tests/jquery.js
vendored
Normal file
9046
tests/jquery.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
226
tests/qunit.css
Normal file
226
tests/qunit.css
Normal file
@ -0,0 +1,226 @@
|
||||
/**
|
||||
* QUnit 1.2.0pre - A JavaScript Unit Testing Framework
|
||||
*
|
||||
* http://docs.jquery.com/QUnit
|
||||
*
|
||||
* Copyright (c) 2011 John Resig, Jörn Zaefferer
|
||||
* Dual licensed under the MIT (MIT-LICENSE.txt)
|
||||
* or GPL (GPL-LICENSE.txt) licenses.
|
||||
*/
|
||||
|
||||
/** Font Family and Sizes */
|
||||
|
||||
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
|
||||
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
|
||||
#qunit-tests { font-size: smaller; }
|
||||
|
||||
|
||||
/** Resets */
|
||||
|
||||
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
/** Header */
|
||||
|
||||
#qunit-header {
|
||||
padding: 0.5em 0 0.5em 1em;
|
||||
|
||||
color: #8699a4;
|
||||
background-color: #0d3349;
|
||||
|
||||
font-size: 1.5em;
|
||||
line-height: 1em;
|
||||
font-weight: normal;
|
||||
|
||||
border-radius: 15px 15px 0 0;
|
||||
-moz-border-radius: 15px 15px 0 0;
|
||||
-webkit-border-top-right-radius: 15px;
|
||||
-webkit-border-top-left-radius: 15px;
|
||||
}
|
||||
|
||||
#qunit-header a {
|
||||
text-decoration: none;
|
||||
color: #c2ccd1;
|
||||
}
|
||||
|
||||
#qunit-header a:hover,
|
||||
#qunit-header a:focus {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#qunit-banner {
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
#qunit-testrunner-toolbar {
|
||||
padding: 0.5em 0 0.5em 2em;
|
||||
color: #5E740B;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
#qunit-userAgent {
|
||||
padding: 0.5em 0 0.5em 2.5em;
|
||||
background-color: #2b81af;
|
||||
color: #fff;
|
||||
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
|
||||
}
|
||||
|
||||
|
||||
/** Tests: Pass/Fail */
|
||||
|
||||
#qunit-tests {
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
#qunit-tests li {
|
||||
padding: 0.4em 0.5em 0.4em 2.5em;
|
||||
border-bottom: 1px solid #fff;
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#qunit-tests li strong {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#qunit-tests li a {
|
||||
padding: 0.5em;
|
||||
color: #c2ccd1;
|
||||
text-decoration: none;
|
||||
}
|
||||
#qunit-tests li a:hover,
|
||||
#qunit-tests li a:focus {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#qunit-tests ol {
|
||||
margin-top: 0.5em;
|
||||
padding: 0.5em;
|
||||
|
||||
background-color: #fff;
|
||||
|
||||
border-radius: 15px;
|
||||
-moz-border-radius: 15px;
|
||||
-webkit-border-radius: 15px;
|
||||
|
||||
box-shadow: inset 0px 2px 13px #999;
|
||||
-moz-box-shadow: inset 0px 2px 13px #999;
|
||||
-webkit-box-shadow: inset 0px 2px 13px #999;
|
||||
}
|
||||
|
||||
#qunit-tests table {
|
||||
border-collapse: collapse;
|
||||
margin-top: .2em;
|
||||
}
|
||||
|
||||
#qunit-tests th {
|
||||
text-align: right;
|
||||
vertical-align: top;
|
||||
padding: 0 .5em 0 0;
|
||||
}
|
||||
|
||||
#qunit-tests td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#qunit-tests pre {
|
||||
margin: 0;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
#qunit-tests del {
|
||||
background-color: #e0f2be;
|
||||
color: #374e0c;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#qunit-tests ins {
|
||||
background-color: #ffcaca;
|
||||
color: #500;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/*** Test Counts */
|
||||
|
||||
#qunit-tests b.counts { color: black; }
|
||||
#qunit-tests b.passed { color: #5E740B; }
|
||||
#qunit-tests b.failed { color: #710909; }
|
||||
|
||||
#qunit-tests li li {
|
||||
margin: 0.5em;
|
||||
padding: 0.4em 0.5em 0.4em 0.5em;
|
||||
background-color: #fff;
|
||||
border-bottom: none;
|
||||
list-style-position: inside;
|
||||
}
|
||||
|
||||
/*** Passing Styles */
|
||||
|
||||
#qunit-tests li li.pass {
|
||||
color: #5E740B;
|
||||
background-color: #fff;
|
||||
border-left: 26px solid #C6E746;
|
||||
}
|
||||
|
||||
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
|
||||
#qunit-tests .pass .test-name { color: #366097; }
|
||||
|
||||
#qunit-tests .pass .test-actual,
|
||||
#qunit-tests .pass .test-expected { color: #999999; }
|
||||
|
||||
#qunit-banner.qunit-pass { background-color: #C6E746; }
|
||||
|
||||
/*** Failing Styles */
|
||||
|
||||
#qunit-tests li li.fail {
|
||||
color: #710909;
|
||||
background-color: #fff;
|
||||
border-left: 26px solid #EE5757;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
#qunit-tests > li:last-child {
|
||||
border-radius: 0 0 15px 15px;
|
||||
-moz-border-radius: 0 0 15px 15px;
|
||||
-webkit-border-bottom-right-radius: 15px;
|
||||
-webkit-border-bottom-left-radius: 15px;
|
||||
}
|
||||
|
||||
#qunit-tests .fail { color: #000000; background-color: #EE5757; }
|
||||
#qunit-tests .fail .test-name,
|
||||
#qunit-tests .fail .module-name { color: #000000; }
|
||||
|
||||
#qunit-tests .fail .test-actual { color: #EE5757; }
|
||||
#qunit-tests .fail .test-expected { color: green; }
|
||||
|
||||
#qunit-banner.qunit-fail { background-color: #EE5757; }
|
||||
|
||||
|
||||
/** Result */
|
||||
|
||||
#qunit-testresult {
|
||||
padding: 0.5em 0.5em 0.5em 2.5em;
|
||||
|
||||
color: #2b81af;
|
||||
background-color: #D2E0E6;
|
||||
|
||||
border-bottom: 1px solid white;
|
||||
}
|
||||
|
||||
/** Fixture */
|
||||
|
||||
#qunit-fixture {
|
||||
position: absolute;
|
||||
top: -10000px;
|
||||
left: -10000px;
|
||||
}
|
1587
tests/qunit.js
Normal file
1587
tests/qunit.js
Normal file
File diff suppressed because it is too large
Load Diff
186
utils/build.py
186
utils/build.py
@ -1,186 +0,0 @@
|
||||
#/usr/bin/env python
|
||||
|
||||
from optparse import OptionParser
|
||||
import httplib, urllib
|
||||
import os, fnmatch, shutil, re
|
||||
|
||||
usage = """usage: %prog [options] command
|
||||
|
||||
Commands:
|
||||
build build the script
|
||||
debug print the header to include js files
|
||||
clean remove any built files
|
||||
"""
|
||||
parser = OptionParser(usage=usage)
|
||||
parser.add_option('-l', '--level', dest='level', default='SIMPLE_OPTIMIZATIONS',
|
||||
help='Closure compilation level [WHITESPACE_ONLY, SIMPLE_OPTIMIZATIONS, \
|
||||
ADVANCED_OPTIMIZATIONS]')
|
||||
|
||||
UTILS = os.path.dirname(os.path.relpath(__file__))
|
||||
PREFIX = os.path.join(UTILS,'..')
|
||||
SRC_ROOT= os.path.join(PREFIX,'src')
|
||||
BUILD_ROOT = os.path.join(PREFIX,'build')
|
||||
INDEX = os.path.join(PREFIX,'index.html')
|
||||
BUILD_NAME = 'DAT.GUI'
|
||||
ALL_JS = ['DAT.GUI.js','DAT.GUI']
|
||||
|
||||
LICENSE = """/**
|
||||
* dat.gui Javascript Controller Library
|
||||
* http://dataarts.github.com/dat.gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
"""
|
||||
|
||||
def flatten(l, ltypes=(list, tuple)):
|
||||
ltype = type(l)
|
||||
l = list(l)
|
||||
i = 0
|
||||
while i < len(l):
|
||||
while isinstance(l[i], ltypes):
|
||||
if not l[i]:
|
||||
l.pop(i)
|
||||
i -= 1
|
||||
break
|
||||
else:
|
||||
l[i:i + 1] = l[i]
|
||||
i += 1
|
||||
return ltype(l)
|
||||
|
||||
def expand(path, globby):
|
||||
matches = []
|
||||
path = path.split('.')
|
||||
path.insert(0,SRC_ROOT)
|
||||
filename = "%s.%s"%(path[-2],path[-1])
|
||||
if fnmatch.fnmatch(filename, globby):
|
||||
tmppath = os.path.join(*(path[:-1]+[filename]))
|
||||
if os.path.exists(tmppath):
|
||||
path[-1] = filename
|
||||
else:
|
||||
path = path[:-2]+[filename]
|
||||
path = os.path.join(*path)
|
||||
if os.path.isdir(path):
|
||||
for root, dirnames, filenames in os.walk(path):
|
||||
for filename in fnmatch.filter(filenames, globby):
|
||||
matches.append(os.path.join(root, filename))
|
||||
else:
|
||||
matches.append(path)
|
||||
return matches
|
||||
|
||||
def unique(seq, idfun=None):
|
||||
"""Ordered uniquify function
|
||||
if in 2.7 use:
|
||||
OrderedDict.fromkeys(seq).keys()
|
||||
"""
|
||||
if idfun is None:
|
||||
def idfun(x): return x
|
||||
seen = {}
|
||||
result = []
|
||||
for item in seq:
|
||||
marker = idfun(item)
|
||||
if marker in seen: continue
|
||||
seen[marker] = 1
|
||||
result.append(item)
|
||||
return result
|
||||
|
||||
def source_list(src, globby='*.js'):
|
||||
def expander(f):
|
||||
return expand(f,globby)
|
||||
return unique(flatten(map(expander, src)))
|
||||
|
||||
def compile(code):
|
||||
params = urllib.urlencode([
|
||||
('js_code', code),
|
||||
('compilation_level', options.level),
|
||||
('output_format', 'text'),
|
||||
('output_info', 'compiled_code'),
|
||||
])
|
||||
headers = { 'Content-type': 'application/x-www-form-urlencoded' }
|
||||
conn = httplib.HTTPConnection('closure-compiler.appspot.com')
|
||||
conn.request('POST', '/compile', params, headers)
|
||||
response = conn.getresponse()
|
||||
data = response.read()
|
||||
conn.close()
|
||||
return data
|
||||
|
||||
def bytes_to_kb(b,digits=1):
|
||||
return round(0.0009765625 * b, digits)
|
||||
|
||||
def clean():
|
||||
if os.path.exists(BUILD_ROOT):
|
||||
shutil.rmtree(BUILD_ROOT)
|
||||
print('DONE. Removed %s'%(BUILD_ROOT,))
|
||||
else:
|
||||
print('DONE. Nothing to clean')
|
||||
|
||||
def build(jssrc, csssrc=list([''])):
|
||||
if not os.path.exists(BUILD_ROOT):
|
||||
os.makedirs(BUILD_ROOT)
|
||||
|
||||
if csssrc:
|
||||
cssfiles = source_list(csssrc, '*.css')
|
||||
print('CSS files being compiled: ', cssfiles)
|
||||
css = '\n'.join([open(f).read() for f in cssfiles])
|
||||
css = re.sub(r'[ \t\n\r]+',' ',css)
|
||||
|
||||
jsfiles = source_list(jssrc, '*.js')
|
||||
print('JS files being compiled: ', jsfiles)
|
||||
code = '\n'.join([open(f).read() for f in jsfiles])
|
||||
if csssrc:
|
||||
code += """DAT.GUI.inlineCSS = '%s';\n"""%(css,)
|
||||
|
||||
outpath = os.path.join(BUILD_ROOT, BUILD_NAME+'.js')
|
||||
with open(outpath,'w') as f:
|
||||
f.write(LICENSE)
|
||||
f.write(code)
|
||||
|
||||
compiled = compile(code)
|
||||
outpathmin = os.path.join(BUILD_ROOT, BUILD_NAME+'.min.js')
|
||||
with open(outpathmin,'w') as f:
|
||||
f.write(LICENSE)
|
||||
f.write(compiled)
|
||||
|
||||
size = bytes_to_kb(os.path.getsize(outpath))
|
||||
sizemin = bytes_to_kb(os.path.getsize(outpathmin))
|
||||
with open(INDEX,'r') as f:
|
||||
index = f.read()
|
||||
with open(INDEX,'w') as f:
|
||||
index = re.sub(r'<small id=\'buildsize\'>\[[0-9.]+kb\]','<small id=\'buildsize\'>[%skb]'%(size,),index)
|
||||
index = re.sub(r'<small id=\'buildsizemin\'>\[[0-9.]+kb\]','<small id=\'buildsizemin\'>[%skb]'%(sizemin,),index)
|
||||
f.write(index)
|
||||
|
||||
print('DONE. Built files in %s.'%(BUILD_ROOT,))
|
||||
|
||||
def debug(jssrc, csssrc=list([''])):
|
||||
head = ""
|
||||
files = source_list(csssrc, '*.css')
|
||||
for f in files:
|
||||
f = f.replace(PREFIX+'/','')
|
||||
head += '<link href="%s" media="screen" rel="stylesheet" type="text/css"/>\n'%(f,)
|
||||
files = source_list(jssrc, '*.js')
|
||||
for f in files:
|
||||
f = f.replace(PREFIX+'/','')
|
||||
head += '<script type="text/javascript" src="%s"></script>\n'%(f,)
|
||||
print(head)
|
||||
|
||||
if __name__ == '__main__':
|
||||
global options
|
||||
(options, args) = parser.parse_args()
|
||||
if len(args) != 1:
|
||||
print(parser.usage)
|
||||
exit(0)
|
||||
command = args[0]
|
||||
if command == 'build':
|
||||
build(ALL_JS)
|
||||
elif command == 'clean':
|
||||
clean()
|
||||
elif command == 'debug':
|
||||
debug(ALL_JS)
|
||||
|
||||
|
8
utils/build_color.js
Normal file
8
utils/build_color.js
Normal file
@ -0,0 +1,8 @@
|
||||
require('./builder.js').build({
|
||||
"baseUrl": "../src/",
|
||||
"main": "dat/color/Color",
|
||||
"out": "../build/dat.color.js",
|
||||
"minify": false,
|
||||
"shortcut": "dat.Color",
|
||||
"paths": {}
|
||||
});
|
8
utils/build_gui.js
Normal file
8
utils/build_gui.js
Normal file
@ -0,0 +1,8 @@
|
||||
require('./builder.js').build({
|
||||
"baseUrl": "../src/",
|
||||
"main": "dat/gui/GUI",
|
||||
"out": "../build/dat.gui.js",
|
||||
"minify": false,
|
||||
"shortcut": "dat.GUI",
|
||||
"paths": {}
|
||||
});
|
284
utils/builder.js
Normal file
284
utils/builder.js
Normal file
@ -0,0 +1,284 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
var fs = require('fs'),
|
||||
closure = require('./closure'),
|
||||
params,
|
||||
defined,
|
||||
third_party,
|
||||
request_counts,
|
||||
namespaces,
|
||||
next_load = '',
|
||||
next_path = '';
|
||||
|
||||
exports.build = build;
|
||||
exports.file_exists = file_exists;
|
||||
exports.read_file = read_file;
|
||||
exports.tab = tab;
|
||||
|
||||
exports.license = read_file('license.txt');
|
||||
|
||||
function build(_params) {
|
||||
|
||||
params = _params;
|
||||
|
||||
defined = {};
|
||||
third_party = {};
|
||||
request_counts = {};
|
||||
namespaces = {};
|
||||
|
||||
var deps = [];
|
||||
|
||||
load_module(params.baseUrl + params.main + '.js', params.main);
|
||||
|
||||
for (var i in defined) {
|
||||
if (params.verbose) console.log('Loaded: ' + defined[i].path);
|
||||
deps.push(defined[i].path);
|
||||
if (defined[i].module) {
|
||||
var namespace = i.substr(0, i.lastIndexOf('/'));
|
||||
namespaces[namespace] = true;
|
||||
}
|
||||
}
|
||||
|
||||
var to_write = '';
|
||||
var ensured = {};
|
||||
|
||||
|
||||
for (var name in params.paths) {
|
||||
var path = params.baseUrl + params.paths[name] + '.js';
|
||||
var str = read_file(path);
|
||||
if (str === false) {
|
||||
console.log('Failed to locate dependency \'' + name + '\' at ' + path);
|
||||
fail();
|
||||
}
|
||||
third_party[name] = str;
|
||||
to_write += third_party[name] + "\n\n";
|
||||
if (params.verbose) console.log('Loaded: ' + path);
|
||||
//deps.push(path);
|
||||
}
|
||||
|
||||
// Ensure namespaces
|
||||
for (i in namespaces) {
|
||||
|
||||
var split = i.split('/');
|
||||
|
||||
for (var j = 0; j < split.length; j++) {
|
||||
var cur = [];
|
||||
if (j == 0 && !ensured[split[j]]) {
|
||||
to_write += '/** @namespace */\n';
|
||||
to_write += 'var ' + split[j] + ' = ' + split[j] + ' || {};\n\n';
|
||||
ensured[split[j]] = true;
|
||||
} else {
|
||||
for (var k = 0; k <= j; k++) {
|
||||
cur.push(split[k]);
|
||||
}
|
||||
var curn = cur.join('.');
|
||||
if (!ensured[curn]) {
|
||||
to_write += '/** @namespace */\n';
|
||||
to_write += curn + ' = ' + curn + ' || {};\n\n';
|
||||
}
|
||||
ensured[curn] = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var shared_count = 0;
|
||||
for (i in request_counts) {
|
||||
var count = request_counts[i];
|
||||
if (count > 1) {
|
||||
if (i in defined) {
|
||||
var new_shared = i.replace(/\//g, '.');
|
||||
var v = new_shared + ' = ' + defined[i].getClosure() + ';\n';
|
||||
to_write += v + "\n\n";
|
||||
defined[i].shared = new_shared;
|
||||
shared_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
to_write += params.shortcut + ' = ' + params.main.replace(/\//g, '.') + ' = ' + defined[params.main].getClosure() + ';';
|
||||
|
||||
if (params.verbose) console.log('Exported: ' + params.main + ' to window.' + params.shortcut);
|
||||
|
||||
if (params.minify) {
|
||||
|
||||
console.log('Compiling minified source ...');
|
||||
|
||||
|
||||
closure.compile(to_write, function(error, code) {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
} else {
|
||||
write(exports.license + code);
|
||||
}
|
||||
if (params.on_compile) {
|
||||
params.on_compile();
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
write(exports.license + "\n" + to_write);
|
||||
|
||||
}
|
||||
|
||||
return deps;
|
||||
|
||||
}
|
||||
|
||||
function define(deps, callback) {
|
||||
|
||||
this.name = next_load;
|
||||
this.path = next_path;
|
||||
this.shared = false;
|
||||
|
||||
defined[this.name] = this;
|
||||
|
||||
if (Array.isArray(deps)) {
|
||||
|
||||
this.deps = deps;
|
||||
this.callback = callback.toString();
|
||||
this.module = true;
|
||||
|
||||
// Simple define call, just an object
|
||||
} else if (typeof deps === 'object') {
|
||||
|
||||
var props = [];
|
||||
for (var i in deps) {
|
||||
props.push(i + ':' + deps[i].toString())
|
||||
}
|
||||
this.callback = '{' + props.join(',') + '}';
|
||||
this.module = true;
|
||||
|
||||
} else {
|
||||
|
||||
this.deps = deps;
|
||||
this.callback = callback;
|
||||
|
||||
}
|
||||
|
||||
this.getClosure = function() {
|
||||
if (this.shared) return this.shared;
|
||||
if (!this.deps || this.text) return this.callback;
|
||||
var arg_string = '(';
|
||||
var args = [];
|
||||
for (var i in this.deps) {
|
||||
var dep = this.deps[i];
|
||||
if (dep in defined) {
|
||||
var closure = defined[dep].getClosure();
|
||||
if (!defined[dep].shared && !defined[dep].text) {
|
||||
closure = defined[dep].name.replace(/\//g, '.') + ' = ' + closure;
|
||||
}
|
||||
args.push(closure);
|
||||
}
|
||||
}
|
||||
arg_string += args.join(',\n');
|
||||
arg_string += ')';
|
||||
return '(' + this.callback + ')' + arg_string;
|
||||
|
||||
};
|
||||
|
||||
this.recurseDeps = function() {
|
||||
|
||||
if (!this.deps) return;
|
||||
|
||||
for (var i in this.deps) {
|
||||
|
||||
var dep = this.deps[i];
|
||||
|
||||
if (dep in params.paths) continue;
|
||||
|
||||
var path = params.baseUrl + dep;
|
||||
|
||||
// Define module?
|
||||
if (file_exists(path + '.js')) {
|
||||
load_module(path + '.js', dep);
|
||||
|
||||
// Text module?
|
||||
} else if (path.match(/text!/) != null) {
|
||||
load_text(path.replace('text!', ''), dep);
|
||||
}
|
||||
|
||||
// up the request count
|
||||
if (dep in request_counts) {
|
||||
request_counts[dep]++
|
||||
} else {
|
||||
request_counts[dep] = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.recurseDeps();
|
||||
|
||||
}
|
||||
|
||||
function file_exists(path) {
|
||||
try {
|
||||
var stats = fs.lstatSync(path)
|
||||
return stats.isFile();
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function read_file(path) {
|
||||
try {
|
||||
return fs.readFileSync(path).toString();
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function load_module(path, name) {
|
||||
name = name || path;
|
||||
if (name in defined) return;
|
||||
next_load = name;
|
||||
next_path = path;
|
||||
eval('new ' + read_file(path));
|
||||
}
|
||||
|
||||
function load_text(path, name) {
|
||||
name = name || path;
|
||||
if (name in defined) return;
|
||||
var text = read_file(path);
|
||||
text = text.replace(/\r/g, "\\r");
|
||||
text = text.replace(/\n/g, "\\n");
|
||||
text = text.replace(/"/g, "\\\"");
|
||||
next_load = name;
|
||||
next_path = path;
|
||||
var d = new define([], '"' + text + '"');
|
||||
d.text = true;
|
||||
d.module = false;
|
||||
}
|
||||
|
||||
function tab(str, tabs) {
|
||||
var lines = str.split("\n");
|
||||
for (var i in lines) {
|
||||
lines[i] = tabs + lines[i];
|
||||
}
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
||||
function write(str) {
|
||||
fs.writeFile(params.out, str);
|
||||
console.log('Saved to ' + params.out);
|
||||
}
|
||||
|
||||
function fail() {
|
||||
console.log('Build failed.');
|
||||
process.exit(0);
|
||||
}
|
108
utils/closure.js
Normal file
108
utils/closure.js
Normal file
@ -0,0 +1,108 @@
|
||||
/// # Google Closure Compiler Service #
|
||||
/// https://github.com/weaver/scribbles/blob/master/node/google-closure/lib/closure.js
|
||||
/// Compress javascript with Node.js using the Closure Compiler
|
||||
/// Service.
|
||||
|
||||
var sys = require('sys');
|
||||
|
||||
exports.compile = compile;
|
||||
|
||||
// Use the Google Closure Compiler Service to compress Javascript
|
||||
// code.
|
||||
//
|
||||
// + code - String of javascript to compress
|
||||
// + next - Function callback that accepts.
|
||||
//
|
||||
// This method will POST the `code` to the compiler service. If an
|
||||
// error occurs, `next()` will be called with an `Error` object as the
|
||||
// first argument. Otherwise, the `next()` will be called with `null`
|
||||
// as the first argument and a String of compressed javascript as the
|
||||
// second argument.
|
||||
//
|
||||
// compile('... javascript ...', function(err, result) {
|
||||
// if (err) throw err;
|
||||
//
|
||||
// ... do something with result ...
|
||||
// });
|
||||
//
|
||||
// Returns nothing.
|
||||
function compile(code, next) {
|
||||
try {
|
||||
var qs = require('querystring'),
|
||||
http = require('http'),
|
||||
host = 'closure-compiler.appspot.com',
|
||||
body = qs.stringify({
|
||||
js_code: code.toString('utf-8'),
|
||||
compilation_level: 'SIMPLE_OPTIMIZATIONS',
|
||||
output_format: 'json',
|
||||
output_info: 'compiled_code'
|
||||
}),
|
||||
client = http.createClient(80, host).on('error', next),
|
||||
req = client.request('POST', '/compile', {
|
||||
'Host': host,
|
||||
'Content-Length': body.length,
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
});
|
||||
|
||||
req.on('error', next).end(body);
|
||||
|
||||
req.on('response', function(res) {
|
||||
if (res.statusCode != 200)
|
||||
next(new Error('Unexpected HTTP response: ' + res.statusCode));
|
||||
else
|
||||
capture(res, 'utf-8', parseResponse);
|
||||
});
|
||||
|
||||
function parseResponse(err, data) {
|
||||
err ? next(err) : loadJSON(data, function(err, obj) {
|
||||
var error;
|
||||
if (err)
|
||||
next(err);
|
||||
else if ((error = obj.errors || obj.serverErrors || obj.warnings))
|
||||
next(new Error('Failed to compile: ' + sys.inspect(error)));
|
||||
else
|
||||
next(null, obj.compiledCode);
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert a Stream to a String.
|
||||
//
|
||||
// + input - Stream object
|
||||
// + encoding - String input encoding
|
||||
// + next - Function error/success callback
|
||||
//
|
||||
// Returns nothing.
|
||||
function capture(input, encoding, next) {
|
||||
var buffer = '';
|
||||
|
||||
input.on('data', function(chunk) {
|
||||
buffer += chunk.toString(encoding);
|
||||
});
|
||||
|
||||
input.on('end', function() {
|
||||
next(null, buffer);
|
||||
});
|
||||
|
||||
input.on('error', next);
|
||||
}
|
||||
|
||||
// Convert JSON.load() to callback-style.
|
||||
//
|
||||
// + data - String value to load
|
||||
// + next - Function error/success callback
|
||||
//
|
||||
// Returns nothing.
|
||||
function loadJSON(data, next) {
|
||||
var err, obj;
|
||||
|
||||
try {
|
||||
obj = JSON.parse(data);
|
||||
} catch (x) {
|
||||
err = x;
|
||||
}
|
||||
next(err, obj);
|
||||
}
|
12
utils/license.txt
Normal file
12
utils/license.txt
Normal file
@ -0,0 +1,12 @@
|
||||
/**
|
||||
* dat-gui JavaScript Controller Library
|
||||
* http://code.google.com/p/dat-gui
|
||||
*
|
||||
* Copyright 2011 Data Arts Team, Google Creative Lab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
Loading…
Reference in New Issue
Block a user