From 3b6827441cd603d81ef31337f9b52187b544d1a8 Mon Sep 17 00:00:00 2001 From: George Michael Brower Date: Wed, 9 Feb 2011 10:27:59 -0800 Subject: [PATCH] Beginnings of easing curves for numbers --- controllers/controller.string.js | 8 ++++ gui.css | 8 ++++ gui.js | 55 +++++++++++++++++++++--- index.html | 5 +-- time/scrubber.js | 73 +++++++++++++++++++++++--------- time/timer.js | 50 ++++++++++++++++------ 6 files changed, 156 insertions(+), 43 deletions(-) diff --git a/controllers/controller.string.js b/controllers/controller.string.js index 98a03c1..8d379d5 100644 --- a/controllers/controller.string.js +++ b/controllers/controller.string.js @@ -22,6 +22,14 @@ GUI.StringController = function() { _this.setValue(input.value); }, false); + input.addEventListener('focus', function() { + GUI.disableKeyListeners = true; + }, false); + + input.addEventListener('blur', function() { + GUI.disableKeyListeners = false; + }, false); + this.updateDisplay = function() { input.value = _this.getValue(); } diff --git a/gui.css b/gui.css index b464006..9b79876 100644 --- a/gui.css +++ b/gui.css @@ -7,6 +7,14 @@ z-index: 1001; } +.guidat-tween-selector { + z-index: 1001; + position: absolute; + top: 0; + left: 0; + +} + .guidat { float: right; padding: 0px; diff --git a/gui.js b/gui.js index 0c24739..d1b462c 100644 --- a/gui.js +++ b/gui.js @@ -44,7 +44,6 @@ var GUI = function() { var controllerContainer = document.createElement('div'); controllerContainer.setAttribute('class', 'guidat-controllers'); - // Firefox hack to prevent horizontal scrolling controllerContainer.addEventListener('DOMMouseScroll', function(e) { @@ -141,8 +140,8 @@ var GUI = function() { }, false); + // Clears lingering slider column var correctWidth = function() { - // Clears lingering slider column _this.domElement.style.width = (width+1)+'px'; setTimeout(function() { _this.domElement.style.width = width+'px'; @@ -470,22 +469,58 @@ var GUI = function() { controllerContainer.scrollTop = t; }, 0); + // TODO: Check this -- don't really remember writing it. + // Wouldn't it suggest I'm only saving one scrollTop position? if (GUI.scrollTop > -1) { document.body.scrollTop = GUI.scrollTop; } resizeTo = openHeight; this.show(); } - + GUI.guiIndex++; - } + } + + if (GUI.allGuis.length == 0) { + window.addEventListener('keyup', function(e) { + // Hide on "H" + if (e.keyCode == 72) { + GUI.toggleHide(); + } + }, false); + } + GUI.allGuis.push(this); }; // Static members +// Do not set this directly. +GUI.hidden = false; + +GUI.toggleHide = function() { + if (GUI.hidden) { + GUI.show(); + } else { + GUI.hide(); + } +} + +GUI.show = function() { + GUI.hidden = false; + for (var i in GUI.allGuis) { + GUI.allGuis[i].domElement.style.display = "block"; + } +} +GUI.hide = function() { + GUI.hidden = true; + for (var i in GUI.allGuis) { + GUI.allGuis[i].domElement.style.display = "none"; + } +} + GUI.autoPlace = true; GUI.autoPlaceContainer = null; GUI.allControllers = []; @@ -633,13 +668,19 @@ GUI.error = function(str) { } }; -GUI.getOffset = function(obj) { +GUI.getOffset = function(obj, relativeTo) { var curleft = curtop = 0; if (obj.offsetParent) { do { curleft += obj.offsetLeft; curtop += obj.offsetTop; - } while (obj = obj.offsetParent); + + var c = obj = obj.offsetParent; + if (relativeTo) { + c = c && obj != relativeTo; + } + + } while (c); return {left: curleft,top: curtop}; } } @@ -654,4 +695,6 @@ GUI.extendController = function(clazz) { clazz.prototype.constructor = clazz; } +GUI.disableKeyListeners = false; + if (GUI.getVarFromURL('saveString') != null) GUI.load(GUI.getVarFromURL('saveString')); \ No newline at end of file diff --git a/index.html b/index.html index 342c340..b003e29 100644 --- a/index.html +++ b/index.html @@ -73,9 +73,8 @@ gui.add(fizzyText, "explode") .at(1000) .at(2000) - .at(3000); - - + .at(3000) + .at(4000); gui2.add(timer, "playhead").step(125).listen(); gui2.add(timer, "playPause"); diff --git a/time/scrubber.js b/time/scrubber.js index 04bbc22..8fd5432 100644 --- a/time/scrubber.js +++ b/time/scrubber.js @@ -1,6 +1,6 @@ GUI.Controller.prototype.at = function(when, what, tween) { if (!this.scrubber) { - GUI.error("You must create a new Timer for this GUI in order to define events."); + GUI.error('You must create a new Timer for this GUI in order to define events.'); return this; } this.scrubber.add(new GUI.ScrubberPoint(this.scrubber, when, what)); @@ -49,20 +49,22 @@ GUI.Scrubber = function(controller, timer) { this.controller.addChangeListener(function(newVal) { - if (!_this.playing) { + var v = newVal; - if (_this.controller.type == "boolean") { + + if (_this.controller.type == 'boolean') { v = !v; // Couldn't tell you why I have to do this. } + if (_this.timer.activePoint == null) { - _this.timer.activePoint = new GUI.ScrubberPoint(_this, _this.timer.playhead, v); _this.add(_this.timer.activePoint); _this.render(); } else { _this.timer.activePoint.value = v; } + } }); @@ -123,13 +125,15 @@ GUI.Scrubber = function(controller, timer) { } // Draw points + for (var i in _this.points) { + _this.points[i].update(); + } for (var i in _this.points) { _this.points[i].render(); } // Draw playhead - _this.g.strokeStyle = '#ff0024'; _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; @@ -205,7 +209,11 @@ GUI.Scrubber = function(controller, timer) { // Double click creates a keyframe if (thisDown - lastDown < 300) { - _this.timer.activePoint = new GUI.ScrubberPoint(_this, _this.timer.playhead, _this.controller.getValue()); + var val = _this.controller.getValue(); + if (_this.controller.type == 'boolean') { + val = !val; + } + _this.timer.activePoint = new GUI.ScrubberPoint(_this, _this.timer.playhead, val); _this.add(_this.timer.activePoint); _this.render(); @@ -215,9 +223,19 @@ GUI.Scrubber = function(controller, timer) { _this.timer.activePoint = _this.timer.hoverPoint; _this.timer.playhead = _this.timer.snap(_this.timer.activePoint.time); + if (_this.controller.type == 'number') { + var tweenSelectorLeft = (position.left + _this.timer.activePoint.x) - _this.timer.tweenSelector.offsetWidth/2; + var tweenSelectorTop = GUI.getOffset(canvas, _this.timer.gui.domElement).top + _this.timer.activePoint.y - 25; + console.log(position.top, GUI.getOffset(_this.timer.gui.domElement).top, tweenSelectorTop); + _this.timer.tweenSelector.style.left = tweenSelectorLeft+'px'; + _this.timer.tweenSelector.style.top = tweenSelectorTop+'px'; + } + pmx = mx = e.pageX; document.addEventListener('mousemove', dragActive, false); + + // Or we could just be trying to place the playhead/scrub. } else { @@ -303,10 +321,10 @@ GUI.Scrubber = function(controller, timer) { var prev = undefined, next = undefined; - // Find "surrounding" points. + // Find 'surrounding' points. for (var i = 0; i < _this.points.length; i++) { - var t = _this.points[i].time; + var t = _this.points[i].time; if (t > curTime) { @@ -383,22 +401,22 @@ GUI.ScrubberPoint = function(scrubber, time, value) { var val; - this.__defineSetter__("value", function(v) { + this.__defineSetter__('value', function(v) { val = v; scrubber.render(); }); this.value = value; - this.__defineGetter__("value", function() { + this.__defineGetter__('value', function() { return val; }); - this.__defineGetter__("x", function() { + this.__defineGetter__('x', function() { return x; }); - this.__defineGetter__("y", function() { + this.__defineGetter__('y', function() { return y; }); @@ -447,25 +465,36 @@ GUI.ScrubberPoint = function(scrubber, time, value) { this.__defineGetter__('time', function() { return time; }); + this.__defineSetter__('time', function(s) { time = s; }); - this.render = function() { + this.update = function() { x = GUI.map(time, timer.windowMin, timer.windowMin+timer.windowWidth, 0, 1); + x = Math.round(GUI.map(x, 0, 1, 0, scrubber.width)); - if (x >= 0 && x <= 1) { - x = Math.round(GUI.map(x, 0, 1, 0, scrubber.width)); - } else { - return; - } - y = scrubber.height/2; if (scrubber.controller.type == 'number') { y = GUI.map(_this.value, scrubber.controller.min, scrubber.controller.max, scrubber.height, 0); } + + } + + this.render = function() { + + if (x < 0 || x > scrubber.width) { + return; + } + + if (GUI.hidden) { + return; + } + + // TODO: if hidden because of scroll top. + if (scrubber.timer.activePoint == this) { g.fillStyle = '#ffd800'; // @@ -509,7 +538,6 @@ GUI.ScrubberPoint = function(scrubber, time, value) { if (n != null) { - console.log(n.x, n.y); g.lineWidth = rectSize/2; g.strokeStyle='#222'; @@ -544,10 +572,15 @@ GUI.ScrubberPoint = function(scrubber, time, value) { } GUI.Easing = {} + GUI.Easing.Linear = function ( k ) { return k; }; +GUI.Easing.Hold = function(k) { + return 0; +} + GUI.Easing.QuadraticEaseIn = function ( k ) { return k * k; diff --git a/time/timer.js b/time/timer.js index d54144b..529614a 100644 --- a/time/timer.js +++ b/time/timer.js @@ -14,13 +14,33 @@ GUI.Timer = function(gui) { this.gui.timer = this; this.gui.domElement.setAttribute('class', 'guidat time'); - this.gui.domElement.style.width = "100%"; + this.gui.domElement.style.width = '100%'; + // Put toggle button on top. var toggleButton = this.gui.domElement.lastChild; + this.gui.domElement.removeChild(toggleButton); this.gui.domElement.insertBefore(toggleButton, this.gui.domElement.firstChild); + + // Create tween dropdown. + this.tweenSelector = document.createElement('select'); + this.tweenSelector.setAttribute('class', 'guidat-tween-selector'); + for (var i in GUI.Easing) { + var opt = document.createElement('option'); + opt.innerHTML = i; + this.tweenSelector.appendChild(opt); + } + this.tweenSelector.addEventListener('change', function(e) { + alert("CHANGE"); + if (_this.activePoint != null) { + _this.activePoint.tween = GUI.Easing[this.value]; + } + }, false); + this.gui.domElement.appendChild(this.tweenSelector); + + var playhead = 0; var lastPlayhead = 0; @@ -41,22 +61,22 @@ GUI.Timer = function(gui) { var snapIncrement = 250; var useSnap = false; - this.__defineGetter__("useSnap", function() { + this.__defineGetter__('useSnap', function() { return useSnap; }); - this.__defineSetter__("useSnap", function(v) { + this.__defineSetter__('useSnap', function(v) { useSnap = v; for (var i in _this.scrubbers) { _this.scrubbers[i].render(); }; }); - this.__defineGetter__("snapIncrement", function() { + this.__defineGetter__('snapIncrement', function() { return snapIncrement; }); - this.__defineSetter__("snapIncrement", function(v) { + this.__defineSetter__('snapIncrement', function(v) { if (snapIncrement > 0) { snapIncrement = v; for (var i in _this.scrubbers) { @@ -78,7 +98,8 @@ GUI.Timer = function(gui) { this.scrubbers = []; - window.addEventListener("keyup", function(e) { + window.addEventListener('keyup', function(e) { + if (GUI.disableKeyListeners) return; switch (e.keyCode) { case 32: _this.playPause(); @@ -113,34 +134,35 @@ GUI.Timer = function(gui) { }; - this.__defineGetter__("windowMin", function() { + this.__defineGetter__('windowMin', function() { return windowMin; }); - this.__defineSetter__("windowMin", function(v) { + this.__defineSetter__('windowMin', function(v) { windowMin = v; for (var i in windowListeners) { windowListeners[i].call(windowListeners[i]); } }); - this.__defineGetter__("windowWidth", function() { + this.__defineGetter__('windowWidth', function() { return windowWidth; }); - this.__defineSetter__("windowWidth", function(v) { - windowWidth = v; + this.__defineSetter__('windowWidth', function(v) { + // TODO: Make these constants. + windowWidth = GUI.constrain(v, 1000, 60000); for (var i in windowListeners) { windowListeners[i].call(windowListeners[i]); } }); - this.__defineGetter__("playhead", function() { + this.__defineGetter__('playhead', function() { return playhead; }); - this.__defineSetter__("playhead", function(t) { + this.__defineSetter__('playhead', function(t) { lastPlayhead = playhead; playhead = t; if (playing) { @@ -151,7 +173,7 @@ GUI.Timer = function(gui) { } }); - this.__defineGetter__("playing", function() { + this.__defineGetter__('playing', function() { return playing; });