Better keyframes.

This commit is contained in:
George Michael Brower 2011-02-08 10:40:38 -05:00
parent 046ef1e1c8
commit f96b1f2e9a
9 changed files with 531 additions and 119 deletions

View File

@ -44,8 +44,10 @@ GUI.Controller.prototype.unlisten = function() {
} }
GUI.Controller.prototype.setValue = function(n) { GUI.Controller.prototype.setValue = function(n) {
this.object[this.propertyName] = n; this.object[this.propertyName] = n;
for (var i in this.changeListeners) { for (var i in this.changeListeners) {
console.log("Telling you I changed to " + n);
this.changeListeners[i].call(this, n); this.changeListeners[i].call(this, n);
} }
// Whenever you call setValue, the display will be updated automatically. // Whenever you call setValue, the display will be updated automatically.

View File

@ -13,8 +13,8 @@ GUI.StringController = function() {
input.setAttribute('spellcheck', 'false'); input.setAttribute('spellcheck', 'false');
this.domElement.addEventListener('mouseup', function() { this.domElement.addEventListener('mouseup', function() {
input.focus(); //input.focus();
input.select(); //input.select();
}, false); }, false);
// TODO: getting messed up on ctrl a // TODO: getting messed up on ctrl a

View File

@ -17,6 +17,7 @@ h1, h2, h3, h4, h5, h6 {
color: #222; color: #222;
} }
hr { hr {
border: 0; border: 0;
height: 0; height: 0;

View File

@ -44,8 +44,8 @@ function FizzyText(message) {
var width = 550; var width = 550;
var height = 200; var height = 200;
var textAscent = 82; var textAscent = 140;
var textOffsetLeft = 80; var textOffsetLeft = 20;
var noiseScale = 300; var noiseScale = 300;
var frameTime = 30; var frameTime = 30;

1
gui.js
View File

@ -365,6 +365,7 @@ var GUI = function() {
for (var i in controllers) { for (var i in controllers) {
controllerHeight += controllers[i].domElement.offsetHeight; controllerHeight += controllers[i].domElement.offsetHeight;
} }
return;
if (controllerHeight - 1 > openHeight) { if (controllerHeight - 1 > openHeight) {
controllerContainer.style.overflowY = "auto"; controllerContainer.style.overflowY = "auto";
} else { } else {

View File

@ -33,13 +33,13 @@
</script> </script>
<script type="text/javascript"> <script type="text/javascript">
//<![CDATA[ //<![CDATA[
var timer;
window.onload = function() { window.onload = function() {
var fizzyText = new FizzyText("gui-dat"); var fizzyText = new FizzyText("gui-dat");
var gui = new GUI(); var gui = new GUI();
var timer = new GUI.Timer(gui); timer = new GUI.Timer(gui);
// Text field // Text field
@ -71,7 +71,9 @@
gui.divider(); gui.divider();
// gui.add(timer, "playhead").step(100).listen(); // gui.add(timer, "playhead").step(100).listen();
gui.add(timer, "playPause"); // gui.add(timer, "playPause");
gui.add(timer, "snapIncrement");
gui.add(timer, "useSnap");
/* /*
gui.add(timer, "windowMin").listen(); gui.add(timer, "windowMin").listen();
gui.add(timer, "windowWidth").listen(); gui.add(timer, "windowWidth").listen();

249
time/easing.js Normal file
View File

@ -0,0 +1,249 @@
TWEEN.Easing = { Linear: {}, Quadratic: {}, Cubic: {}, Quartic: {}, Quintic: {}, Sinusoidal: {}, Exponential: {}, Circular: {}, Elastic: {}, Back: {}, Bounce: {} };
TWEEN.Easing.Linear.EaseNone = function ( k ) {
return k;
};
//
TWEEN.Easing.Quadratic.EaseIn = function ( k ) {
return k * k;
};
TWEEN.Easing.Quadratic.EaseOut = function ( k ) {
return - k * ( k - 2 );
};
TWEEN.Easing.Quadratic.EaseInOut = function ( k ) {
if ( ( k *= 2 ) < 1 ) return 0.5 * k * k;
return - 0.5 * ( --k * ( k - 2 ) - 1 );
};
//
TWEEN.Easing.Cubic.EaseIn = function ( k ) {
return k * k * k;
};
TWEEN.Easing.Cubic.EaseOut = function ( k ) {
return --k * k * k + 1;
};
TWEEN.Easing.Cubic.EaseInOut = function ( k ) {
if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k;
return 0.5 * ( ( k -= 2 ) * k * k + 2 );
};
//
TWEEN.Easing.Quartic.EaseIn = function ( k ) {
return k * k * k * k;
};
TWEEN.Easing.Quartic.EaseOut = function ( k ) {
return - ( --k * k * k * k - 1 );
}
TWEEN.Easing.Quartic.EaseInOut = function ( k ) {
if ( ( k *= 2 ) < 1) return 0.5 * k * k * k * k;
return - 0.5 * ( ( k -= 2 ) * k * k * k - 2 );
};
//
TWEEN.Easing.Quintic.EaseIn = function ( k ) {
return k * k * k * k * k;
};
TWEEN.Easing.Quintic.EaseOut = function ( k ) {
return ( k = k - 1 ) * k * k * k * k + 1;
};
TWEEN.Easing.Quintic.EaseInOut = function ( k ) {
if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k * k * k;
return 0.5 * ( ( k -= 2 ) * k * k * k * k + 2 );
};
//
TWEEN.Easing.Sinusoidal.EaseIn = function ( k ) {
return - Math.cos( k * Math.PI / 2 ) + 1;
};
TWEEN.Easing.Sinusoidal.EaseOut = function ( k ) {
return Math.sin( k * Math.PI / 2 );
};
TWEEN.Easing.Sinusoidal.EaseInOut = function ( k ) {
return - 0.5 * ( Math.cos( Math.PI * k ) - 1 );
};
//
TWEEN.Easing.Exponential.EaseIn = function ( k ) {
return k == 0 ? 0 : Math.pow( 2, 10 * ( k - 1 ) );
};
TWEEN.Easing.Exponential.EaseOut = function ( k ) {
return k == 1 ? 1 : - Math.pow( 2, - 10 * k ) + 1;
};
TWEEN.Easing.Exponential.EaseInOut = function ( k ) {
if ( k == 0 ) return 0;
if ( k == 1 ) return 1;
if ( ( k *= 2 ) < 1 ) return 0.5 * Math.pow( 2, 10 * ( k - 1 ) );
return 0.5 * ( - Math.pow( 2, - 10 * ( k - 1 ) ) + 2 );
};
//
TWEEN.Easing.Circular.EaseIn = function ( k ) {
return - ( Math.sqrt( 1 - k * k ) - 1);
};
TWEEN.Easing.Circular.EaseOut = function ( k ) {
return Math.sqrt( 1 - --k * k );
};
TWEEN.Easing.Circular.EaseInOut = function ( k ) {
if ( ( k /= 0.5 ) < 1) return - 0.5 * ( Math.sqrt( 1 - k * k) - 1);
return 0.5 * ( Math.sqrt( 1 - ( k -= 2) * k) + 1);
};
//
TWEEN.Easing.Elastic.EaseIn = function( k ) {
var s, a = 0.1, p = 0.4;
if ( k == 0 ) return 0; if ( k == 1 ) return 1; if ( !p ) p = 0.3;
if ( !a || a < 1 ) { a = 1; s = p / 4; }
else s = p / ( 2 * Math.PI ) * Math.asin( 1 / a );
return - ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) );
};
TWEEN.Easing.Elastic.EaseOut = function( k ) {
var s, a = 0.1, p = 0.4;
if ( k == 0 ) return 0; if ( k == 1 ) return 1; if ( !p ) p = 0.3;
if ( !a || a < 1 ) { a = 1; s = p / 4; }
else s = p / ( 2 * Math.PI ) * Math.asin( 1 / a );
return ( a * Math.pow( 2, - 10 * k) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) + 1 );
};
TWEEN.Easing.Elastic.EaseInOut = function( k ) {
var s, a = 0.1, p = 0.4;
if ( k == 0 ) return 0; if ( k == 1 ) return 1; if ( !p ) p = 0.3;
if ( !a || a < 1 ) { a = 1; s = p / 4; }
else s = p / ( 2 * Math.PI ) * Math.asin( 1 / a );
if ( ( k *= 2 ) < 1 ) return - 0.5 * ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) );
return a * Math.pow( 2, -10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) * 0.5 + 1;
};
//
TWEEN.Easing.Back.EaseIn = function( k ) {
var s = 1.70158;
return k * k * ( ( s + 1 ) * k - s );
};
TWEEN.Easing.Back.EaseOut = function( k ) {
var s = 1.70158;
return ( k = k - 1 ) * k * ( ( s + 1 ) * k + s ) + 1;
};
TWEEN.Easing.Back.EaseInOut = function( k ) {
var s = 1.70158 * 1.525;
if ( ( k *= 2 ) < 1 ) return 0.5 * ( k * k * ( ( s + 1 ) * k - s ) );
return 0.5 * ( ( k -= 2 ) * k * ( ( s + 1 ) * k + s ) + 2 );
};
//
TWEEN.Easing.Bounce.EaseIn = function( k ) {
return 1 - TWEEN.Easing.Bounce.EaseOut( 1 - k );
};
TWEEN.Easing.Bounce.EaseOut = function( k ) {
if ( ( k /= 1 ) < ( 1 / 2.75 ) ) {
return 7.5625 * k * k;
} else if ( k < ( 2 / 2.75 ) ) {
return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75;
} else if ( k < ( 2.5 / 2.75 ) ) {
return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375;
} else {
return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375;
}
};
TWEEN.Easing.Bounce.EaseInOut = function( k ) {
if ( k < 0.5 ) return TWEEN.Easing.Bounce.EaseIn( k * 2 ) * 0.5;
return TWEEN.Easing.Bounce.EaseOut( k * 2 - 1 ) * 0.5 + 0.5;
};

View File

@ -1,6 +1,5 @@
// Would really love to make it so that as FEW changes as possible are required to gui.js in order to make this work. Would love to make it so you simply include gui.scrubber.min.js in addition to gui.min.js.
GUI.Controller.prototype.at = function(when, what, tween) { GUI.Controller.prototype.at = function(when, what, tween) {
// TODO: tween
this.scrubber.add(new GUI.ScrubberPoint(this.scrubber, when, what)); this.scrubber.add(new GUI.ScrubberPoint(this.scrubber, when, what));
this.scrubber.render(); this.scrubber.render();
return this; return this;
@ -12,32 +11,54 @@ GUI.Scrubber = function(controller, timer) {
this.points = []; this.points = [];
this.timer = timer; this.timer = timer;
this.timer.scrubbers.push(this);
this.controller = controller; this.controller = controller;
this.controller.scrubber = this; this.controller.scrubber = this;
this.playing = false; this.playing = false;
var previouslyHandled;
this.getSaveObject = function() {
var pointArray = [];
for (var i in this.points) {
pointArray.push(this.points[i].getSaveObject());
}
var obj = {'points': pointArray};
return obj;
};
this.sort = function() { this.sort = function() {
this.points.sort(function(a,b) { this.points.sort(function(a,b) {
return a.time - b.time; return a.time - b.time;
}); });
} };
this.add = function(p) { this.add = function(p) {
this.points.push(p); this.points.push(p);
this.getSaveObject();
this.sort(); this.sort();
} };
var lastDown = 0; var lastDown = 0;
this.controller.addChangeListener(function(newVal) { this.controller.addChangeListener(function(newVal) {
if (!_this.playing) { if (!_this.playing) {
var v = newVal;
if (_this.controller.type == "boolean") {
v = !v; // Couldn't tell you why I have to do this.
}
if (_this.timer.activePoint == null) { if (_this.timer.activePoint == null) {
_this.timer.activePoint = new GUI.ScrubberPoint(_this, _this.timer.playhead, newVal);
_this.timer.activePoint = new GUI.ScrubberPoint(_this, _this.timer.playhead, v);
_this.add(_this.timer.activePoint); _this.add(_this.timer.activePoint);
_this.render(); _this.render();
} else { } else {
_this.timer.activePoint.value = newVal; _this.timer.activePoint.value = v;
} }
} }
@ -57,11 +78,11 @@ GUI.Scrubber = function(controller, timer) {
var mx, pmx; var mx, pmx;
this.__defineGetter__("width", function() { this.__defineGetter__('width', function() {
return width; return width;
}); });
this.__defineGetter__("height", function() { this.__defineGetter__('height', function() {
return height; return height;
}); });
@ -70,15 +91,43 @@ GUI.Scrubber = function(controller, timer) {
this.render = function() { this.render = function() {
// TODO: if visible ... // TODO: if visible ...
_this.g.clearRect(0, 0, width, height); _this.g.clearRect(0, 0, width, height);
// Draw 0
if (_this.timer.windowMin < 0) {
var x = GUI.map(0, _this.timer.windowMin, _this.timer.windowMin+_this.timer.windowWidth, 0, width);
_this.g.fillStyle = '#000';
_this.g.fillRect(0, 0, x, height-1);
}
// Draw ticks
if (_this.timer.useSnap) {
_this.g.lineWidth = 1;
for (var i = _this.timer.snap(_this.timer.windowMin); i < _this.timer.windowMin+_this.timer.windowWidth; i+= _this.timer.snapIncrement) {
if (i == 0) continue;
var x = Math.round(GUI.map(i, _this.timer.windowMin, _this.timer.windowMin+_this.timer.windowWidth, 0, width))+0.5;
if (i < 0) {
_this.g.strokeStyle = '#111111';
} else {
_this.g.strokeStyle = '#282828';
}
_this.g.beginPath();
_this.g.moveTo(x, 0);
_this.g.lineTo(x, height-1);
_this.g.stroke();
}
}
// Draw points
for (var i in _this.points) { for (var i in _this.points) {
_this.points[i].render(); _this.points[i].render();
} }
// Draw playhead // Draw playhead
_this.g.strokeStyle = "#ff0024"; _this.g.strokeStyle = '#ff0024';
_this.g.lineWidth = 1; _this.g.lineWidth = 1;
var t = Math.round(GUI.map(_this.timer.playhead, _this.timer.windowMin, _this.timer.windowMin+_this.timer.windowWidth, 0, width))+0.5; var t = Math.round(GUI.map(_this.timer.playhead, _this.timer.windowMin, _this.timer.windowMin+_this.timer.windowWidth, 0, width))+0.5;
_this.g.beginPath(); _this.g.beginPath();
@ -90,8 +139,6 @@ GUI.Scrubber = function(controller, timer) {
this.render(); this.render();
var onResize = function() { var onResize = function() {
canvas.width = width = _this.domElement.offsetWidth; canvas.width = width = _this.domElement.offsetWidth;
canvas.height = height = _this.domElement.offsetHeight; canvas.height = height = _this.domElement.offsetHeight;
@ -120,51 +167,64 @@ GUI.Scrubber = function(controller, timer) {
} }
} }
var scrub = function(e) { var scrub = function(e) {
var t = GUI.map(e.pageX, position.left, position.left+width, _this.timer.windowMin, _this.timer.windowMin+_this.timer.windowWidth); var t = GUI.map(e.pageX, position.left, position.left+width, _this.timer.windowMin, _this.timer.windowMin+_this.timer.windowWidth);
_this.timer.playhead = _this.timer.snap(t);
_this.timer.playhead = t;
scrubPan(); scrubPan();
}
var pan = function(e) {
mx = e.pageX;
var t = GUI.map(mx - pmx, 0, width, 0, _this.timer.windowWidth);
_this.timer.windowMin -= t;
pmx = mx;
} }
var dragActive = function(e) { var dragActive = function(e) {
mx = e.pageX; var t = GUI.map(e.pageX, position.left, position.left+width, _this.timer.windowMin, _this.timer.windowMin+_this.timer.windowWidth);
var t = GUI.map(mx - pmx, 0, width, 0, _this.timer.windowWidth); _this.timer.activePoint.time = _this.timer.snap(t);
_this.timer.activePoint.time += t; _this.timer.playhead = _this.timer.snap(t);
pmx = mx; pmx = mx;
_this.sort(); _this.sort();
_this.timer.playhead += t;
} }
canvas.addEventListener('mousedown', function(e) { canvas.addEventListener('mousedown', function(e) {
if (false) {
e.preventDefault();
document.addEventListener('mousemove', pan, false);
return false;
}
var thisDown = GUI.millis(); var thisDown = GUI.millis();
// Double click creates a keyframe
if (thisDown - lastDown < 300) { if (thisDown - lastDown < 300) {
_this.timer.activePoint = new GUI.ScrubberPoint(_this, _this.timer.playhead, _this.controller.getValue()); _this.timer.activePoint = new GUI.ScrubberPoint(_this, _this.timer.playhead, _this.controller.getValue());
_this.add(_this.timer.activePoint); _this.add(_this.timer.activePoint);
_this.render(); _this.render();
} else if (_this.timer.hoverPoint != null ) { // A regular click COULD select a point ...
} else if (_this.timer.hoverPoint != null) {
_this.timer.activePoint = _this.timer.hoverPoint; _this.timer.activePoint = _this.timer.hoverPoint;
_this.timer.playhead = _this.timer.activePoint.time; _this.timer.playhead = _this.timer.snap(_this.timer.activePoint.time);
pmx = mx = e.pageX;
document.addEventListener("mousemove", dragActive, false);
pmx = mx = e.pageX;
document.addEventListener('mousemove', dragActive, false);
// Or we could just be trying to place the playhead/scrub.
} else { } else {
_this.timer.activePoint = null; _this.timer.activePoint = null;
_this.timer.hoverPoint = null; _this.timer.hoverPoint = null;
scrub(e); scrub(e);
document.body.style.cursor = "text"; document.body.style.cursor = 'text';
_this.timer.pause(); _this.timer.pause();
pmx = mx = e.pageX;
document.addEventListener('mousemove', scrub, false); document.addEventListener('mousemove', scrub, false);
_this.render(); _this.render();
@ -174,6 +234,19 @@ GUI.Scrubber = function(controller, timer) {
}, false); }, false);
canvas.addEventListener('mousewheel', function(e) {
e.preventDefault();
var dx = e.wheelDeltaX*4;
var dy = e.wheelDeltaY*4;
_this.timer.windowWidth -= dy;
_this.timer.windowMin += dy/2 + dx;
return false;
}, false);
canvas.addEventListener('mousemove', function(e) { canvas.addEventListener('mousemove', function(e) {
_this.timer.hoverPoint = null; _this.timer.hoverPoint = null;
for (var i in _this.points) { for (var i in _this.points) {
@ -183,107 +256,112 @@ GUI.Scrubber = function(controller, timer) {
} }
} }
if (_this.timer.hoverPoint == null) { if (_this.timer.hoverPoint == null) {
document.body.style.cursor = "pointer"; document.body.style.cursor = 'pointer';
} else { } else {
document.body.style.cursor = "auto"; document.body.style.cursor = 'auto';
} }
_this.render(); _this.render();
}); });
document.addEventListener('mouseup', function() { document.addEventListener('mouseup', function() {
document.body.style.cursor = "auto"; document.body.style.cursor = 'auto';
document.removeEventListener("mousemove", dragActive, false); document.removeEventListener('mousemove', dragActive, false);
document.removeEventListener('mousemove', scrub, false); document.removeEventListener('mousemove', scrub, false);
document.removeEventListener('mousemove', pan, false);
}, false); }, false);
onResize(); onResize();
this.timer.addPlayListener(this.render); this.timer.addPlayListener(this.render);
var handlePoint = function(point) {
if (point != previouslyHandled) {
previouslyHandled = point;
_this.controller.setValue(point.value);
}
};
var onPlayChange = function(curTime, prevTime) { var onPlayChange = function(curTime, prevTime) {
if (_this.points.length == 0) return;
_this.playing = true; _this.playing = true;
// This assumes a SORTED point array if (_this.controller.type == 'function') {
// And a PROGRESSING/INCREASING/GROWING playhead
if (_this.controller.type == "number" || for (var i = 0; i < _this.points.length; i++) {
_this.controller.type == "string") { var t = _this.points[i].time;
if ((curTime > prevTime && prevTime < t && t < curTime) ||
var closestToLeft = null; (curTime < prevTime && prevTime > t && t > curTime)) {
for (var i = 0; i < _this.points.length; i++) { _this.controller.getValue().call(this);
var cur = _this.points[i]; }
if (cur.time >= curTime && i > 0) {
closestToLeft = _this.points[i-1];
break;
} }
}
if (closestToLeft != null && closestToLeft.time <= curTime &&
_this.controller.type == "number") {
var n = closestToLeft.next;
if (n != null) {
// Interpolate.
var t = GUI.map(curTime, closestToLeft.time, n.time, 0, 1);
t = closestToLeft.tween(t);
var val = GUI.map(t, 0, 1, closestToLeft.value, n.value);
_this.controller.setValue(val);
}
} else if (closestToLeft != null) {
_this.controller.setValue(closestToLeft.value);
}
} else { } else {
var prev = undefined, next = undefined;
// Find "surrounding" points.
for (var i = 0; i < _this.points.length; i++) { for (var i = 0; i < _this.points.length; i++) {
var t = _this.points[i].time;
if (t > curTime) {
var cur = _this.points[i]; if (i == 0) {
if (prevTime < curTime) {
prev = null;
next = _this.points[i];
break;
if (cur.time < prevTime) { } else {
continue;
} prev = _this.points[i-1];
next = _this.points[i];
break;
if (cur.time >= prevTime && cur.time <= curTime) {
pointHandlers[_this.controller.type].call(_this, cur);
} }
} }
} }
if (next == undefined) {
prev = _this.points[_this.points.length-1];
next = null;
}
console.log(next, prev);
if (next != null & prev != null) {
if (_this.controller.type == 'number') {
var t = prev.tween(GUI.map(curTime, prev.time, next.time, 0, 1));
_this.controller.setValue(GUI.map(t, 0, 1, prev.value, next.value));
} else {
handlePoint(prev);
}
} else if (next != null) {
handlePoint(next);
} else if (prev != null) {
handlePoint(prev);
}
} }
_this.playing = false; _this.playing = false;
}; };
var pointHandlers = {
'function': function(point) {
this.controller.getValue().call(this);
},
'boolean': function(point) {
this.controller.setValue(point.value);
},
'string': function(point) {
this.controller.setValue(point.value);
},
}
this.timer.addPlayListener(onPlayChange); this.timer.addPlayListener(onPlayChange);
this.timer.addWindowListener(this.render); this.timer.addWindowListener(this.render);
@ -293,8 +371,6 @@ GUI.Scrubber = function(controller, timer) {
GUI.ScrubberPoint = function(scrubber, time, value) { GUI.ScrubberPoint = function(scrubber, time, value) {
var _this = this; var _this = this;
var g = scrubber.g; var g = scrubber.g;
@ -304,13 +380,37 @@ GUI.ScrubberPoint = function(scrubber, time, value) {
this.hold = false; this.hold = false;
var val;
this.__defineSetter__("value", function(v) {
val = v;
scrubber.render();
});
this.value = value; this.value = value;
this.__defineGetter__("value", function() {
return val;
});
var barSize = 4; var barSize = 4;
var rectSize = 7; var rectSize = 7;
var c1 = "#ffd800"; var c1 = '#ffd800';
var c2 = "#ff9000"; var c2 = '#ff9000';
this.getSaveObject = function() {
var obj = { 'value': _this.value, 'time': time };
if (this.hold) {
obj.hold = true;
}
// TODO: save tweens
return obj;
};
this.tween = function(t) { this.tween = function(t) {
return t; return t;
@ -325,7 +425,7 @@ GUI.ScrubberPoint = function(scrubber, time, value) {
return xx >= x-rectSize/2 && xx <= x+rectSize/2; return xx >= x-rectSize/2 && xx <= x+rectSize/2;
}; };
this.__defineGetter__("next", function() { this.__defineGetter__('next', function() {
if (scrubber.points.length <= 1) { if (scrubber.points.length <= 1) {
return null; return null;
} }
@ -339,10 +439,10 @@ GUI.ScrubberPoint = function(scrubber, time, value) {
}); });
this.__defineGetter__("time", function() { this.__defineGetter__('time', function() {
return time; return time;
}); });
this.__defineSetter__("time", function(s) { this.__defineSetter__('time', function(s) {
time = s; time = s;
}); });
@ -359,16 +459,16 @@ GUI.ScrubberPoint = function(scrubber, time, value) {
y = scrubber.height/2; y = scrubber.height/2;
if (scrubber.timer.activePoint == this) { if (scrubber.timer.activePoint == this) {
g.fillStyle = "#ffd800"; // g.fillStyle = '#ffd800'; //
} else if (scrubber.timer.hoverPoint == this) { } else if (scrubber.timer.hoverPoint == this) {
g.fillStyle = "#999"; g.fillStyle = '#999';
} else { } else {
g.fillStyle = "#ccc"; g.fillStyle = '#ccc';
} }
switch (type) { switch (type) {
case "boolean": case 'boolean':
g.save(); g.save();
@ -393,7 +493,7 @@ GUI.ScrubberPoint = function(scrubber, time, value) {
break; break;
case "number": case 'number':
g.save(); g.save();
var n = this.next; var n = this.next;
@ -402,11 +502,10 @@ GUI.ScrubberPoint = function(scrubber, time, value) {
var nx = GUI.constrain(GUI.map(n.time, timer.windowMin, timer.windowMin+timer.windowWidth, 0, 1)); var nx = GUI.constrain(GUI.map(n.time, timer.windowMin, timer.windowMin+timer.windowWidth, 0, 1));
nx = GUI.constrain(GUI.map(nx, 0, 1, 0, scrubber.width)); nx = GUI.constrain(GUI.map(nx, 0, 1, 0, scrubber.width));
g.lineWidth = rectSize/2 g.lineWidth = rectSize/2
g.strokeStyle="#222"; g.strokeStyle='#222';
g.beginPath(); g.beginPath();
g.moveTo(nx, y); g.moveTo(nx, y);
g.lineTo(x, y); g.lineTo(x, y);

View File

@ -15,6 +15,7 @@ GUI.Timer = function(gui) {
var playhead = 0; var playhead = 0;
var lastPlayhead = 0; var lastPlayhead = 0;
var playListeners = []; var playListeners = [];
var windowListeners = []; var windowListeners = [];
@ -29,6 +30,46 @@ GUI.Timer = function(gui) {
var playing = false; var playing = false;
var snapIncrement = 250;
var useSnap = false;
this.__defineGetter__("useSnap", function() {
return useSnap;
});
this.__defineSetter__("useSnap", function(v) {
useSnap = v;
for (var i in _this.scrubbers) {
_this.scrubbers[i].render();
};
});
this.__defineGetter__("snapIncrement", function() {
return snapIncrement;
});
this.__defineSetter__("snapIncrement", function(v) {
if (snapIncrement > 0) {
snapIncrement = v;
for (var i in _this.scrubbers) {
_this.scrubbers[i].render();
};
}
});
this.snap = function(t) {
if (!this.useSnap) {
return t;
}
var r = Math.round(t/this.snapIncrement)*this.snapIncrement;
return r;
}
this.scrubbers = [];
window.addEventListener("keyup", function(e) { window.addEventListener("keyup", function(e) {
switch (e.keyCode) { switch (e.keyCode) {
case 32: case 32:
@ -44,9 +85,26 @@ GUI.Timer = function(gui) {
} }
break; break;
} }
console.log(e.keyCode);
}, false); }, false);
this.getSaveObject = function() {
var scrubberArr = [];
for (var i in _this.scrubbers) {
scrubberArr.push(_this.scrubbers[i].getSaveObject());
}
var obj = {'windowMin':_this.windowMin,
'windowWidth':_this.windowWidth,
'playhead':_this.playhead,
'snapIncrement': _this.snapIncrement,
'scrubbers': scrubberArr};
return obj;
};
this.__defineGetter__("windowMin", function() { this.__defineGetter__("windowMin", function() {
return windowMin; return windowMin;
}); });