From e2162ee0a34973a0abc0773868d25c9f6e63ec7a Mon Sep 17 00:00:00 2001 From: Jeremy Archer Date: Sat, 29 Oct 2011 13:55:00 -0500 Subject: [PATCH] Initial commit --- README | 4 ++ editor.js | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++ index.html | 24 ++++++++++++ samples.js | 27 ++++++++++++++ styles.css | 14 +++++++ tabs.js | 71 +++++++++++++++++++++++++++++++++++ 6 files changed, 248 insertions(+) create mode 100644 README create mode 100644 editor.js create mode 100644 index.html create mode 100644 samples.js create mode 100644 styles.css create mode 100644 tabs.js diff --git a/README b/README new file mode 100644 index 0000000..2fcf11d --- /dev/null +++ b/README @@ -0,0 +1,4 @@ +Graphics Playpen +================ + +Because compiling a Processing.org takes two seconds too long, I've created this script to better create HTML5 applications and renderings. \ No newline at end of file diff --git a/editor.js b/editor.js new file mode 100644 index 0000000..bb134ae --- /dev/null +++ b/editor.js @@ -0,0 +1,108 @@ +// 29 October 2011 +// +// Copyright (c) 2011 Jeremy Arche +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +GraphEditor = { + anyChangesYet : false, + + initialized : (function() { + window.onload = function() { + GraphEditor.setupDOM(); + } + + return true; + })(), + + setupDOM : function() { + var textarea = document.getElementsByTagName('textarea')[0]; + var canvas = document.getElementsByTagName('canvas')[0]; + var context = canvas.getContext('2d'); + var errors = document.getElementsByTagName('pre')[0]; + var body = document.getElementsByTagName('body')[0]; + var select = document.getElementsByTagName('select')[0]; + + textarea.value = "draw = function() {\n \n};"; + errors.firstChild.nodeValue = 'Type someting in the field above to start.'; + + context.width = canvas.width; + context.height = canvas.height; + + textarea.onkeydown = function(event) { + checkTab(event); + return !event.defaultPrevented; + } + + textarea.onkeyup = function(event) { + GraphEditor.anyChangesYet = true; + + context.save(); + + try { + var code = ( + 'var width = canvas.width, height = canvas.height;' + + textarea.value + ); + + GraphEditor.compileFor(code, context); + + errors.firstChild.nodeValue = "Compilation successful."; + } catch (e) { + errors.firstChild.nodeValue = e.toString(); + } + + context.restore(); + } + + select.onchange = function() { + var code = GraphEditor.samples[select.selectedIndex]; + + if (code) { + textarea.value = code; + textarea.onkeyup(null); + } + + select.selectedIndex = 0; + } + + window.onbeforeunload = function(e) { + if (GraphEditor.anyChangesYet) + return e.returnValue = 'Changes are not saved in this demonstration.'; + } + }, + + compileFor: function(code, scope) { + var exports = eval( + '(function() { ' + + ' var draw, setup; ' + + ' with(scope) { ' + + code + + ' }' + + ' return [ draw, setup ];' + + '})();' + ); + + var draw = exports[0]; + var setup = exports[1]; + + draw(); + } +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..6ee62aa --- /dev/null +++ b/index.html @@ -0,0 +1,24 @@ + + + + + Graphics Playpen + + + + + + +

Graphics Playpen

+
+
+ +
Loading...
+
+ +

See the HTML5 canvas tutorial for details : Jeremy Archer 2011

