From 9843e5977352bbd62c16cdef04e917b76ca1c29d Mon Sep 17 00:00:00 2001 From: George Michael Brower Date: Sun, 13 Feb 2011 12:23:10 -0500 Subject: [PATCH] I made a composition in gui-dat/time. It is not that good, but you can save and load. --- controllers/controller.js | 1 - demo/demo.js | 62 ++++++++++++++++++++++++--------------- gui.css | 35 ++++++++++++++++++++++ gui.js | 19 +++++++----- index.html | 31 +++++++++++++++----- time/scrubber.js | 27 +++++++++++++++-- time/timer.js | 56 +++++++++++++++++++++++++++-------- 7 files changed, 175 insertions(+), 56 deletions(-) diff --git a/controllers/controller.js b/controllers/controller.js index 7e78ba5..3b79c2e 100644 --- a/controllers/controller.js +++ b/controllers/controller.js @@ -47,7 +47,6 @@ GUI.Controller.prototype.setValue = function(n) { this.object[this.propertyName] = n; for (var i in this.changeListeners) { - console.log("Telling you I changed to " + n); this.changeListeners[i].call(this, n); } // Whenever you call setValue, the display will be updated automatically. diff --git a/demo/demo.js b/demo/demo.js index 4745681..e9a012b 100644 --- a/demo/demo.js +++ b/demo/demo.js @@ -1,9 +1,9 @@ function FizzyText(message) { - var that = this; + var _this = this; - // These are the variables that we manipulate with gui-dat. - // Notice they're all defined with "this". That makes them public. + // These are the variables _this we manipulate with gui-dat. + // Notice they're all defined with "this". _this makes them public. // Otherwise, gui-dat can't see them. this.growthSpeed = 0.5; // how fast do particles change size? @@ -12,8 +12,11 @@ function FizzyText(message) { 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 + this.x = 0; + this.y = 0; + this.scale = 1; + + // __defineGetter__ and __defineSetter__ makes JavaScript believe _this // we've defined a variable 'this.message'. This way, whenever we // change the message variable, we can call some more functions. @@ -42,8 +45,8 @@ function FizzyText(message) { var _this = this; - var width = 550; - var height = 200; + var width, height; + var textAscent = 140; var textOffsetLeft = 20; var noiseScale = 300; @@ -60,10 +63,17 @@ function FizzyText(message) { 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); + var onResize = function() { + r.width = c.width = width = window.innerWidth; + r.height = c.height = height = window.innerHeight; + console.log(width, height); + } + + window.addEventListener('resize', function() { + onResize(); + createBitmap(this.message); + }, false); + onResize(); // Add our demo to the HTML document.getElementById('helvetica-demo').appendChild(c); @@ -76,10 +86,10 @@ function FizzyText(message) { // Set g.font to the same font as the bitmap canvas, incase we // want to draw some outlines. - s.font = g.font = "800 " + textAscent + "px helvetica, arial, sans-serif"; + s.font = g.font = "bold " + textAscent + "px Helvetica, Arial, sans-serif"; // Instantiate some particles - for (var i = 0; i < 1000; i++) { + for (var i = 0; i < 1500; i++) { particles.push(new Particle(Math.random() * width, Math.random() * height)); } @@ -91,7 +101,8 @@ function FizzyText(message) { s.fillRect(0, 0, width, height); s.fillStyle = "#222"; - s.fillText(msg, textOffsetLeft, textAscent); + s.textAlign = 'center'; + s.fillText(msg, width/2, height/2); // Pull reference var imageData = s.getImageData(0, 0, width, height); @@ -102,23 +113,30 @@ function FizzyText(message) { // Called once per frame, updates the animation. var render = function () { - that.framesRendered ++; - - g.clearRect(0, 0, width, height); + _this.framesRendered ++; + g.fillStyle="#000"; + g.fillRect(0, 0, width, height); + g.save(); + g.translate(width/2, height/2); + g.scale(_this.scale, _this.scale); + g.translate(-width/2+_this.x, -height/2+_this.y); + if (_this.displayOutline) { g.globalCompositeOperation = "source-over"; g.strokeStyle = "#000"; g.lineWidth = .5; - g.strokeText(message, textOffsetLeft, textAscent); + g.strokeText(message, textOffsetLeft+width/2, textAscent+height/2); } - g.globalCompositeOperation = "darker"; + g.globalCompositeOperation = "lighter"; for (var i = 0; i < particles.length; i++) { g.fillStyle = colors[i % colors.length]; particles[i].render(); } + + g.restore(); }; @@ -148,11 +166,7 @@ function FizzyText(message) { this.message = message; var loop = function() { - // 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(); - } + render(); } // This calls the render function every 30 milliseconds. diff --git a/gui.css b/gui.css index 9f9f6b8..26a8d4e 100644 --- a/gui.css +++ b/gui.css @@ -31,6 +31,41 @@ height: 31px; } +#guidat-save-dialogue { +z-index: 1001; +-webkit-box-shadow: rgba(0,0,0,0.6) 0px 0px 10px; +position: fixed; +top: 50%; +left: 50%; +background-color: #111; +color: #ccc; +width: 400px; +height: 228px; +margin-top: -114px; +margin-left: -200px; +text-align: center; +padding: 10px; +} + +#guidat-save-dialogue textarea { +margin-top: 9px; +width: 390px; +height: 160px; +font-size: 9px; +border: 0; +font-family: Monaco, monospace; +padding: 5px; +} + +#guidat-save-dialogue a { +display: block; +text-decoration: none; +background-color: rgba(255,255,255,0.1); +border: 1px outset #444; +margin-bottom: 9px; +padding: 5px; +} + .guidat { color: #fff; opacity: 0.97; diff --git a/gui.js b/gui.js index 40de6da..94a6580 100644 --- a/gui.js +++ b/gui.js @@ -7,6 +7,10 @@ var GUI = function() { var json = GUI.loadedJSON.guis.splice(0, 1)[0]; } + this.__defineGetter__("json", function() { + return json; + }); + var _this = this; // For use with GUIScrubber @@ -351,7 +355,7 @@ var GUI = function() { GUI.allControllers.push(controllerObject); // Do we have a saved value for this controller? - if (json.values.length > 0) { + if (json && json.values.length > 0) { var val = json.values.splice(0, 1)[0]; if (type != "function") { controllerObject.setValue(val); @@ -435,7 +439,11 @@ var GUI = function() { values.push(val); } - return {open:open, width:width, openHeight:openHeight, scroll:controllerContainer.scrollTop, values:values} + var obj= {open:open, width:width, openHeight:openHeight, scroll:controllerContainer.scrollTop, values:values} + if (this.timer) { + obj.timer = timer.getJSON(); + } + return obj; } // GUI ... GUI @@ -465,11 +473,6 @@ var GUI = function() { toggleButton.innerHTML = n; } - // used in saveURL - this.appearanceVars = function() { - return [open, width, openHeight, controllerContainer.scrollTop] - } - var beginResize = function() { //console.log("Resizing from " + curControllerContainerHeight + " to " + resizeTo); curControllerContainerHeight += (resizeTo - curControllerContainerHeight)*0.6; @@ -508,7 +511,7 @@ var GUI = function() { } // Add hide listener if this is the first GUI. - if (GUI.allGuis.length == 0) { + if (GUI.allGuis.length == 1) { window.addEventListener('keyup', function(e) { // Hide on "H" if (e.keyCode == 72) { diff --git a/index.html b/index.html index 562e4be..e97d27e 100644 --- a/index.html +++ b/index.html @@ -24,31 +24,48 @@ var timer; window.onload = function() { - GUI.loadJSON('{"guis":[{"open":true,"width":279,"openHeight":95,"scroll":0,"values":["gui-datddd",3.315,0.5841]},{"open":true,"width":283,"openHeight":127,"scroll":0,"values":[1.71,45,true,null]}],"timers":[]}'); - + GUI.loadJSON({"guis":[{"open":true,"width":280,"openHeight":287,"scroll":1,"values":["over time",1.35,8.955,0.9833,1.254,10,false,null,0],"timer":{"windowMin":1687.2598554396586,"windowWidth":11596,"playhead":6413.8663,"snapIncrement":250,"useSnap":false,"scrubbers":[{"points":[{"value":"","time":-961.1787},{"value":"gui-dat","time":197.8981},{"value":"over time","time":5000}]},{"points":[{"value":1.3499999999999999,"time":644.1387}]},{"points":[{"value":0.5,"time":72.8056,"tween":"CircularEaseOut"},{"value":7,"time":659.1556},{"value":7,"time":2211.2348},{"value":5.525,"time":4992.5319},{"value":8.955,"time":6413.8663}]},{"points":[{"value":0.5049,"time":-532.8902,"tween":"Hold"},{"value":0.5544,"time":1666.4321},{"value":0.01,"time":3382.0743,"tween":"Hold"},{"value":0.01,"time":4969.9097},{"value":1,"time":6393.5388}]},{"points":[{"value":0.39899999999999997,"time":1652.5592,"tween":"QuarticEaseIn"},{"value":1.254,"time":3471.5432}]},{"points":[{"value":10,"time":795.5192,"tween":"Hold"},{"value":10,"time":5000}]},{"points":[]},{"points":[]},{"points":[{"value":0,"time":250,"tween":"Hold"}]}]}},{"open":true,"width":280,"openHeight":127,"scroll":0,"values":[null,false,250,null]}]}); var fizzyText = new FizzyText("gui-dat"); var gui = new GUI(); - var gui2 = new GUI(); + var timerControls = new GUI(); + + timer = new GUI.Timer(gui); // Text field gui.add(fizzyText, "message"); + gui.add(fizzyText, "scale", 0.25, 4); + // Sliders with min and max gui.add(fizzyText, "maxSize", 0.5, 7); gui.add(fizzyText, "growthSpeed", 0.01, 1); - gui2.add(fizzyText, "speed", 0.1, 2); + gui.add(fizzyText, "speed", 0.1, 2); // Sliders with min, max and increment. - gui2.add(fizzyText, "noiseStrength", 10, 100, 5); + gui.add(fizzyText, "noiseStrength", 10, 100, 5); // Boolean checkbox - gui2.add(fizzyText, "displayOutline"); + gui.add(fizzyText, "displayOutline"); // Fires a function called "explode" - gui2.add(fizzyText, "explode"); + gui.add(fizzyText, "explode"); + + + timerControls.add(timer, "playPause"); + timerControls.add(timer, "useSnap"); + timerControls.add(timer, "snapIncrement"); + + timerControls.add(GUI, "save"); + + gui.add(fizzyText, 'y', -500, 500); + +GUI.hide(); + timer.playhead = 0; + timer.play(); + }; diff --git a/time/scrubber.js b/time/scrubber.js index f9f2964..fa0ec62 100644 --- a/time/scrubber.js +++ b/time/scrubber.js @@ -2,6 +2,7 @@ GUI.Scrubber = function(controller, timer) { var _this = this; + this.points = []; this.timer = timer; this.timer.scrubbers.push(this); @@ -32,7 +33,6 @@ GUI.Scrubber = function(controller, timer) { this.add = function(p) { this.points.push(p); - this.getJSON(); this.sort(); }; @@ -374,9 +374,22 @@ GUI.Scrubber = function(controller, timer) { }; this.timer.addPlayListener(onPlayChange); - this.timer.addWindowListener(this.render); + // Load saved points!!!! + + if (timer.gui.json) { + var json = timer.gui.json.timer.scrubbers.splice(0, 1)[0]; + for (var i in json.points) { + var p = json.points[i]; + var pp = new GUI.ScrubberPoint(this, p.time, p.value); + if (p.tween) { + pp.tween = GUI.Easing[p.tween]; + } + this.add(pp); + } + } + }; @@ -452,10 +465,18 @@ GUI.ScrubberPoint = function(scrubber, time, value) { } this.getJSON = function() { - var obj = { 'value': _this.value, 'time': time }; + var obj = { 'value': _this.value, 'time': GUI.roundToDecimal(time,4) }; // TODO: save tweens + if (this.tween != GUI.Easing.Linear) { + for (var i in GUI.Easing) { + if (this.tween == GUI.Easing[i]) { + obj.tween = i; + } + } + } + return obj; }; diff --git a/time/timer.js b/time/timer.js index 443460a..9df2058 100644 --- a/time/timer.js +++ b/time/timer.js @@ -4,6 +4,7 @@ GUI.millis = function() { }; GUI.Controller.prototype.at = function(when, what, tween) { + // TODO: Disable if we're using loaded JSON. Don't want to duplicate events. if (!this.scrubber) { GUI.error('You must create a new Timer for this GUI in order to define events.'); return this; @@ -20,28 +21,48 @@ GUI.loadJSON = function(json) { GUI.loadedJSON = json; } - GUI.loadedJSON = null; GUI.getJSON = function() { - var guis = [], timers = []; + var guis = []; for (var i in GUI.allGuis) { guis.push(GUI.allGuis[i].getJSON()); } - for (var i in GUI.allTimers) { - timers.push(GUI.allTimers[i].getJSON()); - } - - var obj = {guis:guis, timers:timers}; - return obj; + var obj = {guis:guis}; + return {guis:guis}; +} + +GUI.save = function() { + + var jsonString = JSON.stringify(GUI.getJSON()); + + var dialogue = document.createElement('div'); + dialogue.setAttribute('id', 'guidat-save-dialogue'); + + var a = document.createElement('a'); + a.setAttribute('href', window.location.href+'?gui='+escape(jsonString)); + a.innerHTML = 'Use this URL.'; + + var span2 = document.createElement('span'); + span2.innerHTML = '… or paste this into the beginning of your source:'; + + var textarea = document.createElement('textarea'); + textarea.setAttribute('disabled', 'true'); + textarea.innerHTML += 'GUI.loadJSON('+jsonString+');'; + + //textarea.select(); + + dialogue.appendChild(a); + dialogue.appendChild(span2); + dialogue.appendChild(textarea); + + document.body.appendChild(dialogue); + } -GUI.allTimers = []; GUI.Timer = function(gui) { - - GUI.allTimers.push(this); - + var _this = this; this.hoverPoint = null; @@ -171,6 +192,7 @@ GUI.Timer = function(gui) { 'windowWidth':_this.windowWidth, 'playhead':_this.playhead, 'snapIncrement': _this.snapIncrement, + 'useSnap': _this.useSnap, 'scrubbers': scrubberArr}; return obj; @@ -261,5 +283,13 @@ GUI.Timer = function(gui) { this.addWindowListener = function(fnc) { windowListeners.push(fnc); }; - + + // Load saved stuff. + if (gui.json && gui.json.timer) { + this.playhead = gui.json.timer.playhead; + this.snapIncrement = gui.json.timer.snapIncrement; + this.useSnap = gui.json.timer.useSnap; + this.windowMin = gui.json.timer.windowMin; + this.windowWidth = gui.json.timer.windowWidth; + } } \ No newline at end of file