+ + \ No newline at end of file diff --git a/samples.js b/samples.js new file mode 100644 index 0000000..65f3cc1 --- /dev/null +++ b/samples.js @@ -0,0 +1,27 @@ +// 29 October 2011 +// +// Copyright (c) 2011 Jeremy Arche +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +GraphEditor.samples = [ + null, + "draw = function() {\n clearRect(0, 0, width, height);\n \n strokeStyle = 'rgba(100, 100, 100, 0.2)';\n \n for (var prd = 0; prd <= 10; prd++) {\n if (prd == 5) {\n strokeStyle = '#c00;';\n } else if (prd == 10) {\n strokeStyle = '#39c';\n } else{\n var r = prd * 30\n strokeStyle = 'rgba('+r+','+r+','+r+',0.2)';\n }\n \n beginPath();\n \n for (var x = 0; x < 500; x += 2) {\n lineTo(x, (1 + Math.sin(x / (5 + 2 * prd)) * 0.2) * height / 2);\n }\n \n stroke();\n closePath();\n }\n};" +] \ No newline at end of file diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..10ef9a5 --- /dev/null +++ b/styles.css @@ -0,0 +1,14 @@ +*{margin:0;padding:0;} +body{background-color:#eee;padding:1em;} +textarea{font:11px Monaco,monospace;width:40em;height:20em;} +textarea{padding:0.5em;} +h1{font:bold 2em Arial,sans-serif;letter-spacing:-0.1em;} +h1{padding-bottom:0.2em;} +canvas{border:1px solid #ccc;background-color:#fff;} +canvas{margin-top:2em;} +.left,canvas{vertical-align:top;display:inline-block;} +pre{border:1px solid #ccc;text-align:left;padding:1em;background-color:#fff;} +form{display:block;height:2em;} +#info{position:absolute;bottom:1em;left:0em;right:0;text-align:center;} +#info{font:0.8em Helvetica,sans-serif;color:#999;} +#info a{color:#555;text-decoration:underline;} \ No newline at end of file diff --git a/tabs.js b/tabs.js new file mode 100644 index 0000000..07995aa --- /dev/null +++ b/tabs.js @@ -0,0 +1,71 @@ +// 29 October 2011 +// +// Licence unspecified; see source for details: +// +// +// Code essentially unmodified. +// + +function checkTab(evt) { + var t = evt.target; + var ss = t.selectionStart; + var se = t.selectionEnd; + var tab = " "; + + // Tab key - insert tab expansion + if (evt.keyCode == 9) { + evt.preventDefault(); + + // Special case of multi line selection + if (ss != se && t.value.slice(ss,se).indexOf("n") != -1) { + // In case selection was not of entire lines (e.g. selection begins in the middle of a line) + // we ought to tab at the beginning as well as at the start of every following line. + var pre = t.value.slice(0,ss); + var sel = t.value.slice(ss,se).replace(/n/g,"n"+tab); + var post = t.value.slice(se,t.value.length); + t.value = pre.concat(tab).concat(sel).concat(post); + + t.selectionStart = ss + tab.length; + t.selectionEnd = se + tab.length; + } + + // "Normal" case (no selection or selection on one line only) + else { + t.value = t.value.slice(0,ss).concat(tab).concat(t.value.slice(ss,t.value.length)); + if (ss == se) { + t.selectionStart = t.selectionEnd = ss + tab.length; + } + else { + t.selectionStart = ss + tab.length; + t.selectionEnd = se + tab.length; + } + } + } + + // Backspace key - delete preceding tab expansion, if exists + else if (evt.keyCode==8 && t.value.slice(ss - tab.length,ss) == tab) { + evt.preventDefault(); + + t.value = t.value.slice(0,ss - tab.length).concat(t.value.slice(ss,t.value.length)); + t.selectionStart = t.selectionEnd = ss - tab.length; + } + + // Delete key - delete following tab expansion, if exists + else if (evt.keyCode==46 && t.value.slice(se,se + tab.length) == tab) { + evt.preventDefault(); + + t.value = t.value.slice(0,ss).concat(t.value.slice(ss + tab.length,t.value.length)); + t.selectionStart = t.selectionEnd = ss; + } + // Left/right arrow keys - move across the tab in one go + else if (evt.keyCode == 37 && t.value.slice(ss - tab.length,ss) == tab) { + evt.preventDefault(); + t.selectionStart = t.selectionEnd = ss - tab.length; + } + else if (evt.keyCode == 39 && t.value.slice(ss,ss + tab.length) == tab) { + evt.preventDefault(); + t.selectionStart = t.selectionEnd = ss + tab.length; + } +} + +