├── .gitignore ├── README.md ├── examples ├── basic │ ├── arm.pde │ ├── arraylist.pde │ ├── color.pde │ ├── colorwheel.pde │ ├── coollines.pde │ ├── coordinatesystem.pde │ ├── createimage.pde │ ├── eames.jpg │ ├── easing.pde │ ├── fillstrokeweight.pde │ ├── functions.pde │ ├── google-code-prettify │ │ ├── lang-apollo.js │ │ ├── lang-clj.js │ │ ├── lang-css.js │ │ ├── lang-go.js │ │ ├── lang-hs.js │ │ ├── lang-lisp.js │ │ ├── lang-lua.js │ │ ├── lang-ml.js │ │ ├── lang-n.js │ │ ├── lang-proto.js │ │ ├── lang-scala.js │ │ ├── lang-sql.js │ │ ├── lang-tex.js │ │ ├── lang-vb.js │ │ ├── lang-vhdl.js │ │ ├── lang-wiki.js │ │ ├── lang-xq.js │ │ ├── lang-yaml.js │ │ ├── prettify.css │ │ └── prettify.js │ ├── hashmap.pde │ ├── helloworld.pde │ ├── index.html │ ├── jelly.jpg │ ├── jquery-1.6.4.js │ ├── keyboard.pde │ ├── loadimage.pde │ ├── loop.pde │ ├── mousesignals.pde │ ├── objects.pde │ ├── pgraphics.pde │ ├── piechart.pde │ ├── pointilism.pde │ ├── pointsandlines.pde │ ├── redraw.pde │ ├── rotate.pde │ ├── scale.pde │ ├── setupanddraw.pde │ ├── shapeprimitives.pde │ ├── text.pde │ ├── translate.pde │ └── variables.pde ├── localfiles │ ├── test.html │ └── test.pde ├── multitouch │ └── index.html ├── pewpew │ ├── css │ │ ├── console.css │ │ ├── main.css │ │ ├── pewpew.css │ │ ├── reset.css │ │ └── ui.css │ ├── highscores.itf │ ├── images │ │ ├── body_bg.png │ │ ├── jui │ │ │ ├── pbar-ani.gif │ │ │ ├── ui-bg_gloss-wave_35_f6a828_500x100.png │ │ │ └── ui-bg_inset-soft_25_000000_1x100.png │ │ └── wrapper_bg.png │ ├── index.html │ ├── input.js │ ├── jquery-1.7.min.js │ ├── jquery-ui-1.8.9.custom.min.js │ ├── jquery.hotkeys-0.7.9.js │ ├── pewpew.js │ ├── pewpew.pjs │ └── processing.js ├── processing-and-js │ ├── index.html │ ├── translation-data-html.html │ ├── translation-data-sketch.html │ ├── translation-data-window.html │ ├── translation-fullscreen.html │ ├── translation-html.html │ ├── translation-inline.html │ ├── translation-jquery.html │ ├── translation-js.html │ ├── translation-many-sketches.html │ ├── translation.html │ ├── translation.js │ ├── translation.pde │ └── translation.pjs ├── processing-mobile │ └── index.html ├── tangle │ ├── Tangle-0.1.0 │ │ ├── Tangle.js │ │ ├── TangleKit │ │ │ ├── BVTouchable.js │ │ │ ├── TangleKit.css │ │ │ ├── TangleKit.js │ │ │ ├── mootools.js │ │ │ └── sprintf.js │ │ └── TangleTemplate.html │ └── index.html └── twitter │ ├── blprnt-twitter-demo.html │ ├── processing-twitter.js │ └── twitter-images.html ├── index.html ├── processing-mobile.js ├── processing-phonegap.js ├── processing.js └── tools ├── httpd.py ├── jsbeautify.js ├── processing-helper.html └── processing-helper.js /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Processing Mobile 2 | ----------------- 3 | 4 | A collection of demos used on the Processing.js Workshop Tour 5 | -------------------------------------------------------------------------------- /examples/basic/arm.pde: -------------------------------------------------------------------------------- 1 | float x = 50; 2 | float y = 100; 3 | float angle1 = 0.0; 4 | float angle2 = 0.0; 5 | float segLength = 50; 6 | 7 | void setup() { 8 | size(200, 200); 9 | smooth(); 10 | strokeWeight(20.0); 11 | stroke(0, 100); 12 | } 13 | 14 | void draw() { 15 | background(226); 16 | 17 | angle1 = (mouseX/float(width) - 0.5) * -PI; 18 | angle2 = (mouseY/float(height) - 0.5) * PI; 19 | 20 | pushMatrix(); 21 | segment(x, y, angle1); 22 | segment(segLength, 0, angle2); 23 | popMatrix(); 24 | } 25 | 26 | void segment(float x, float y, float a) { 27 | translate(x, y); 28 | rotate(a); 29 | line(0, 0, segLength, 0); 30 | } 31 | -------------------------------------------------------------------------------- /examples/basic/arraylist.pde: -------------------------------------------------------------------------------- 1 | ArrayList balls; 2 | int ballWidth = 48; 3 | 4 | void setup() { 5 | size(200, 200); 6 | smooth(); 7 | noStroke(); 8 | 9 | // Create an empty ArrayList 10 | balls = new ArrayList(); 11 | 12 | // Start by adding one element 13 | balls.add(new Ball(width/2, 0, ballWidth)); 14 | } 15 | 16 | void draw() { 17 | background(255); 18 | 19 | // With an array, we say balls.length, with an ArrayList, we say balls.size() 20 | // The length of an ArrayList is dynamic 21 | // Notice how we are looping through the ArrayList backwards 22 | // This is because we are deleting elements from the list 23 | for (int i = balls.size()-1; i >= 0; i--) { 24 | // An ArrayList doesn't know what it is storing so we have to cast the object coming out 25 | Ball ball = (Ball) balls.get(i); 26 | ball.move(); 27 | ball.display(); 28 | if (ball.finished()) { 29 | // Items can be deleted with remove() 30 | balls.remove(i); 31 | } 32 | 33 | } 34 | 35 | } 36 | 37 | void mousePressed() { 38 | // A new ball object is added to the ArrayList (by default to the end) 39 | balls.add(new Ball(mouseX, mouseY, ballWidth)); 40 | } 41 | 42 | 43 | 44 | 45 | // Simple bouncing ball class 46 | 47 | class Ball { 48 | 49 | float x; 50 | float y; 51 | float speed; 52 | float gravity; 53 | float w; 54 | float life = 255; 55 | 56 | Ball(float tempX, float tempY, float tempW) { 57 | x = tempX; 58 | y = tempY; 59 | w = tempW; 60 | speed = 0; 61 | gravity = 0.1; 62 | } 63 | 64 | void move() { 65 | // Add gravity to speed 66 | speed = speed + gravity; 67 | // Add speed to y location 68 | y = y + speed; 69 | // If square reaches the bottom 70 | // Reverse speed 71 | if (y > height) { 72 | // Dampening 73 | speed = speed * -0.8; 74 | y = height; 75 | } 76 | } 77 | 78 | boolean finished() { 79 | // Balls fade out 80 | life--; 81 | if (life < 0) { 82 | return true; 83 | } else { 84 | return false; 85 | } 86 | } 87 | 88 | void display() { 89 | // Display the circle 90 | fill(0,life); 91 | //stroke(0,life); 92 | ellipse(x,y,w,w); 93 | } 94 | } 95 | 96 | -------------------------------------------------------------------------------- /examples/basic/color.pde: -------------------------------------------------------------------------------- 1 | size(200, 200); 2 | noStroke(); 3 | 4 | color inside = color(204, 102, 0); 5 | color middle = color(204, 153, 0); 6 | color outside = color(153, 51, 0); 7 | 8 | fill(outside); 9 | rect(0, 0, 200, 200); 10 | fill(middle); 11 | rect(40, 60, 120, 120); 12 | fill(inside); 13 | rect(60, 90, 80, 80); 14 | -------------------------------------------------------------------------------- /examples/basic/colorwheel.pde: -------------------------------------------------------------------------------- 1 | int segs = 12; 2 | int steps = 6; 3 | float rotAdjust = TWO_PI / segs / 2; 4 | float radius; 5 | float segWidth; 6 | float interval = TWO_PI / segs; 7 | 8 | void setup() { 9 | size(200, 200); 10 | background(127); 11 | smooth(); 12 | ellipseMode(RADIUS); 13 | noStroke(); 14 | // make the diameter 90% of the sketch area 15 | radius = min(width, height) * 0.45; 16 | segWidth = radius / steps; 17 | 18 | drawShadeWheel(); 19 | } 20 | 21 | void drawShadeWheel() { 22 | for (int j = 0; j < steps; j++) { 23 | color[] cols = { 24 | color(255-(255/steps)*j, 255-(255/steps)*j, 0), 25 | color(255-(255/steps)*j, (255/1.5)-((255/1.5)/steps)*j, 0), 26 | color(255-(255/steps)*j, (255/2)-((255/2)/steps)*j, 0), 27 | color(255-(255/steps)*j, (255/2.5)-((255/2.5)/steps)*j, 0), 28 | color(255-(255/steps)*j, 0, 0), 29 | color(255-(255/steps)*j, 0, (255/2)-((255/2)/steps)*j), 30 | color(255-(255/steps)*j, 0, 255-(255/steps)*j), 31 | color((255/2)-((255/2)/steps)*j, 0, 255-(255/steps)*j), 32 | color(0, 0, 255-(255/steps)*j), 33 | color(0, 255-(255/steps)*j, (255/2.5)-((255/2.5)/steps)*j), 34 | color(0, 255-(255/steps)*j, 0), 35 | color((255/2)-((255/2)/steps)*j, 255-(255/steps)*j, 0) 36 | }; 37 | for (int i = 0; i < segs; i++) { 38 | fill(cols[i]); 39 | arc(width/2, height/2, radius, radius, 40 | interval*i+rotAdjust, interval*(i+1)+rotAdjust); 41 | } 42 | radius -= segWidth; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /examples/basic/coollines.pde: -------------------------------------------------------------------------------- 1 | int i = 0; 2 | void setup() { // this is run once. 3 | 4 | // set the background color 5 | background(255); 6 | 7 | // canvas size (Integers only, please.) 8 | size(300, 300); 9 | 10 | // smooth edges 11 | smooth(); 12 | 13 | // limit the number of frames per second 14 | frameRate(30); 15 | 16 | // set the width of the line. 17 | strokeWeight(12); 18 | } 19 | 20 | void draw() { // this is run repeatedly. 21 | // set the color 22 | stroke(random(50), random(255), random(255), 100); 23 | 24 | // draw the line 25 | line(i, 0, random(0, width), height); 26 | 27 | // move over a pixel 28 | if (i < width) { 29 | i++; 30 | } else { 31 | i = 0; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/basic/coordinatesystem.pde: -------------------------------------------------------------------------------- 1 | size(450, 450); 2 | 3 | background(255, 255, 255); 4 | 5 | fill(0); 6 | text("(0, 0)", 0, 25); 7 | text("X", width/2, 13); 8 | text("Y", 0, height/2); 9 | 10 | strokeWeight(2); 11 | stroke(255, 50, 50); 12 | line(30, 0, 30, height); 13 | line(0, 30, width, 30); 14 | 15 | strokeWeight(1); 16 | stroke(0); 17 | for (int i = 50; i < width; i = i + 20) { 18 | line(i, 30, i, height); 19 | line(30, i, width, i); 20 | } 21 | 22 | for (int i = 0; i <= 20; i++) { 23 | textAlign(CENTER, BASELINE); 24 | text(i, 40 + (i * 20), 25); 25 | textAlign(RIGHT, BASELINE); 26 | text(i, 25, 45 + (i * 20)); 27 | } 28 | -------------------------------------------------------------------------------- /examples/basic/createimage.pde: -------------------------------------------------------------------------------- 1 | PImage img; 2 | 3 | void setup() 4 | { 5 | size(200, 200); 6 | img = createImage(120, 120, ARGB); 7 | for(int i=0; i < img.pixels.length; i++) { 8 | img.pixels[i] = color(0, 90, 102, i%img.width * 2); 9 | } 10 | } 11 | 12 | void draw() 13 | { 14 | background(204); 15 | image(img, 33, 33); 16 | image(img, mouseX-60, mouseY-60); 17 | } 18 | -------------------------------------------------------------------------------- /examples/basic/eames.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing-js/processing-mobile/407ee0b54a400ba299aa2c0e277bdaaedaa327c1/examples/basic/eames.jpg -------------------------------------------------------------------------------- /examples/basic/easing.pde: -------------------------------------------------------------------------------- 1 | float x; 2 | float y; 3 | float targetX, targetY; 4 | float easing = 0.05; 5 | 6 | void setup() 7 | { 8 | size(200, 200); 9 | smooth(); 10 | noStroke(); 11 | } 12 | 13 | void draw() 14 | { 15 | background( 51 ); 16 | 17 | targetX = mouseX; 18 | float dx = targetX - x; 19 | if(abs(dx) > 1) { 20 | x += dx * easing; 21 | } 22 | 23 | targetY = mouseY; 24 | float dy = targetY - y; 25 | if(abs(dy) > 1) { 26 | y += dy * easing; 27 | } 28 | 29 | ellipse(x, y, 33, 33); 30 | } 31 | -------------------------------------------------------------------------------- /examples/basic/fillstrokeweight.pde: -------------------------------------------------------------------------------- 1 | size(200, 200); 2 | background(255); 3 | 4 | rect(5, 5, 90, 90); 5 | 6 | fill(50, 200, 50); 7 | rect(105, 5, 90, 90); 8 | 9 | strokeWeight(10); 10 | rect(10, 110, 80, 80); 11 | 12 | stroke(50, 50, 150); 13 | rect(110, 110, 80, 80); 14 | -------------------------------------------------------------------------------- /examples/basic/functions.pde: -------------------------------------------------------------------------------- 1 | void setup() { 2 | size(450, 450); 3 | background(51); 4 | noStroke(); 5 | smooth(); 6 | noLoop(); 7 | } 8 | 9 | void draw() { 10 | drawTarget(250, 250, 400, 10); 11 | drawTarget(152, 16, 200, 3); 12 | drawTarget(100, 144, 180, 5); 13 | } 14 | 15 | void drawTarget(int xloc, int yloc, int size, int num) { 16 | float grayvalues = 255/num; 17 | float steps = size/num; 18 | for (int i = 0; i < num; i++) { 19 | fill(i*grayvalues); 20 | ellipse(xloc, yloc, size-i*steps, size-i*steps); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /examples/basic/google-code-prettify/lang-apollo.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing-js/processing-mobile/407ee0b54a400ba299aa2c0e277bdaaedaa327c1/examples/basic/google-code-prettify/lang-apollo.js -------------------------------------------------------------------------------- /examples/basic/google-code-prettify/lang-clj.js: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2011 Google Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | var a=null; 17 | PR.registerLangHandler(PR.createSimpleLexer([["opn",/^[([{]+/,a,"([{"],["clo",/^[)\]}]+/,a,")]}"],["com",/^;[^\n\r]*/,a,";"],["pln",/^[\t\n\r \xa0]+/,a,"\t\n\r \xa0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,a,'"']],[["kwd",/^(?:def|if|do|let|quote|var|fn|loop|recur|throw|try|monitor-enter|monitor-exit|defmacro|defn|defn-|macroexpand|macroexpand-1|for|doseq|dosync|dotimes|and|or|when|not|assert|doto|proxy|defstruct|first|rest|cons|defprotocol|deftype|defrecord|reify|defmulti|defmethod|meta|with-meta|ns|in-ns|create-ns|import|intern|refer|alias|namespace|resolve|ref|deref|refset|new|set!|memfn|to-array|into-array|aset|gen-class|reduce|map|filter|find|nil?|empty?|hash-map|hash-set|vec|vector|seq|flatten|reverse|assoc|dissoc|list|list?|disj|get|union|difference|intersection|extend|extend-type|extend-protocol|prn)\b/,a], 18 | ["typ",/^:[\dA-Za-z-]+/]]),["clj"]); 19 | -------------------------------------------------------------------------------- /examples/basic/google-code-prettify/lang-css.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", 2 | /^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); 3 | -------------------------------------------------------------------------------- /examples/basic/google-code-prettify/lang-go.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing-js/processing-mobile/407ee0b54a400ba299aa2c0e277bdaaedaa327c1/examples/basic/google-code-prettify/lang-go.js -------------------------------------------------------------------------------- /examples/basic/google-code-prettify/lang-hs.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t-\r ]+/,null,"\t\n \r "],["str",/^"(?:[^\n\f\r"\\]|\\[\S\s])*(?:"|$)/,null,'"'],["str",/^'(?:[^\n\f\r'\\]|\\[^&])'?/,null,"'"],["lit",/^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+-]?\d+)?)/i,null,"0123456789"]],[["com",/^(?:--+[^\n\f\r]*|{-(?:[^-]|-+[^}-])*-})/],["kwd",/^(?:case|class|data|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|module|newtype|of|then|type|where|_)(?=[^\d'A-Za-z]|$)/, 2 | null],["pln",/^(?:[A-Z][\w']*\.)*[A-Za-z][\w']*/],["pun",/^[^\d\t-\r "'A-Za-z]+/]]),["hs"]); 3 | -------------------------------------------------------------------------------- /examples/basic/google-code-prettify/lang-lisp.js: -------------------------------------------------------------------------------- 1 | var a=null; 2 | PR.registerLangHandler(PR.createSimpleLexer([["opn",/^\(+/,a,"("],["clo",/^\)+/,a,")"],["com",/^;[^\n\r]*/,a,";"],["pln",/^[\t\n\r \xa0]+/,a,"\t\n\r \xa0"],["str",/^"(?:[^"\\]|\\[\S\s])*(?:"|$)/,a,'"']],[["kwd",/^(?:block|c[ad]+r|catch|con[ds]|def(?:ine|un)|do|eq|eql|equal|equalp|eval-when|flet|format|go|if|labels|lambda|let|load-time-value|locally|macrolet|multiple-value-call|nil|progn|progv|quote|require|return-from|setq|symbol-macrolet|t|tagbody|the|throw|unwind)\b/,a], 3 | ["lit",/^[+-]?(?:[#0]x[\da-f]+|\d+\/\d+|(?:\.\d+|\d+(?:\.\d*)?)(?:[de][+-]?\d+)?)/i],["lit",/^'(?:-*(?:\w|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?)?/],["pln",/^-*(?:[_a-z]|\\[!-~])(?:[\w-]*|\\[!-~])[!=?]?/i],["pun",/^[^\w\t\n\r "'-);\\\xa0]+/]]),["cl","el","lisp","scm"]); 4 | -------------------------------------------------------------------------------- /examples/basic/google-code-prettify/lang-lua.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing-js/processing-mobile/407ee0b54a400ba299aa2c0e277bdaaedaa327c1/examples/basic/google-code-prettify/lang-lua.js -------------------------------------------------------------------------------- /examples/basic/google-code-prettify/lang-ml.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing-js/processing-mobile/407ee0b54a400ba299aa2c0e277bdaaedaa327c1/examples/basic/google-code-prettify/lang-ml.js -------------------------------------------------------------------------------- /examples/basic/google-code-prettify/lang-n.js: -------------------------------------------------------------------------------- 1 | var a=null; 2 | PR.registerLangHandler(PR.createSimpleLexer([["str",/^(?:'(?:[^\n\r'\\]|\\.)*'|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,a,'"'],["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,a,"#"],["pln",/^\s+/,a," \r\n\t\xa0"]],[["str",/^@"(?:[^"]|"")*(?:"|$)/,a],["str",/^<#[^#>]*(?:#>|$)/,a],["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,a],["com",/^\/\/[^\n\r]*/,a],["com",/^\/\*[\S\s]*?(?:\*\/|$)/, 3 | a],["kwd",/^(?:abstract|and|as|base|catch|class|def|delegate|enum|event|extern|false|finally|fun|implements|interface|internal|is|macro|match|matches|module|mutable|namespace|new|null|out|override|params|partial|private|protected|public|ref|sealed|static|struct|syntax|this|throw|true|try|type|typeof|using|variant|virtual|volatile|when|where|with|assert|assert2|async|break|checked|continue|do|else|ensures|for|foreach|if|late|lock|new|nolate|otherwise|regexp|repeat|requires|return|surroundwith|unchecked|unless|using|while|yield)\b/, 4 | a],["typ",/^(?:array|bool|byte|char|decimal|double|float|int|list|long|object|sbyte|short|string|ulong|uint|ufloat|ulong|ushort|void)\b/,a],["lit",/^@[$_a-z][\w$@]*/i,a],["typ",/^@[A-Z]+[a-z][\w$@]*/,a],["pln",/^'?[$_a-z][\w$@]*/i,a],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,a,"0123456789"],["pun",/^.[^\s\w"-$'./@`]*/,a]]),["n","nemerle"]); 5 | -------------------------------------------------------------------------------- /examples/basic/google-code-prettify/lang-proto.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.sourceDecorator({keywords:"bytes,default,double,enum,extend,extensions,false,group,import,max,message,option,optional,package,repeated,required,returns,rpc,service,syntax,to,true",types:/^(bool|(double|s?fixed|[su]?int)(32|64)|float|string)\b/,cStyleComments:!0}),["proto"]); 2 | -------------------------------------------------------------------------------- /examples/basic/google-code-prettify/lang-scala.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing-js/processing-mobile/407ee0b54a400ba299aa2c0e277bdaaedaa327c1/examples/basic/google-code-prettify/lang-scala.js -------------------------------------------------------------------------------- /examples/basic/google-code-prettify/lang-sql.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing-js/processing-mobile/407ee0b54a400ba299aa2c0e277bdaaedaa327c1/examples/basic/google-code-prettify/lang-sql.js -------------------------------------------------------------------------------- /examples/basic/google-code-prettify/lang-tex.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing-js/processing-mobile/407ee0b54a400ba299aa2c0e277bdaaedaa327c1/examples/basic/google-code-prettify/lang-tex.js -------------------------------------------------------------------------------- /examples/basic/google-code-prettify/lang-vb.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing-js/processing-mobile/407ee0b54a400ba299aa2c0e277bdaaedaa327c1/examples/basic/google-code-prettify/lang-vb.js -------------------------------------------------------------------------------- /examples/basic/google-code-prettify/lang-vhdl.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing-js/processing-mobile/407ee0b54a400ba299aa2c0e277bdaaedaa327c1/examples/basic/google-code-prettify/lang-vhdl.js -------------------------------------------------------------------------------- /examples/basic/google-code-prettify/lang-wiki.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing-js/processing-mobile/407ee0b54a400ba299aa2c0e277bdaaedaa327c1/examples/basic/google-code-prettify/lang-wiki.js -------------------------------------------------------------------------------- /examples/basic/google-code-prettify/lang-yaml.js: -------------------------------------------------------------------------------- 1 | var a=null; 2 | PR.registerLangHandler(PR.createSimpleLexer([["pun",/^[:>?|]+/,a,":|>?"],["dec",/^%(?:YAML|TAG)[^\n\r#]+/,a,"%"],["typ",/^&\S+/,a,"&"],["typ",/^!\S*/,a,"!"],["str",/^"(?:[^"\\]|\\.)*(?:"|$)/,a,'"'],["str",/^'(?:[^']|'')*(?:'|$)/,a,"'"],["com",/^#[^\n\r]*/,a,"#"],["pln",/^\s+/,a," \t\r\n"]],[["dec",/^(?:---|\.\.\.)(?:[\n\r]|$)/],["pun",/^-/],["kwd",/^\w+:[\n\r ]/],["pln",/^\w+/]]),["yaml","yml"]); 3 | -------------------------------------------------------------------------------- /examples/basic/google-code-prettify/prettify.css: -------------------------------------------------------------------------------- 1 | .pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} -------------------------------------------------------------------------------- /examples/basic/google-code-prettify/prettify.js: -------------------------------------------------------------------------------- 1 | var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; 2 | (function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= 3 | [],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), 9 | l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, 10 | q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, 11 | q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, 12 | "");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), 13 | a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} 14 | for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], 18 | "catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], 19 | H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], 20 | J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ 21 | I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), 22 | ["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", 23 | /^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), 24 | ["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", 25 | hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= 26 | !k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p 2 | 3 | 4 | Basic Examples 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 54 | 55 | 56 |
57 |

Select a Sketch:

58 | 105 |
106 |
107 |

Code

108 |
Select a sketch from the dropdown above to get started
109 |
110 |
111 |

Sketch

112 | Your browser does not support the HTML5 Canvas tag :( 113 |
114 |
115 |
116 | 117 | 118 | -------------------------------------------------------------------------------- /examples/basic/jelly.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing-js/processing-mobile/407ee0b54a400ba299aa2c0e277bdaaedaa327c1/examples/basic/jelly.jpg -------------------------------------------------------------------------------- /examples/basic/keyboard.pde: -------------------------------------------------------------------------------- 1 | int rectWidth; 2 | 3 | void setup() { 4 | size(200, 200); 5 | noStroke(); 6 | background(0); 7 | rectWidth = width/4; 8 | } 9 | 10 | void draw() { 11 | // keep draw() here to continue looping while waiting for keys 12 | } 13 | 14 | void keyPressed() { 15 | int keyIndex = -1; 16 | if (key >= 'A' && key <= 'Z') { 17 | keyIndex = key - 'A'; 18 | } else if (key >= 'a' && key <= 'z') { 19 | keyIndex = key - 'a'; 20 | } 21 | if (keyIndex == -1) { 22 | // If it's not a letter key, clear the screen 23 | background(0); 24 | } else { 25 | // It's a letter key, fill a rectangle 26 | fill(millis() % 255); 27 | float x = map(keyIndex, 0, 25, 0, width - rectWidth); 28 | rect(x, 0, rectWidth, height); 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /examples/basic/loadimage.pde: -------------------------------------------------------------------------------- 1 | /* @pjs preload="jelly.jpg"; */ 2 | 3 | PImage a; // Declare variable "a" of type PImage 4 | 5 | void setup() { 6 | size(200, 200); 7 | // The file "jelly.jpg" must be in the data folder 8 | // of the current sketch to load successfully 9 | a = loadImage("jelly.jpg"); // Load the image into the program 10 | noLoop(); // Makes draw() only run once 11 | } 12 | 13 | void draw() { 14 | // Displays the image at its actual size at point (0,0) 15 | image(a, 0, 0); 16 | // Displays the image at point (100, 0) at half of its size 17 | image(a, 100, 0, a.width/2, a.height/2); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /examples/basic/loop.pde: -------------------------------------------------------------------------------- 1 | float y = 100; 2 | boolean doLoop = false; 3 | 4 | void setup() { 5 | size(450, 450); 6 | stroke(255); 7 | noLoop(); 8 | } 9 | 10 | void draw() { 11 | background(0); 12 | line(0, y, width, y); 13 | 14 | y = y - 1; 15 | if (y < 0) { 16 | y = height; 17 | } 18 | } 19 | 20 | void mousePressed() { 21 | if (doLoop) { 22 | noLoop(); 23 | } else { 24 | loop(); 25 | } 26 | doLoop = !doLoop; 27 | } 28 | -------------------------------------------------------------------------------- /examples/basic/mousesignals.pde: -------------------------------------------------------------------------------- 1 | int[] xvals; 2 | int[] yvals; 3 | int[] bvals; 4 | 5 | void setup() 6 | { 7 | size(200, 200); 8 | xvals = new int[width]; 9 | yvals = new int[width]; 10 | bvals = new int[width]; 11 | } 12 | 13 | int arrayindex = 0; 14 | 15 | void draw() 16 | { 17 | background(102); 18 | 19 | for(int i=1; i 1) { 50 | ypos -= dif/damping; 51 | } 52 | dif = xpos - posX; 53 | if (abs(dif) > 1) { 54 | xpos -= dif/damping; 55 | } 56 | } 57 | 58 | void display() { 59 | for (int i=0; i < t; i++) { 60 | rect(xpos+(i*(d+w)), ypos, w, height*h); 61 | } 62 | } 63 | } 64 | 65 | -------------------------------------------------------------------------------- /examples/basic/pgraphics.pde: -------------------------------------------------------------------------------- 1 | PGraphics pg; 2 | 3 | void setup() { 4 | size(200, 200); 5 | pg = createGraphics(80, 80, P2D); 6 | } 7 | 8 | void draw() { 9 | fill(0, 12); 10 | rect(0, 0, width, height); 11 | fill(255); 12 | noStroke(); 13 | ellipse(mouseX, mouseY, 60, 60); 14 | 15 | pg.beginDraw(); 16 | pg.background(102); 17 | pg.noFill(); 18 | pg.stroke(255); 19 | pg.ellipse(mouseX-60, mouseY-60, 60, 60); 20 | pg.endDraw(); 21 | 22 | image(pg, 60, 60); 23 | } 24 | -------------------------------------------------------------------------------- /examples/basic/piechart.pde: -------------------------------------------------------------------------------- 1 | size(450, 450); 2 | background(100); 3 | smooth(); 4 | noStroke(); 5 | 6 | float diameter = min(width, height) * 0.75; 7 | int[] angs = {30, 10, 45, 35, 60, 38, 75, 67}; 8 | float lastAng = 0; 9 | 10 | for (int i = 0; i < angs.length; i++){ 11 | fill(angs[i] * 3.0); 12 | arc(width/2, height/2, diameter, diameter, lastAng, lastAng+radians(angs[i])); 13 | lastAng += radians(angs[i]); 14 | } 15 | -------------------------------------------------------------------------------- /examples/basic/pointilism.pde: -------------------------------------------------------------------------------- 1 | /* @pjs preload="eames.jpg"; */ 2 | 3 | PImage img; 4 | 5 | int smallPoint = 2; 6 | int largePoint; 7 | int top, left; 8 | 9 | void setup() { 10 | size(200, 200); 11 | img = loadImage("eames.jpg"); 12 | noStroke(); 13 | background(255); 14 | smooth(); 15 | largePoint = min(width, height) / 10; 16 | // center the image on the screen 17 | left = (width - img.width) / 2; 18 | top = (height - img.height) / 2; 19 | } 20 | 21 | void draw() { 22 | float pointillize = map(random(img.width), 0, width, smallPoint, largePoint); 23 | int x = int(random(img.width)); 24 | int y = int(random(img.height)); 25 | color pix = img.get(x, y); 26 | fill(pix, 128); 27 | ellipse(left + x, top + y, pointillize, pointillize); 28 | } 29 | -------------------------------------------------------------------------------- /examples/basic/pointsandlines.pde: -------------------------------------------------------------------------------- 1 | int d = 40; 2 | int p1 = d; 3 | int p2 = p1+d; 4 | int p3 = p2+d; 5 | int p4 = p3+d; 6 | 7 | size(200, 200); 8 | background(0); 9 | 10 | // Draw gray box 11 | stroke(153); 12 | line(p3, p3, p2, p3); 13 | line(p2, p3, p2, p2); 14 | line(p2, p2, p3, p2); 15 | line(p3, p2, p3, p3); 16 | 17 | // Draw white points 18 | stroke(255); 19 | point(p1, p1); 20 | point(p1, p3); 21 | point(p2, p4); 22 | point(p3, p1); 23 | point(p4, p2); 24 | point(p4, p4); 25 | 26 | -------------------------------------------------------------------------------- /examples/basic/redraw.pde: -------------------------------------------------------------------------------- 1 | // The statements in the setup() function 2 | // execute once when the program begins 3 | void setup() { 4 | size(450, 450); // Size should be the first statement 5 | stroke(255); // Set line drawing color to white 6 | noLoop(); 7 | } 8 | 9 | float y = 100; 10 | 11 | // The statements in draw() are executed until the 12 | // program is stopped. Each statement is executed in 13 | // sequence and after the last line is read, the first 14 | // line is executed again. 15 | void draw() { 16 | background(0); // Set the background to black 17 | y = y - 1; 18 | if (y < 0) { y = height; } 19 | line(0, y, width, y); 20 | } 21 | 22 | void mousePressed() { 23 | redraw(); 24 | } 25 | -------------------------------------------------------------------------------- /examples/basic/rotate.pde: -------------------------------------------------------------------------------- 1 | float angle; 2 | float jitter; 3 | 4 | void setup() { 5 | size(200, 200); 6 | smooth(); 7 | noStroke(); 8 | fill(255); 9 | rectMode(CENTER); 10 | frameRate(30); 11 | } 12 | 13 | void draw() { 14 | background(102); 15 | 16 | // during even-numbered seconds (0, 2, 4, 6...) 17 | if (second() % 2 == 0) { 18 | jitter = random(-0.1, 0.1); 19 | } 20 | angle = angle + jitter; 21 | float c = cos(angle); 22 | translate(width/2, height/2); 23 | rotate(c); 24 | rect(0, 0, 115, 115); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /examples/basic/scale.pde: -------------------------------------------------------------------------------- 1 | float a = 0.0; 2 | float s = 0.0; 3 | 4 | void setup() 5 | { 6 | size(200,200); 7 | noStroke(); 8 | rectMode(CENTER); 9 | frameRate(30); 10 | } 11 | 12 | void draw() 13 | { 14 | background(102); 15 | 16 | a = a + 0.04; 17 | s = cos(a)*2; 18 | 19 | translate(width/2, height/2); 20 | scale(s); 21 | fill(51); 22 | rect(0, 0, 50, 50); 23 | 24 | translate(75, 0); 25 | fill(255); 26 | scale(s); 27 | rect(0, 0, 50, 50); 28 | } 29 | -------------------------------------------------------------------------------- /examples/basic/setupanddraw.pde: -------------------------------------------------------------------------------- 1 | // This gets executed first as part of the sketch loading 2 | float y = 100; 3 | 4 | // The statements in the setup() function execute once when the program begins 5 | void setup() { 6 | size(450, 450); // Size must be the first statement 7 | stroke(255); // Set line drawing color to white 8 | frameRate(30); 9 | } 10 | 11 | // The statements in draw() are executed until the 12 | // program is stopped. Each statement is executed in 13 | // sequence and after the last line is read, the first 14 | // line is executed again. 15 | void draw() { 16 | background(0); // Set the background to black 17 | y = y - 1; 18 | if (y < 0) { 19 | y = height; 20 | } 21 | line(0, y, width, y); 22 | } 23 | -------------------------------------------------------------------------------- /examples/basic/shapeprimitives.pde: -------------------------------------------------------------------------------- 1 | size(200, 200); 2 | smooth(); 3 | background(0); 4 | noStroke(); 5 | fill(226); 6 | triangle(10, 10, 10, 200, 45, 200); 7 | rect(45, 45, 35, 35); 8 | quad(105, 10, 120, 10, 120, 200, 80, 200); 9 | ellipse(140, 80, 40, 40); 10 | triangle(160, 10, 195, 200, 160, 200); 11 | -------------------------------------------------------------------------------- /examples/basic/text.pde: -------------------------------------------------------------------------------- 1 | size(450, 450); 2 | background(255); 3 | fill(0); 4 | 5 | text("PJS", 20, 20); 6 | 7 | textSize(80); 8 | text("PJS", 20, 80); 9 | 10 | textAlign(RIGHT); 11 | text("PJS", 120, 160); 12 | textAlign(CENTER); 13 | text("PJS", 120, 240); 14 | textAlign(LEFT); 15 | text("PJS", 120, 320); 16 | 17 | fill(50, 150, 50); 18 | text("PJS rules", 350, 0, 100, 300); 19 | -------------------------------------------------------------------------------- /examples/basic/translate.pde: -------------------------------------------------------------------------------- 1 | float x, y; 2 | float boxsize = 40.0; 3 | 4 | void setup() 5 | { 6 | size(200,200); 7 | noStroke(); 8 | frameRate(30); 9 | } 10 | 11 | void draw() 12 | { 13 | background(102); 14 | 15 | x = x + 0.8; 16 | 17 | if (x > width + boxsize) { 18 | x = -boxsize; 19 | } 20 | 21 | translate(x, height/2-boxsize/2); 22 | fill(255); 23 | rect(-boxsize/2, -boxsize/2, boxsize, boxsize); 24 | 25 | // Transforms accumulate. 26 | // Notice how this rect moves twice 27 | // as fast as the other, but it has 28 | // the same parameter for the x-axis value 29 | translate(x, boxsize); 30 | fill(0); 31 | rect(-boxsize/2, -boxsize/2, boxsize, boxsize); 32 | } 33 | 34 | -------------------------------------------------------------------------------- /examples/basic/variables.pde: -------------------------------------------------------------------------------- 1 | size(450, 450); 2 | background(255); 3 | fill(0); 4 | 5 | int a = 20; 6 | int b; 7 | b = 75; 8 | 9 | float c = 40.0; 10 | float d; 11 | d = 200.0; 12 | 13 | boolean e = true; 14 | boolean f = false; 15 | 16 | char g = 'A'; 17 | char h = 'a'; 18 | 19 | String i = "Hello"; 20 | String j = "World"; 21 | 22 | strokeWeight(5); 23 | stroke(25, 50, 255); 24 | line(a, b, c, d); 25 | 26 | stroke(0); 27 | textSize(80); 28 | text(i + j, a, b); 29 | text(g, c, d); 30 | -------------------------------------------------------------------------------- /examples/localfiles/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Processing.js Example Page 5 | 6 | 7 | 47 | 48 | 49 | 50 |
51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /examples/localfiles/test.pde: -------------------------------------------------------------------------------- 1 | void setup() { 2 | size(500, 500); 3 | noLoop(); 4 | clearScreen(); 5 | } 6 | 7 | void clearScreen() { 8 | background(204); 9 | textSize(68); 10 | textAlign(CENTER, CENTER); 11 | text("Select an image\nbelow or drag\nand drop an\nimage on\nthe sketch", width/2, height/2); 12 | } 13 | 14 | void drawImage(Image orig) { 15 | background(255); 16 | PImage pi = new PImage(orig); 17 | image(pi); 18 | } 19 | -------------------------------------------------------------------------------- /examples/multitouch/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Processing.js multi-touch event handling 5 | 6 | 7 | 14 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /examples/pewpew/css/console.css: -------------------------------------------------------------------------------- 1 | div.console { 2 | display: none; 3 | width: 99.8%; 4 | height: 300px; 5 | font-family: fixed; 6 | font-size: 8pt; 7 | background-color: #000000; 8 | border-bottom: solid 1px #595959; 9 | padding-bottom: 5px; 10 | position: absolute; 11 | top: 0px; 12 | left: 0px; 13 | opacity: 0.90; 14 | z-index: 3; 15 | } 16 | #console div.consolehistory { 17 | height: 285px; 18 | overflow: hidden; 19 | width: 99.9%; 20 | color: #cccccc; 21 | opacity: 0.90; 22 | margin-left: 4px; 23 | } 24 | #console div.consoleinput { 25 | width: 100%; 26 | color: #e9a800; 27 | opacity: 0.90; 28 | padding-left: 2px; 29 | } 30 | #console input.consolecommandline { 31 | width: 700px; 32 | border: 0px; 33 | color: #cccccc; 34 | background-color: #000000; 35 | opacity: 0.95; 36 | 37 | } 38 | #console span.highlight {color: #E9A800;} 39 | #console span.success {color: #6FFF31;} 40 | #console span.notice {color:#1E90FF;} 41 | #console span.warning {color:#FFFF00;} 42 | #console span.fatal {color:#FF0000;} 43 | #console span.error {color: #B24D4D;} 44 | 45 | -------------------------------------------------------------------------------- /examples/pewpew/css/main.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Main Colours 3 | * ----------------------- 4 | * Orange - #e9a800 5 | * body gray - #262927 6 | * light gray - #5d645f 7 | */ 8 | a { 9 | border-bottom: 1px dotted #e9a800; 10 | color: #ffffff; 11 | text-decoration: none; 12 | } 13 | a:hover { 14 | border-bottom: 1px solid #cccccc; 15 | } 16 | body { 17 | background: url('../images/body_bg.png') repeat-x left top; 18 | background-color: #212121; 19 | font: 12px/1.2 arial, helvetica, clean, sans-serif; 20 | height: 100%; 21 | } 22 | pre { 23 | color: #333333; 24 | } 25 | 26 | /* 27 | * Comments -------------------- 28 | */ 29 | #comments div.addnew { 30 | margin-top: 10px; 31 | text-align: right; 32 | } 33 | #comments div.commentbox { 34 | background-color: #333; 35 | border: 1px solid #666; 36 | border-radius: 5px; 37 | -moz-border-radius: 5px; 38 | -webkit-border-radius: 5px; 39 | margin: 2px; 40 | } 41 | #comments div.details { 42 | color: #999999; 43 | font-size: 7pt; 44 | margin-right: 3px; 45 | text-align: right; 46 | } 47 | #comments h4 { 48 | color: #aaa; 49 | font-size: 9pt; 50 | margin-bottom: 5px; 51 | } 52 | #comments h5 { 53 | color: #ccc; 54 | font-size: 9pt; 55 | } 56 | #commentdialog { 57 | display: none; 58 | } 59 | #commentform { 60 | width: 98%; 61 | } 62 | #commentform input { 63 | background-color: #1c1c1c; 64 | color: #ffffff; 65 | border: 1px solid #888888; 66 | float: right; 67 | margin-bottom: 5px; 68 | width: 470px; 69 | } 70 | #commentform label { 71 | clear: both; 72 | float: left; 73 | padding-bottom: 8px; 74 | padding-top: 5px; 75 | width: 60px; 76 | } 77 | #commentform textarea { 78 | background-color: #1c1c1c; 79 | color: #ffffff; 80 | height: 200px; 81 | width:99%; 82 | } 83 | 84 | /* 85 | * Content --------------------- 86 | */ 87 | #content { 88 | background-color: #1c1c1c; 89 | border: 1px solid #353535; 90 | border-radius: 5px; 91 | -moz-border-radius: 5px; 92 | -webkit-border-radius: 5px; 93 | color: #ffffff; 94 | float: left; 95 | font-size: 8pt; 96 | margin: 10px; 97 | padding: 10px; 98 | padding-top: 2px; 99 | width: 580px; 100 | } 101 | #content blockquote { 102 | background-color: #333; 103 | border: 1px solid #555; 104 | font-style: italic; 105 | margin: 5px; 106 | padding: 5px; 107 | } 108 | #content div.buttons a { 109 | background: url('../images/header_bg.png') repeat-x left bottom; 110 | border: 2px solid #353535; 111 | border-radius: 3px; 112 | -moz-border-radius: 3px; 113 | -webkit-border-radius: 3px; 114 | color: #e9a800; 115 | display: block; 116 | float: left; 117 | margin: 2px; 118 | padding: 5px; 119 | text-align: center; 120 | width: 80px; 121 | } 122 | #content div.buttons a:hover { 123 | border: 2px solid #e9a800; 124 | } 125 | #content div.contentbox { 126 | clear: both; 127 | padding-bottom: 15px; 128 | padding-top: 5px; 129 | } 130 | #content div.contentinfo { 131 | float: right; 132 | text-align: right; 133 | } 134 | #content div.contentinfobox { 135 | border-top: 1px solid #555555; 136 | clear: both; 137 | color: #999999; 138 | font-size: 7pt; 139 | line-height: 12px; 140 | margin-top: 2px; 141 | padding-bottom: 10px; 142 | } 143 | #content div.contentinfobox a { 144 | border: 0px; 145 | color: #999999; 146 | } 147 | #content div.contentinfobox a:hover { 148 | border-bottom: 1px solid #888888; 149 | color: #999999; 150 | } 151 | #content div.contentitem { 152 | padding-left: 5px; 153 | padding-top: 8px; 154 | overflow-y: hidden; 155 | } 156 | #content div.contenttags { 157 | float: left; 158 | } 159 | 160 | #content span.highlight { 161 | color: #e9a800; 162 | } 163 | 164 | #content img { 165 | padding: 5px; 166 | vertical-align: top; 167 | } 168 | 169 | #content h1, #content h1 a { 170 | border-bottom: 1px solid #e9a800; 171 | font-size: 10pt; 172 | padding-left: 2px; 173 | } 174 | #content h1 a { 175 | border-bottom: 0; 176 | } 177 | #content h2 { 178 | border-bottom: 1px solid #e9a800; 179 | font-size: 9pt; 180 | } 181 | #content h3 { 182 | border-bottom: 1px solid #e9a800; 183 | font-size: 10pt; 184 | } 185 | #content h3 a { 186 | border: 0px; 187 | color: #ffffff; 188 | } 189 | #content h3 a:hover { 190 | color: #e9a800; 191 | } 192 | #content p { 193 | padding: 5px; 194 | line-height: 15px; 195 | } 196 | #content table td { 197 | vertical-align: top; 198 | } 199 | 200 | /* 201 | * Header ---------------------- 202 | */ 203 | #header { 204 | background: url('../images/header_bg.png') repeat-x left top; 205 | height: 77px; 206 | margin-left: auto; 207 | margin-right: auto; 208 | width: 900px; 209 | } 210 | #header a { 211 | border: 0px; 212 | } 213 | 214 | /* 215 | * Footer ---------------------- 216 | */ 217 | #footer { 218 | background: url('../images/footer_bg.png') repeat-x left top; 219 | border-bottom-left-radius: 8px; 220 | border-bottom-right-radius: 8px; 221 | -moz-border-radius-bottomleft: 8px; 222 | -moz-border-radius-bottomright: 8px; 223 | -webkit-border-bottom-left-radius: 8px; 224 | -webkit-border-bottom-right-radius: 8px; 225 | clear: both; 226 | color: #cecece; 227 | font-size: 7pt; 228 | height: 77px; 229 | line-height: 12px; 230 | margin-left: auto; 231 | margin-right: auto; 232 | overflow: hidden; 233 | text-align: justify; 234 | width: 900px; 235 | } 236 | #footer a { 237 | color: #cecece; 238 | } 239 | #footer div.disclaimer { 240 | float: left; 241 | padding-left: 10px; 242 | padding-top: 10px; 243 | width: 550px; 244 | 245 | } 246 | #footer div.gauges { 247 | float: right; 248 | padding-top: 10px; 249 | padding-right: 5px; 250 | overflow: hidden; 251 | } 252 | 253 | /* 254 | * Highscores ------------------ 255 | */ 256 | #highscores li { 257 | color: #ffffff; 258 | font-size: 8pt; 259 | font-weight: bold; 260 | text-align: center; 261 | } 262 | 263 | #highscores div.score { 264 | float: left; 265 | width: 50%; 266 | } 267 | #highscores div.name { 268 | float: right; 269 | width: 50%; 270 | } 271 | /* 272 | * Main ------------------------ 273 | */ 274 | #main { 275 | margin-left: auto; 276 | margin-right: auto; 277 | min-height: 550px; 278 | width: 900px; 279 | } 280 | 281 | /* 282 | * MAngband -------------------- 283 | */ 284 | #mangband table { 285 | border: 1px solid #444444; 286 | border-radius: 5px; 287 | -moz-border-radius: 5px; 288 | -webkit-border-radius: 5px; 289 | width: 100%; 290 | } 291 | #mangband td { 292 | background-color: #444444; 293 | padding: 5px; 294 | text-align: center; 295 | } 296 | #mangband th { 297 | padding: 5px; 298 | border-bottom: 1px solid #999999; 299 | } 300 | 301 | #mangband table.mangwindow { 302 | background-color: #000000; 303 | border: 1px solid #444444; 304 | border-radius: 0px; 305 | -moz-border-radius: 0px; 306 | -webkit-border-radius: 0px; 307 | font-family: fixed; 308 | font-size: 8pt; 309 | font-weight: normal; 310 | line-height: 15px; 311 | width: 100%; 312 | } 313 | #mangband table.mangwindow td { 314 | background-color: #000000; 315 | padding: 0px; 316 | padding-left: 3px; 317 | text-align: left; 318 | } 319 | #mangband table.mangwindow td.blue {color: #00C8FF;} 320 | #mangband table.mangwindow td.green {color: #00FF00;} 321 | #mangband table.mangwindow td.red {color: #FF0000;} 322 | #mangband table.mangwindow td.yellow {color: #FFFD00;} 323 | #mangband table.mangwindow td span.f_sep {color: #FFFFFF;} 324 | 325 | #mangband span {font-weight: bold;} 326 | #mangband span.mage, #sidebar span.mage {color: #FF0000;} 327 | #mangband span.priest, #sidebar span.priest {color: #00DD00;} 328 | #mangband span.paladin, #sidebar span.paladin {color: #0056c6;} 329 | #mangband span.ranger, #sidebar span.ranger {color: #ffffff;} 330 | #mangband span.rouge, #sidebar span.rouge {color: #0000FF;} 331 | #mangband span.warrior, #sidebar span.warrior {color: #AA4700;} 332 | 333 | /* 334 | * Navbar ---------------------- 335 | */ 336 | #navbar { 337 | background: url('../images/navbar_bg.png') no-repeat left top; 338 | background-color: #121212; 339 | border-bottom: 1px solid #999999; 340 | font-size: 9pt; 341 | font-weight: bold; 342 | height: 29px; 343 | margin-left: auto; 344 | margin-right: auto; 345 | overflow: hidden; 346 | width: 900px; 347 | } 348 | #navbar a { 349 | color: #ffffff; 350 | height: 29px; 351 | line-height: 29px; 352 | text-decoration: none; 353 | border: 0; 354 | } 355 | #navbar a.active { 356 | color: #E9A800; 357 | } 358 | #navbar ul { 359 | list-style-type: none; 360 | } 361 | #navbar li { 362 | float: left; 363 | line-height: 29px; 364 | padding-left: 10px; 365 | } 366 | #navbar li a:hover { 367 | color: #E9A800; 368 | } 369 | /* 370 | * Pagination ------------------ 371 | */ 372 | #pagination { 373 | font-size: 130%; 374 | padding-top: 20px; 375 | width: 100%; 376 | } 377 | #pagination a { 378 | border: 0; 379 | color: #ccc; 380 | } 381 | #pagination a:hover { 382 | border-bottom: 1px dotted #e9a800; 383 | } 384 | #pagination .newer { 385 | float: left; 386 | } 387 | #pagination .older { 388 | float: right; 389 | } 390 | /* 391 | * Sidebar --------------------- 392 | */ 393 | #sb_toggle { 394 | background:url('../images/sb_arrows.png') no-repeat left top; 395 | float: right; 396 | height: 29px; 397 | width: 34px; 398 | } 399 | #sidebar { 400 | float: right; 401 | height: 100%; 402 | padding-left: 10px; 403 | padding-right: 15px; 404 | padding-top: 10px; 405 | text-align: center; 406 | width: 250px; 407 | } 408 | #sidebar div.sidebarbody { 409 | color: #dddddd; 410 | font-size: 8pt; 411 | padding: 5px; 412 | } 413 | #sidebar div.sidebaritem { 414 | background-color: #353535; 415 | border: 1px solid #444444; 416 | border-radius: 5px; 417 | -moz-border-radius: 5px; 418 | -webkit-border-radius: 5px; 419 | width: 100%; 420 | } 421 | #sidebar h4 { 422 | background: url('../images/header_bg.png') repeat-x left bottom; 423 | border-bottom: 1px solid #999999; 424 | border-top-left-radius: 5px; 425 | border-top-right-radius: 5px; 426 | -moz-border-radius-topleft: 5px; 427 | -moz-border-radius-topright: 5px; 428 | -webkit-border-top-left-radius: 5px; 429 | -webkit-border-top-right-radius: 5px; 430 | color: #ffffff; 431 | font-size: 9pt; 432 | line-height: 15px; 433 | } 434 | #sidebar h4 img { 435 | vertical-align: middle; 436 | } 437 | #sidebar a { 438 | color: #ffffff; 439 | border: 0; 440 | } 441 | /* 442 | * Steam stuff ----------------- 443 | */ 444 | table.steambox { 445 | border: 2px solid #111111; 446 | vertical-align: top; 447 | } 448 | table.steambox th { 449 | background-color: #111111; 450 | } 451 | table.steambox td { 452 | vertical-align: top; 453 | } 454 | table.steambox td.label { 455 | color: #e9a800; 456 | } 457 | 458 | #steamcommunity, #steamgamefinder_members, #steamgamefinder_games_loading { 459 | display: none; 460 | } 461 | #steamgamefinder_games_loading { 462 | text-align: center; 463 | width: 570px; 464 | } 465 | #steamcommunity a, table.steambox a { 466 | text-decoration: none; 467 | border: 0; 468 | } 469 | #steamcommunity img, 470 | #content table.steambox img, 471 | #steamgamefinder_members img { 472 | border-radius: 5px; 473 | -moz-border-radius: 5px; 474 | -webkit-border-radius: 5px; 475 | margin: 2px; 476 | } 477 | #steamcommunity img.in-game, 478 | #content table.steambox img.in-game, 479 | #steamgamefinder_members img.in-game { 480 | border: 3px solid #91c34a; 481 | } 482 | #steamcommunity img.offline, 483 | #content table.steambox img.offline, 484 | #steamgamefinder_members img.offline { 485 | border: 3px solid #777777; 486 | } 487 | #steamcommunity img.online, 488 | #content table.steambox img.online, 489 | #steamgamefinder_members img.online { 490 | border: 3px solid #89cbfb; 491 | } 492 | 493 | #steamcommunity img.selected, 494 | #content table.steambox img.selected, 495 | #steamgamefinder_members img.selected { 496 | border: 3px solid #e9a800; 497 | } 498 | 499 | #steamgamefinder_members img { 500 | cursor: pointer; 501 | margin: 1px; 502 | } 503 | 504 | #steamgamefinder_games div.gameline { 505 | background-color: #222; 506 | border: 2px solid #333; 507 | border-radius: 2px; 508 | -moz-border-radius: 2px; 509 | -webkit-border-radius: 2px; 510 | clear:both; 511 | height: 79px; 512 | margin: 4px; 513 | width: 570px; 514 | } 515 | #steamgamefinder_games div.gameline:hover { 516 | border: 2px solid #e9a800; 517 | } 518 | #steamgamefinder_games div.gamelogo { 519 | float: left; 520 | margin-top: 2px; 521 | margin-left: 2px; 522 | width: 190px; 523 | } 524 | #steamgamefinder_games div.gamelogo img { 525 | border: 3px solid #333; 526 | border-radius: 2px; 527 | -moz-border-radius: 2px; 528 | -webkit-border-radius: 2px; 529 | } 530 | #steamgamefinder_games div.gameinfo { 531 | float: right; 532 | font-size: 10pt; 533 | height: 79px; 534 | margin-top: 2px; 535 | text-align: left; 536 | width: 360px; 537 | } 538 | #steamgamefinder_games div.gamename { 539 | height: 40px; 540 | } 541 | #steamgamefinder_games div.alsoownsthisgame { 542 | height: 30px; 543 | font-size: 8pt; 544 | vertical-align: middle; 545 | } 546 | #steamgamefinder_games div.alsoownsthisgame img { 547 | vertical-align: middle; 548 | } 549 | /* 550 | * Table of Contents ----------- 551 | */ 552 | #toc { 553 | border: 1px solid #888888; 554 | font-size: 7pt; 555 | line-height: 12px; 556 | margin: 5px; 557 | padding: 5px; 558 | width: 210px; 559 | } 560 | 561 | #toc h2 { 562 | border: 0px; 563 | font-size: 9pt; 564 | text-align: center; 565 | } 566 | 567 | /* 568 | * Tag Cloud ------------------- 569 | */ 570 | #tags a.small { 571 | font-size: 70%; 572 | color: #999; 573 | } 574 | #tags a.medium { 575 | font-size: 110%; 576 | color: #bbb; 577 | } 578 | #tags a.large { 579 | font-size: 145%; 580 | font-weight: bold; 581 | } 582 | 583 | /* 584 | * Page Wrapper ---------------- 585 | */ 586 | #wrapper { 587 | background: url('../images/wrapper_bg.png') repeat-y left top; 588 | border-radius: 10px; 589 | -moz-border-radius: 10px; 590 | -webkit-border-radius: 10px; 591 | border-top: 0;; 592 | margin-left: auto; 593 | margin-right: auto; 594 | min-height: 100%; 595 | width: 1000px; 596 | } 597 | /* 598 | * Misc Bits ------------------- 599 | */ 600 | span.poweredby { 601 | color: #ffffff; 602 | font-size: 7pt; 603 | } 604 | div.spacer { 605 | height: 1px; 606 | padding: 2px; 607 | width: 1px; 608 | } 609 | 610 | div.clearfix { 611 | clear: both; 612 | } 613 | 614 | ::-moz-selection{ background: #e9a800; color:#000; text-shadow: none; } 615 | ::selection { background:#e9a800; color:#000; text-shadow: none; } 616 | 617 | -------------------------------------------------------------------------------- /examples/pewpew/css/pewpew.css: -------------------------------------------------------------------------------- 1 | #pewpew div.canvasbox { 2 | border: 4px solid #000; 3 | border-top: 20px solid #000; 4 | border-bottom: 20px solid #000; 5 | width: 640px; 6 | } 7 | 8 | #pewpew div.leveldrain { 9 | background-image: url('../images/jui/pbar-ani.gif'); 10 | } 11 | 12 | #pewpew div.lbar { 13 | width: 100px; 14 | height: 10px; 15 | } 16 | 17 | #pewpew .ui-widget-header { 18 | border: 1px solid #e78f08; 19 | background: #f6a828 url('../images/jui/ui-bg_gloss-wave_35_f6a828_500x100.png') 50% 50% repeat-x; 20 | color: #ffffff; 21 | font-weight: bold; 22 | } 23 | 24 | #pewpew p.levels { 25 | font-weight: bold; 26 | font-size: 140%; 27 | color: #e9a800; 28 | } 29 | 30 | #pewpew .retro { 31 | border: 1px solid #00ff00; 32 | } 33 | 34 | #pewpew .retrolevels { 35 | background-image: none; 36 | background-color: #00ff00; 37 | border: 1px solid #00ff00; 38 | } 39 | 40 | #pewpew .retrotext { 41 | font-weight: bold; 42 | font-size: 140%; 43 | color: #00ff00; 44 | } 45 | -------------------------------------------------------------------------------- /examples/pewpew/css/reset.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ */ 2 | /* v1.0 | 20080212 */ 3 | 4 | html, body, div, span, applet, object, iframe, 5 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 6 | a, abbr, acronym, address, big, cite, code, 7 | del, dfn, em, font, img, ins, kbd, q, s, samp, 8 | small, strike, strong, sub, sup, tt, var, 9 | b, u, i, center, 10 | dl, dt, dd, ol, ul, li, 11 | fieldset, form, label, legend, 12 | caption, tbody, tfoot, thead, tr, th, td { 13 | margin: 0; 14 | padding: 0; 15 | border: 0; 16 | outline: 0; 17 | font-size: 100%; 18 | vertical-align: baseline; 19 | background: transparent; 20 | } 21 | body { 22 | line-height: 1; 23 | } 24 | ol, ul { 25 | list-style: none; 26 | } 27 | blockquote, q { 28 | quotes: none; 29 | } 30 | blockquote:before, blockquote:after, 31 | q:before, q:after { 32 | content: ''; 33 | content: none; 34 | } 35 | 36 | /* remember to define focus styles! */ 37 | :focus { 38 | outline: 0; 39 | } 40 | 41 | /* remember to highlight inserts somehow! */ 42 | ins { 43 | text-decoration: none; 44 | } 45 | del { 46 | text-decoration: line-through; 47 | } 48 | -------------------------------------------------------------------------------- /examples/pewpew/highscores.itf: -------------------------------------------------------------------------------- 1 | [["343200","spoo"],["252000","omeh"],["246400","omeh"],["232800","omeh"],["179600","omeh"]] 2 | -------------------------------------------------------------------------------- /examples/pewpew/images/body_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing-js/processing-mobile/407ee0b54a400ba299aa2c0e277bdaaedaa327c1/examples/pewpew/images/body_bg.png -------------------------------------------------------------------------------- /examples/pewpew/images/jui/pbar-ani.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing-js/processing-mobile/407ee0b54a400ba299aa2c0e277bdaaedaa327c1/examples/pewpew/images/jui/pbar-ani.gif -------------------------------------------------------------------------------- /examples/pewpew/images/jui/ui-bg_gloss-wave_35_f6a828_500x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing-js/processing-mobile/407ee0b54a400ba299aa2c0e277bdaaedaa327c1/examples/pewpew/images/jui/ui-bg_gloss-wave_35_f6a828_500x100.png -------------------------------------------------------------------------------- /examples/pewpew/images/jui/ui-bg_inset-soft_25_000000_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing-js/processing-mobile/407ee0b54a400ba299aa2c0e277bdaaedaa327c1/examples/pewpew/images/jui/ui-bg_inset-soft_25_000000_1x100.png -------------------------------------------------------------------------------- /examples/pewpew/images/wrapper_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/processing-js/processing-mobile/407ee0b54a400ba299aa2c0e277bdaaedaa327c1/examples/pewpew/images/wrapper_bg.png -------------------------------------------------------------------------------- /examples/pewpew/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Pew Pew! 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 |
23 |
24 |
25 | 26 | 27 | 30 | 31 | 32 | 33 | 38 | 46 | 52 | 53 | 54 | 62 | 63 | 64 | 71 | 72 |
28 |

Pew Pew!!

29 |
34 |

35 | Shield

36 |

37 |
39 | 40 |

41 | Lives    42 | Level
43 | Score 44 |

45 |
47 | 48 |

49 | Beam

50 |

51 |
55 |
56 | 57 | 58 | Your 59 | Browser doesn't support Canvas 60 | 61 |
65 | Controls : 66 | N = New Game / P = Pause / R = Retro Mode
67 | 68 | W = Thrust / Mouse1 = PEW! / Mouse2 = Beam / 69 | Mouse 3 or S = Shield

70 |
73 |
74 |
75 |
76 |
77 | 78 | 79 | -------------------------------------------------------------------------------- /examples/pewpew/input.js: -------------------------------------------------------------------------------- 1 | /* 2 | Input.js is MIT-licensed software 3 | Copyright (c) 2011 Jon Buckley 4 | */ 5 | 6 | (function() { 7 | // Holds all of the physical device to USB enumeration mappings 8 | var keymapBlob = { 9 | '45e' : { /* Microsoft */ 10 | '28e' : { /* Xbox 360 controller */ 11 | 'Mac' : { 12 | 'axes' : { 13 | 'Left_Stick_X': 0, 14 | 'Left_Stick_Y': 1, 15 | 'Right_Stick_X': 2, 16 | 'Right_Stick_Y': 3, 17 | 'Left_Trigger_2': [4, -1, 1], 18 | 'Right_Trigger_2': [5, -1, 1] 19 | }, 20 | 'buttons' : { 21 | 'A_Button': 0, 22 | 'B_Button': 1, 23 | 'X_Button': 2, 24 | 'Y_Button': 3, 25 | 'Left_Trigger_1': 4, 26 | 'Right_Trigger_1': 5, 27 | 'Left_Stick_Button': 6, 28 | 'Right_Stick_Button': 7, 29 | 'Start_Button': 8, 30 | 'Back_Button': 9, 31 | 'Home_Button': 10, 32 | 'Pad_Up': 11, 33 | 'Pad_Down': 12, 34 | 'Pad_Left': 13, 35 | 'Pad_Right': 14 36 | } 37 | }, 38 | "Win": { 39 | "axes": { 40 | "Left_Stick_X": 0, 41 | "Left_Stick_Y": 1, 42 | "Right_Stick_X": 3, 43 | "Right_Stick_Y": 4, 44 | "Pad_Left": [5, -1, 0], 45 | "Pad_Right": [5, 0, 1], 46 | "Pad_Up": [6, -1, 0], 47 | "Pad_Down": [6, 0, 1], 48 | "Left_Trigger_2": [2, 0, 1], 49 | "Right_Trigger_2": [2, -1, 0] 50 | }, 51 | "buttons": { 52 | "A_Button": 0, 53 | "B_Button": 1, 54 | "X_Button": 2, 55 | "Y_Button": 3, 56 | "Left_Trigger_1": 4, 57 | "Right_Trigger_1": 5, 58 | "Back_Button": 6, 59 | "Start_Button": 7, 60 | "Left_Stick_Button": 8, 61 | "Right_Stick_Button": 9 62 | } 63 | } 64 | } 65 | }, 66 | "54c": { /* Sony */ 67 | "268": { /* PS3 Controller */ 68 | "Mac": { 69 | "axes": { 70 | "Left_Stick_X": 0, 71 | "Left_Stick_Y": 1, 72 | "Right_Stick_X": 2, 73 | "Right_Stick_Y": 3 74 | }, 75 | "buttons": { 76 | "Back_Button": 0, 77 | "Left_Stick_Button": 1, 78 | "Right_Stick_Button": 2, 79 | "Start_Button": 3, 80 | "Pad_Up": 4, 81 | "Pad_Down": 6, 82 | "Pad_Right": 5, 83 | "Pad_Left": 7, 84 | "Left_Trigger_2": 8, 85 | "Right_Trigger_2": 9, 86 | "Left_Trigger_1": 10, 87 | "Right_Trigger_1": 11, 88 | "Y_Button": 12, 89 | "B_Button": 13, 90 | "A_Button": 14, 91 | "X_Button": 15, 92 | "Home_Button": 16 93 | } 94 | } 95 | } 96 | }, 97 | "46d": { /* Logitech */ 98 | "c242": { /* Chillstream */ 99 | "Win": { 100 | "axes": { 101 | "Left_Stick_X": 0, 102 | "Left_Stick_Y": 1, 103 | "Right_Stick_Y": 4, 104 | "Right_Stick_X": 3, 105 | "Left_Trigger_2": [2, 0, 1], 106 | "Right_Trigger_2": [2, -1, 0], 107 | "Pad_Left": [5, -1, 0], 108 | "Pad_Right": [5, 0, 1], 109 | "Pad_Up": [6, -1, 0], 110 | "Pad_Down": [6, 0, 1] 111 | }, 112 | "buttons": { 113 | "A_Button": 0, 114 | "X_Button": 2, 115 | "B_Button": 1, 116 | "Y_Button": 3, 117 | "Left_Trigger_1": 4, 118 | "Right_Trigger_1": 5, 119 | "Back_Button": 6, 120 | "Start_Button": 7, 121 | "Left_Stick_Button": 8, 122 | "Right_Stick_Button": 9 123 | } 124 | } 125 | }, 126 | "c216": { /* Dual Action */ 127 | "Mac": { 128 | "axes": { 129 | "Left_Stick_X": 1, 130 | "Left_Stick_Y": 2, 131 | "Right_Stick_X": 3, 132 | "Right_Stick_Y": 4, 133 | "Pad_Left": [1, 0, -1], 134 | "Pad_Right": [1, 0, 1], 135 | "Pad_Up": [2, 0, -1], 136 | "Pad_Down": [2, 0, 1] 137 | }, 138 | "buttons": { 139 | "X_Button": 0, 140 | "A_Button": 1, 141 | "B_Button": 2, 142 | "Y_Button": 3, 143 | "Left_Trigger_1": 4, 144 | "Right_Trigger_1": 5, 145 | "Left_Trigger_2": 6, 146 | "Right_Trigger_2": 7, 147 | "Back_Button": 8, 148 | "Start_Button": 9, 149 | "Left_Stick_Button": 10, 150 | "Right_Stick_Button": 11 151 | } 152 | } 153 | } 154 | }, 155 | "40b": { 156 | "6533": { /* USB 2A4K GamePad */ 157 | "Mac": { 158 | "axes": { 159 | "Pad_Left": [0, 0, -1], 160 | "Pad_Right": [0, 0, 1], 161 | "Pad_Up": [1, 0, -1], 162 | "Pad_Down": [1, 0, 1] 163 | }, 164 | "buttons": { 165 | "A_Button": 0, 166 | "B_Button": 1, 167 | "X_Button": 2, 168 | "Y_Button": 3 169 | } 170 | } 171 | } 172 | }, 173 | "Firefox": { 174 | "Fake Gamepad": { 175 | "Mac": { 176 | "axes": { 177 | 178 | }, 179 | "buttons": { 180 | 'A_Button' : 0, 181 | 'B_Button' : 1, 182 | 'X_Button' : 2, 183 | 'Y_Button' : 3, 184 | 'Pad_Up' : 4, 185 | 'Pad_Down': 5, 186 | 'Pad_Left': 6, 187 | 'Pad_Right': 7 188 | } 189 | } 190 | } 191 | } 192 | 193 | }; 194 | 195 | // Our ideal gamepad that we present to the developer 196 | var ImaginaryGamepad = { 197 | 'axes' : [ 198 | 'Left_Stick_X', 199 | 'Left_Stick_Y', 200 | 'Right_Stick_X', 201 | 'Right_Stick_Y' 202 | ], 203 | 'buttons' : [ 204 | 'A_Button', 205 | 'B_Button', 206 | 'X_Button', 207 | 'Y_Button', 208 | 'Left_Stick_Button', 209 | 'Right_Stick_Button', 210 | 'Start_Button', 211 | 'Back_Button', 212 | 'Home_Button', 213 | 'Pad_Up', 214 | 'Pad_Down', 215 | 'Pad_Left', 216 | 'Pad_Right', 217 | 'Left_Trigger_1', 218 | 'Right_Trigger_1', 219 | 'Left_Trigger_2', 220 | 'Right_Trigger_2' 221 | ] 222 | }; 223 | 224 | var osList = ['Win', 'Mac', 'Linux']; 225 | function detectOS() { 226 | for (var i in osList) { 227 | if (navigator.platform.indexOf(osList[i]) !== -1) { 228 | return osList[i]; 229 | } 230 | } 231 | return 'Unknown'; 232 | } 233 | 234 | function map(value, istart, istop, ostart, ostop) { 235 | return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)); 236 | }; 237 | 238 | // Map imaginary device action to physical device action 239 | function mapAxisToAxis(device, keymap, axes, prop) { 240 | Object.defineProperty(axes, prop, { 241 | enumerable: true, 242 | get: function() { return device.axes[keymap.axes[prop]]; } 243 | }); 244 | } 245 | 246 | function mapAxisToButton(device, keymap, axes, prop) { 247 | Object.defineProperty(axes, prop, { 248 | enumerable: true, 249 | get: function() { return 0; } 250 | }); 251 | } 252 | 253 | function mapButtonToButton(device, keymap, buttons, prop) { 254 | Object.defineProperty(buttons, prop, { 255 | enumerable: true, 256 | get: function() { return device.buttons[keymap.buttons[prop]]; } 257 | }); 258 | } 259 | 260 | function mapButtonToAxis(device, keymap, buttons, prop) { 261 | var transform = keymap.axes[prop] instanceof Array; 262 | 263 | Object.defineProperty(buttons, prop, { 264 | enumerable: true, 265 | get: function() { 266 | if (transform) { 267 | return map(device.axes[keymap.axes[prop][0]], keymap.axes[prop][1], keymap.axes[prop][2], 0, 1); 268 | } else { 269 | return device.axes[keymap.axes[prop]]; 270 | } 271 | } 272 | }); 273 | } 274 | 275 | function mapZero(type, prop) { 276 | Object.defineProperty(type, prop, { 277 | enumerable: true, 278 | get: function() { return 0; } 279 | }); 280 | } 281 | 282 | var Input = window.Input = {}; 283 | var Device = Input.Device = function(domGamepad) { 284 | if (!domGamepad) { 285 | throw "You didn't pass a valid gamepad to the constructor"; 286 | } 287 | 288 | var device = domGamepad, 289 | usbVendor = domGamepad.id.split('-')[0], 290 | usbDevice = domGamepad.id.split('-')[1], 291 | os = detectOS(), 292 | keymap = keymapBlob, 293 | axes = this.axes = {}, 294 | buttons = this.buttons = {}; 295 | 296 | if (keymap && keymap[usbVendor] && keymap[usbVendor][usbDevice] && keymap[usbVendor][usbDevice][os]) { 297 | keymap = keymap[usbVendor][usbDevice][os]; 298 | } else { 299 | throw "A physical device layout for " + usbVendor + "-" + usbDevice + "-" + os + " isn't available"; 300 | } 301 | 302 | // Wire the axes and buttons up 303 | for (var a in ImaginaryGamepad.axes) { 304 | if (keymap.axes[ImaginaryGamepad.axes[a]] !== undefined) { 305 | mapAxisToAxis(device, keymap, axes, ImaginaryGamepad.axes[a]); 306 | } else if (keymap.buttons[ImaginaryGamepad.axes[a]] !== undefined) { 307 | mapAxisToButton(device, keymap, axes, ImaginaryGamepad.axes[a]); 308 | } else { 309 | mapZero(axes, ImaginaryGamepad.axes[a]); 310 | } 311 | } 312 | 313 | for (var b in ImaginaryGamepad.buttons) { 314 | if (keymap.buttons[ImaginaryGamepad.buttons[b]] !== undefined) { 315 | mapButtonToButton(device, keymap, buttons, ImaginaryGamepad.buttons[b]); 316 | } else if (keymap.axes[ImaginaryGamepad.buttons[b]] !== undefined) { 317 | mapButtonToAxis(device, keymap, buttons, ImaginaryGamepad.buttons[b]); 318 | } else { 319 | mapZero(buttons, ImaginaryGamepad.buttons[b]); 320 | } 321 | } 322 | 323 | // Add some useful properties from the DOMGamepad object 324 | Object.defineProperty(this, "connected", { 325 | enumerable: true, 326 | get: function() { return device.connected; } 327 | }); 328 | 329 | Object.defineProperty(this, "id", { 330 | enumerable: true, 331 | get: function() { return device.id; } 332 | }); 333 | 334 | Object.defineProperty(this, "index", { 335 | enumerable: true, 336 | get: function() { return device.index; } 337 | }); 338 | }; 339 | }()); 340 | -------------------------------------------------------------------------------- /examples/pewpew/jquery.hotkeys-0.7.9.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery Hotkeys Plugin 3 | * Copyright 2010, John Resig 4 | * Dual licensed under the MIT or GPL Version 2 licenses. 5 | * 6 | * Based upon the plugin by Tzury Bar Yochay: 7 | * http://github.com/tzuryby/hotkeys 8 | * 9 | * Original idea by: 10 | * Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/ 11 | */ 12 | 13 | (function(jQuery){ 14 | 15 | jQuery.hotkeys = { 16 | version: "0.8", 17 | 18 | specialKeys: { 19 | 8: "backspace", 9: "tab", 13: "return", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause", 20 | 20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home", 21 | 37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del", 22 | 96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7", 23 | 104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/", 24 | 112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8", 25 | 120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 191: "/", 224: "meta" 26 | }, 27 | 28 | shiftNums: { 29 | "`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&", 30 | "8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ": ", "'": "\"", ",": "<", 31 | ".": ">", "/": "?", "\\": "|" 32 | } 33 | }; 34 | 35 | function keyHandler( handleObj ) { 36 | // Only care when a possible input has been specified 37 | if ( typeof handleObj.data !== "string" ) { 38 | return; 39 | } 40 | 41 | var origHandler = handleObj.handler, 42 | keys = handleObj.data.toLowerCase().split(" "); 43 | 44 | handleObj.handler = function( event ) { 45 | // Don't fire in text-accepting inputs that we didn't directly bind to 46 | if ( this !== event.target && (/textarea|select/i.test( event.target.nodeName ) || 47 | event.target.type === "text") ) { 48 | return; 49 | } 50 | 51 | // Keypress represents characters, not special keys 52 | var special = event.type !== "keypress" && jQuery.hotkeys.specialKeys[ event.which ], 53 | character = String.fromCharCode( event.which ).toLowerCase(), 54 | key, modif = "", possible = {}; 55 | 56 | // check combinations (alt|ctrl|shift+anything) 57 | if ( event.altKey && special !== "alt" ) { 58 | modif += "alt+"; 59 | } 60 | 61 | if ( event.ctrlKey && special !== "ctrl" ) { 62 | modif += "ctrl+"; 63 | } 64 | 65 | // TODO: Need to make sure this works consistently across platforms 66 | if ( event.metaKey && !event.ctrlKey && special !== "meta" ) { 67 | modif += "meta+"; 68 | } 69 | 70 | if ( event.shiftKey && special !== "shift" ) { 71 | modif += "shift+"; 72 | } 73 | 74 | if ( special ) { 75 | possible[ modif + special ] = true; 76 | 77 | } else { 78 | possible[ modif + character ] = true; 79 | possible[ modif + jQuery.hotkeys.shiftNums[ character ] ] = true; 80 | 81 | // "$" can be triggered as "Shift+4" or "Shift+$" or just "$" 82 | if ( modif === "shift+" ) { 83 | possible[ jQuery.hotkeys.shiftNums[ character ] ] = true; 84 | } 85 | } 86 | 87 | for ( var i = 0, l = keys.length; i < l; i++ ) { 88 | if ( possible[ keys[i] ] ) { 89 | return origHandler.apply( this, arguments ); 90 | } 91 | } 92 | }; 93 | } 94 | 95 | jQuery.each([ "keydown", "keyup", "keypress" ], function() { 96 | jQuery.event.special[ this ] = { add: keyHandler }; 97 | }); 98 | 99 | })( jQuery ); 100 | -------------------------------------------------------------------------------- /examples/pewpew/pewpew.js: -------------------------------------------------------------------------------- 1 | /* 2 | * int13h Javascript for Pew Pew 3 | */ 4 | $(document).ready(function(){ 5 | $("#shieldlevel").progressbar({value: 100}); 6 | $("#beamlevel").progressbar({value: 100}); 7 | 8 | // Stop cursor highlight 9 | document.onselectstart=function(){return false;}; 10 | 11 | // Stop Backspace event 12 | $(document).keypress(function(event){ 13 | if(event.keyCode == 8) 14 | return false; 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /examples/processing-and-js/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Evolution of Processing/JavaScript Hybrids

4 | 5 |
    6 | 7 |
  1. A simple case study: Translation 8 | 9 |
  2. Pure Processing (.pde) 10 | 11 |
  3. Processing "compiled" to JavaScript (.js) 12 | 13 |
  4. Processing mixed with JavaScript (.pjs) 14 | 15 |
  5. Processing.js using external .pde files 16 | 17 |
  6. Processing.js using inline Processing code 18 | 19 |
  7. Processing.js sketch rewritten in pure JavaScript, using Processing.js as API 20 | 21 |
  8. Controlling a sketch from user interaction with HTML/JavaScript 22 | 23 |
  9. Processing.js mixed with JavaScript libraries: jQuery 24 | 25 |
  10. Fine control over sketch startup and initialization using jQuery 26 | 27 |
  11. Dynamic sketch creation using JavaScript, multiple sketches 28 | 29 |
  12. Sharing data between JavaScript and Processing 30 | 31 |
  13. Accessing data, functions within the sketch 32 | 33 |
  14. Access and alter data in a sketch from the DOM/JavaScript 34 |
35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /examples/processing-and-js/translation-data-html.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 |
89 | 90 |

Change the value of x

91 | 92 | 93 | -------------------------------------------------------------------------------- /examples/processing-and-js/translation-data-sketch.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 |
74 | 75 | 76 | -------------------------------------------------------------------------------- /examples/processing-and-js/translation-data-window.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /examples/processing-and-js/translation-fullscreen.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /examples/processing-and-js/translation-html.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
32 |

Some simple form interation from HTML that triggers things in the Processing sketch.

33 | 34 | 35 |
36 | 37 | 38 | -------------------------------------------------------------------------------- /examples/processing-and-js/translation-inline.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /examples/processing-and-js/translation-jquery.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 31 | 32 | 33 |
34 |

Some simple form interation from HTML that triggers things in the Processing sketch.

35 | 36 | 37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /examples/processing-and-js/translation-js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /examples/processing-and-js/translation-many-sketches.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 68 | 69 | 70 | 71 | 72 | 73 |
74 | 75 | 76 | -------------------------------------------------------------------------------- /examples/processing-and-js/translation.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/processing-and-js/translation.js: -------------------------------------------------------------------------------- 1 | // Converted Translation sketch from in JavaScript (Processing.compile) 2 | 3 | // this code was autogenerated from PJS 4 | (function($p) { 5 | 6 | var x = 0, 7 | y = 0; 8 | var dim = 80.0; 9 | 10 | function setup() { 11 | $p.size(640, 360); 12 | $p.noStroke(); 13 | } 14 | $p.setup = setup; 15 | 16 | function draw() { 17 | $p.background(102); 18 | 19 | x = x + 0.8; 20 | 21 | if (x > $p.width + dim) { 22 | x = -dim; 23 | } 24 | 25 | $p.translate(x, $p.height / 2 - dim / 2); 26 | $p.fill(255); 27 | $p.rect(-dim / 2, -dim / 2, dim, dim); 28 | 29 | $p.translate(x, dim); 30 | $p.fill(0); 31 | $p.rect(-dim / 2, -dim / 2, dim, dim); 32 | } 33 | $p.draw = draw; 34 | }) 35 | -------------------------------------------------------------------------------- /examples/processing-and-js/translation.pde: -------------------------------------------------------------------------------- 1 | // Original Translation sketch from processing.org 2 | float x, y; 3 | float dim = 80.0; 4 | 5 | void setup() { 6 | size(640, 360); 7 | noStroke(); 8 | } 9 | 10 | void draw() { 11 | background(102); 12 | 13 | x = x + 0.8; 14 | 15 | if (x > width + dim) { 16 | x = -dim; 17 | } 18 | 19 | translate(x, height/2-dim/2); 20 | fill(255); 21 | rect(-dim/2, -dim/2, dim, dim); 22 | 23 | // Transforms accumulate. Notice how this rect moves 24 | // twice as fast as the other, but it has the same 25 | // parameter for the x-axis value 26 | translate(x, dim); 27 | fill(0); 28 | rect(-dim/2, -dim/2, dim, dim); 29 | } 30 | -------------------------------------------------------------------------------- /examples/processing-and-js/translation.pjs: -------------------------------------------------------------------------------- 1 | // Original Translation sketch from processing.org 2 | 3 | // No data types, and everything still works! 4 | var x, y; 5 | var dim = 80.0; 6 | 7 | void setup() { 8 | size(640, 360); 9 | noStroke(); 10 | } 11 | 12 | void draw() { 13 | background(102); 14 | 15 | x = x + 0.8; 16 | 17 | if (x > width + dim) { 18 | x = -dim; 19 | } 20 | 21 | translate(x, height/2-dim/2); 22 | fill(255); 23 | rect(-dim/2, -dim/2, dim, dim); 24 | 25 | // Transforms accumulate. Notice how this rect moves 26 | // twice as fast as the other, but it has the same 27 | // parameter for the x-axis value 28 | translate(x, dim); 29 | fill(0); 30 | rect(-dim/2, -dim/2, dim, dim); 31 | } 32 | -------------------------------------------------------------------------------- /examples/processing-mobile/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Custom Device Motion Events in Processing.js 4 | 5 | 6 | 7 | 8 | 9 | 10 |

Device Motion Events in Processing.js for X and Y

11 | 12 |

New built-in types are added to Processing: motionX, motionY, motionZ. These are floats indicating the position of the device along the x, y, and z axis. Each has a value bewtween -1 and 1. Devices that do not support DeviceMotion events will have motionX == motionY == motionZ == 0 by default.

13 | 14 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /examples/tangle/Tangle-0.1.0/Tangle.js: -------------------------------------------------------------------------------- 1 | // 2 | // Tangle.js 3 | // Tangle 0.1.0 4 | // 5 | // Created by Bret Victor on 5/2/10. 6 | // (c) 2011 Bret Victor. MIT open-source license. 7 | // 8 | // ------ model ------ 9 | // 10 | // var tangle = new Tangle(rootElement, model); 11 | // tangle.setModel(model); 12 | // 13 | // ------ variables ------ 14 | // 15 | // var value = tangle.getValue(variableName); 16 | // tangle.setValue(variableName, value); 17 | // tangle.setValues({ variableName:value, variableName:value }); 18 | // 19 | // ------ UI components ------ 20 | // 21 | // Tangle.classes.myClass = { 22 | // initialize: function (element, options, tangle, variable) { ... }, 23 | // update: function (element, value) { ... } 24 | // }; 25 | // Tangle.formats.myFormat = function (value) { return "..."; }; 26 | // 27 | 28 | var Tangle = this.Tangle = function (rootElement, modelClass) { 29 | 30 | var tangle = this; 31 | tangle.element = rootElement; 32 | tangle.setModel = setModel; 33 | tangle.getValue = getValue; 34 | tangle.setValue = setValue; 35 | tangle.setValues = setValues; 36 | 37 | var _model; 38 | var _nextSetterID = 0; 39 | var _setterInfosByVariableName = {}; // { varName: { setterID:7, setter:function (v) { } }, ... } 40 | var _varargConstructorsByArgCount = []; 41 | 42 | 43 | //---------------------------------------------------------- 44 | // 45 | // construct 46 | 47 | initializeElements(); 48 | setModel(modelClass); 49 | return tangle; 50 | 51 | 52 | //---------------------------------------------------------- 53 | // 54 | // elements 55 | 56 | function initializeElements() { 57 | var elements = rootElement.getElementsByTagName("*"); 58 | var interestingElements = []; 59 | 60 | // build a list of elements with class or data-var attributes 61 | 62 | for (var i = 0, length = elements.length; i < length; i++) { 63 | var element = elements[i]; 64 | if (element.getAttribute("class") || element.getAttribute("data-var")) { 65 | interestingElements.push(element); 66 | } 67 | } 68 | 69 | // initialize interesting elements in this list. (Can't traverse "elements" 70 | // directly, because elements is "live", and views that change the node tree 71 | // will change elements mid-traversal.) 72 | 73 | for (var i = 0, length = interestingElements.length; i < length; i++) { 74 | var element = interestingElements[i]; 75 | 76 | var varNames = null; 77 | var varAttribute = element.getAttribute("data-var"); 78 | if (varAttribute) { varNames = varAttribute.split(" "); } 79 | 80 | var views = null; 81 | var classAttribute = element.getAttribute("class"); 82 | if (classAttribute) { 83 | var classNames = classAttribute.split(" "); 84 | views = getViewsForElement(element, classNames, varNames); 85 | } 86 | 87 | if (!varNames) { continue; } 88 | 89 | var didAddSetter = false; 90 | if (views) { 91 | for (var j = 0; j < views.length; j++) { 92 | if (!views[j].update) { continue; } 93 | addViewSettersForElement(element, varNames, views[j]); 94 | didAddSetter = true; 95 | } 96 | } 97 | 98 | if (!didAddSetter) { 99 | var formatAttribute = element.getAttribute("data-format"); 100 | var formatter = getFormatterForFormat(formatAttribute, varNames); 101 | addFormatSettersForElement(element, varNames, formatter); 102 | } 103 | } 104 | } 105 | 106 | function getViewsForElement(element, classNames, varNames) { // initialize classes 107 | var views = null; 108 | 109 | for (var i = 0, length = classNames.length; i < length; i++) { 110 | var clas = Tangle.classes[classNames[i]]; 111 | if (!clas) { continue; } 112 | 113 | var options = getOptionsForElement(element); 114 | var args = [ element, options, tangle ]; 115 | if (varNames) { args = args.concat(varNames); } 116 | 117 | var view = constructClass(clas, args); 118 | 119 | if (!views) { views = []; } 120 | views.push(view); 121 | } 122 | 123 | return views; 124 | } 125 | 126 | function getOptionsForElement(element) { // might use dataset someday 127 | var options = {}; 128 | 129 | var attributes = element.attributes; 130 | var regexp = /^data-[\w\-]+$/; 131 | 132 | for (var i = 0, length = attributes.length; i < length; i++) { 133 | var attr = attributes[i]; 134 | var attrName = attr.name; 135 | if (!attrName || !regexp.test(attrName)) { continue; } 136 | 137 | options[attrName.substr(5)] = attr.value; 138 | } 139 | 140 | return options; 141 | } 142 | 143 | function constructClass(clas, args) { 144 | if (typeof clas !== "function") { // class is prototype object 145 | var View = function () { }; 146 | View.prototype = clas; 147 | var view = new View(); 148 | if (view.initialize) { view.initialize.apply(view,args); } 149 | return view; 150 | } 151 | else { // class is constructor function, which we need to "new" with varargs (but no built-in way to do so) 152 | var ctor = _varargConstructorsByArgCount[args.length]; 153 | if (!ctor) { 154 | var ctorArgs = []; 155 | for (var i = 0; i < args.length; i++) { ctorArgs.push("args[" + i + "]"); } 156 | var ctorString = "(function (clas,args) { return new clas(" + ctorArgs.join(",") + "); })"; 157 | ctor = eval(ctorString); // nasty 158 | _varargConstructorsByArgCount[args.length] = ctor; // but cached 159 | } 160 | return ctor(clas,args); 161 | } 162 | } 163 | 164 | 165 | //---------------------------------------------------------- 166 | // 167 | // formatters 168 | 169 | function getFormatterForFormat(formatAttribute, varNames) { 170 | if (!formatAttribute) { formatAttribute = "default"; } 171 | 172 | var formatter = getFormatterForCustomFormat(formatAttribute, varNames); 173 | if (!formatter) { formatter = getFormatterForSprintfFormat(formatAttribute, varNames); } 174 | if (!formatter) { log("Tangle: unknown format: " + formatAttribute); formatter = getFormatterForFormat(null,varNames); } 175 | 176 | return formatter; 177 | } 178 | 179 | function getFormatterForCustomFormat(formatAttribute, varNames) { 180 | var components = formatAttribute.split(" "); 181 | var formatName = components[0]; 182 | if (!formatName) { return null; } 183 | 184 | var format = Tangle.formats[formatName]; 185 | if (!format) { return null; } 186 | 187 | var formatter; 188 | var params = components.slice(1); 189 | 190 | if (varNames.length <= 1 && params.length === 0) { // one variable, no params 191 | formatter = format; 192 | } 193 | else if (varNames.length <= 1) { // one variable with params 194 | formatter = function (value) { 195 | var args = [ value ].concat(params); 196 | return format.apply(null, args); 197 | }; 198 | } 199 | else { // multiple variables 200 | formatter = function () { 201 | var values = getValuesForVariables(varNames); 202 | var args = values.concat(params); 203 | return format.apply(null, args); 204 | }; 205 | } 206 | return formatter; 207 | } 208 | 209 | function getFormatterForSprintfFormat(formatAttribute, varNames) { 210 | if (!sprintf || !formatAttribute.test(/\%/)) { return null; } 211 | 212 | var formatter; 213 | if (varNames.length <= 1) { // one variable 214 | formatter = function (value) { 215 | return sprintf(formatAttribute, value); 216 | }; 217 | } 218 | else { 219 | formatter = function (value) { // multiple variables 220 | var values = getValuesForVariables(varNames); 221 | var args = [ formatAttribute ].concat(values); 222 | return sprintf.apply(null, args); 223 | }; 224 | } 225 | return formatter; 226 | } 227 | 228 | 229 | //---------------------------------------------------------- 230 | // 231 | // setters 232 | 233 | function addViewSettersForElement(element, varNames, view) { // element has a class with an update method 234 | var setter; 235 | if (varNames.length <= 1) { 236 | setter = function (value) { view.update(element, value); }; 237 | } 238 | else { 239 | setter = function () { 240 | var values = getValuesForVariables(varNames); 241 | var args = [ element ].concat(values); 242 | view.update.apply(view,args); 243 | }; 244 | } 245 | 246 | addSetterForVariables(setter, varNames); 247 | } 248 | 249 | function addFormatSettersForElement(element, varNames, formatter) { // tangle is injecting a formatted value itself 250 | var span = null; 251 | var setter = function (value) { 252 | if (!span) { 253 | span = document.createElement("span"); 254 | element.insertBefore(span, element.firstChild); 255 | } 256 | span.innerHTML = formatter(value); 257 | }; 258 | 259 | addSetterForVariables(setter, varNames); 260 | } 261 | 262 | function addSetterForVariables(setter, varNames) { 263 | var setterInfo = { setterID:_nextSetterID, setter:setter }; 264 | _nextSetterID++; 265 | 266 | for (var i = 0; i < varNames.length; i++) { 267 | var varName = varNames[i]; 268 | if (!_setterInfosByVariableName[varName]) { _setterInfosByVariableName[varName] = []; } 269 | _setterInfosByVariableName[varName].push(setterInfo); 270 | } 271 | } 272 | 273 | function applySettersForVariables(varNames) { 274 | var appliedSetterIDs = {}; // remember setterIDs that we've applied, so we don't call setters twice 275 | 276 | for (var i = 0, ilength = varNames.length; i < ilength; i++) { 277 | var varName = varNames[i]; 278 | var setterInfos = _setterInfosByVariableName[varName]; 279 | if (!setterInfos) { continue; } 280 | 281 | var value = _model[varName]; 282 | 283 | for (var j = 0, jlength = setterInfos.length; j < jlength; j++) { 284 | var setterInfo = setterInfos[j]; 285 | if (setterInfo.setterID in appliedSetterIDs) { continue; } // if we've already applied this setter, move on 286 | appliedSetterIDs[setterInfo.setterID] = true; 287 | 288 | setterInfo.setter(value); 289 | } 290 | } 291 | } 292 | 293 | 294 | //---------------------------------------------------------- 295 | // 296 | // variables 297 | 298 | function getValue(varName) { 299 | var value = _model[varName]; 300 | if (value === undefined) { log("Tangle: unknown variable: " + varName); return 0; } 301 | return value; 302 | } 303 | 304 | function setValue(varName, value) { 305 | var obj = {}; 306 | obj[varName] = value; 307 | setValues(obj); 308 | } 309 | 310 | function setValues(obj) { 311 | var changedVarNames = []; 312 | 313 | for (var varName in obj) { 314 | var value = obj[varName]; 315 | var oldValue = _model[varName]; 316 | if (oldValue === undefined) { log("Tangle: setting unknown variable: " + varName); continue; } 317 | if (oldValue === value) { continue; } // don't update if new value is the same 318 | 319 | _model[varName] = value; 320 | changedVarNames.push(varName); 321 | } 322 | 323 | if (changedVarNames.length) { 324 | applySettersForVariables(changedVarNames); 325 | updateModel(); 326 | } 327 | } 328 | 329 | function getValuesForVariables(varNames) { 330 | var values = []; 331 | for (var i = 0, length = varNames.length; i < length; i++) { 332 | values.push(getValue(varNames[i])); 333 | } 334 | return values; 335 | } 336 | 337 | 338 | //---------------------------------------------------------- 339 | // 340 | // model 341 | 342 | function setModel(modelClass) { 343 | var ModelClass = function () { }; 344 | ModelClass.prototype = modelClass; 345 | _model = new ModelClass; 346 | 347 | updateModel(true); // initialize and update 348 | } 349 | 350 | function updateModel(shouldInitialize) { 351 | var ShadowModel = function () {}; // make a shadow object, so we can see exactly which properties changed 352 | ShadowModel.prototype = _model; 353 | var shadowModel = new ShadowModel; 354 | 355 | if (shouldInitialize) { shadowModel.initialize(); } 356 | shadowModel.update(); 357 | 358 | var changedVarNames = []; 359 | for (var varName in shadowModel) { 360 | if (!shadowModel.hasOwnProperty(varName)) { continue; } 361 | if (_model[varName] === shadowModel[varName]) { continue; } 362 | 363 | _model[varName] = shadowModel[varName]; 364 | changedVarNames.push(varName); 365 | } 366 | 367 | applySettersForVariables(changedVarNames); 368 | } 369 | 370 | 371 | //---------------------------------------------------------- 372 | // 373 | // debug 374 | 375 | function log (msg) { 376 | if (window.console) { window.console.log(msg); } 377 | } 378 | 379 | }; // end of Tangle 380 | 381 | 382 | //---------------------------------------------------------- 383 | // 384 | // components 385 | 386 | Tangle.classes = {}; 387 | Tangle.formats = {}; 388 | 389 | Tangle.formats["default"] = function (value) { return "" + value; }; 390 | 391 | -------------------------------------------------------------------------------- /examples/tangle/Tangle-0.1.0/TangleKit/BVTouchable.js: -------------------------------------------------------------------------------- 1 | // 2 | // BVTouchable.js 3 | // ExplorableExplanations 4 | // 5 | // Created by Bret Victor on 3/10/11. 6 | // (c) 2011 Bret Victor. MIT open-source license. 7 | // 8 | 9 | (function () { 10 | 11 | var BVTouchable = this.BVTouchable = new Class ({ 12 | 13 | initialize: function (el, delegate) { 14 | this.element = el; 15 | this.delegate = delegate; 16 | this.setTouchable(true); 17 | }, 18 | 19 | //---------------------------------------------------------------------------------- 20 | // 21 | // touches 22 | // 23 | 24 | setTouchable: function (isTouchable) { 25 | if (this.touchable === isTouchable) { return; } 26 | this.touchable = isTouchable; 27 | this.element.style.pointerEvents = (this.touchable || this.hoverable) ? "auto" : "none"; 28 | 29 | if (isTouchable) { 30 | if (!this._mouseBound) { 31 | this._mouseBound = { 32 | mouseDown: this._mouseDown.bind(this), 33 | mouseMove: this._mouseMove.bind(this), 34 | mouseUp: this._mouseUp.bind(this), 35 | touchStart: this._touchStart.bind(this), 36 | touchMove: this._touchMove.bind(this), 37 | touchEnd: this._touchEnd.bind(this), 38 | touchCancel: this._touchCancel.bind(this) 39 | }; 40 | } 41 | this.element.addEvent("mousedown", this._mouseBound.mouseDown); 42 | this.element.addEvent("touchstart", this._mouseBound.touchStart); 43 | } 44 | else { 45 | this.element.removeEvents("mousedown"); 46 | this.element.removeEvents("touchstart"); 47 | } 48 | }, 49 | 50 | touchDidGoDown: function (touches) { this.delegate.touchDidGoDown(touches); }, 51 | touchDidMove: function (touches) { this.delegate.touchDidMove(touches); }, 52 | touchDidGoUp: function (touches) { this.delegate.touchDidGoUp(touches); }, 53 | 54 | 55 | _mouseDown: function (event) { 56 | event.stop(); 57 | this.element.getDocument().addEvents({ 58 | mousemove: this._mouseBound.mouseMove, 59 | mouseup: this._mouseBound.mouseUp 60 | }); 61 | 62 | this.touches = new BVTouches(event); 63 | this.touchDidGoDown(this.touches); 64 | }, 65 | 66 | _mouseMove: function (event) { 67 | event.stop(); 68 | this.touches.updateWithEvent(event); 69 | this.touchDidMove(this.touches); 70 | }, 71 | 72 | _mouseUp: function (event) { 73 | event.stop(); 74 | this.touches.updateWithEvent(event); 75 | this.touches.count = 0; 76 | this.touchDidGoUp(this.touches); 77 | 78 | delete this.touches; 79 | this.element.getDocument().removeEvents({ 80 | mousemove: this._mouseBound.mouseMove, 81 | mouseup: this._mouseBound.mouseUp 82 | }); 83 | }, 84 | 85 | _touchStart: function (event) { 86 | event.stop(); 87 | if (this.touches || event.length > 1) { this._touchCancel(event); return; } // only-single touch for now 88 | 89 | this.element.getDocument().addEvents({ 90 | touchmove: this._mouseBound.touchMove, 91 | touchend: this._mouseBound.touchEnd, 92 | touchcancel: this._mouseBound.touchCancel 93 | }); 94 | 95 | this.touches = new BVTouches(event); 96 | this.touchDidGoDown(this.touches); 97 | }, 98 | 99 | _touchMove: function (event) { 100 | event.stop(); 101 | if (!this.touches) { return; } 102 | 103 | this.touches.updateWithEvent(event); 104 | this.touchDidMove(this.touches); 105 | }, 106 | 107 | _touchEnd: function (event) { 108 | event.stop(); 109 | if (!this.touches) { return; } 110 | 111 | this.touches.count = 0; 112 | this.touchDidGoUp(this.touches); 113 | 114 | delete this.touches; 115 | this.element.getDocument().removeEvents({ 116 | touchmove: this._mouseBound.touchMove, 117 | touchend: this._mouseBound.touchEnd, 118 | touchcancel: this._mouseBound.touchCancel 119 | }); 120 | }, 121 | 122 | _touchCancel: function (event) { 123 | this._touchEnd(event); 124 | } 125 | 126 | }); 127 | 128 | 129 | //==================================================================================== 130 | // 131 | // BVTouches 132 | // 133 | 134 | var BVTouches = this.BVTouches = new Class({ 135 | 136 | initialize: function (event) { 137 | this.globalPoint = { x:event.page.x, y:-event.page.y }; 138 | this.translation = { x:0, y:0 }; 139 | this.deltaTranslation = { x:0, y:0 }; 140 | this.count = 1; 141 | this.event = event; 142 | }, 143 | 144 | updateWithEvent: function (event) { 145 | var dx = event.page.x - this.globalPoint.x; // todo, transform to local coordinate space? 146 | var dy = -event.page.y - this.globalPoint.y; 147 | this.translation.x += dx; 148 | this.translation.y += dy; 149 | this.deltaTranslation.x += dx; 150 | this.deltaTranslation.y += dy; 151 | this.globalPoint.x = event.page.x; 152 | this.globalPoint.y = -event.page.y; 153 | this.event = event; 154 | }, 155 | 156 | resetDeltaTranslation: function () { 157 | this.deltaTranslation.x = 0; 158 | this.deltaTranslation.y = 0; 159 | } 160 | 161 | }); 162 | 163 | 164 | //==================================================================================== 165 | 166 | })(); 167 | -------------------------------------------------------------------------------- /examples/tangle/Tangle-0.1.0/TangleKit/TangleKit.css: -------------------------------------------------------------------------------- 1 | /* 2 | * TangleKit.css 3 | * Tangle 0.1.0 4 | * 5 | * Created by Bret Victor on 6/10/11. 6 | * (c) 2011 Bret Victor. MIT open-source license. 7 | * 8 | */ 9 | 10 | 11 | /* cursor */ 12 | 13 | .TKCursorDragHorizontal { 14 | cursor: pointer; 15 | cursor: move; 16 | cursor: col-resize; 17 | } 18 | 19 | 20 | /* TKToggle */ 21 | 22 | .TKToggle { 23 | color: #46f; 24 | border-bottom: 1px dashed #46f; 25 | cursor: pointer; 26 | } 27 | 28 | 29 | /* TKAdjustableNumber */ 30 | 31 | .TKAdjustableNumber { 32 | position:relative; 33 | color: #46f; 34 | border-bottom: 1px dashed #46f; 35 | } 36 | 37 | .TKAdjustableNumberHover { 38 | } 39 | 40 | .TKAdjustableNumberDown { 41 | color: #00c; 42 | border-bottom: 1px dashed #00c; 43 | } 44 | 45 | .TKAdjustableNumberHelp { 46 | position:absolute; 47 | color: #00f; 48 | font: 9px "Helvetica-Neue", "Arial", sans-serif; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /examples/tangle/Tangle-0.1.0/TangleKit/TangleKit.js: -------------------------------------------------------------------------------- 1 | // 2 | // TangleKit.js 3 | // Tangle 0.1.0 4 | // 5 | // Created by Bret Victor on 6/10/11. 6 | // (c) 2011 Bret Victor. MIT open-source license. 7 | // 8 | 9 | 10 | (function () { 11 | 12 | 13 | //---------------------------------------------------------- 14 | // 15 | // TKIf 16 | // 17 | // Shows the element if value is true (non-zero), hides if false. 18 | // 19 | // Attributes: data-invert (optional): show if false instead. 20 | 21 | Tangle.classes.TKIf = { 22 | 23 | initialize: function (element, options, tangle, variable) { 24 | this.isInverted = !!options.invert; 25 | }, 26 | 27 | update: function (element, value) { 28 | if (this.isInverted) { value = !value; } 29 | element.style.display = !value ? "none" : "inline"; // todo, block or inline? 30 | } 31 | }; 32 | 33 | 34 | //---------------------------------------------------------- 35 | // 36 | // TKSwitch 37 | // 38 | // Shows the element's nth child if value is n. 39 | // 40 | // False or true values will show the first or second child respectively. 41 | 42 | Tangle.classes.TKSwitch = { 43 | 44 | update: function (element, value) { 45 | element.getChildren().each( function (child, index) { 46 | child.style.display = (index != value) ? "none" : "inline"; 47 | }); 48 | } 49 | }; 50 | 51 | 52 | //---------------------------------------------------------- 53 | // 54 | // TKSwitchPositiveNegative 55 | // 56 | // Shows the element's first child if value is positive or zero. 57 | // Shows the element's second child if value is negative. 58 | 59 | Tangle.classes.TKSwitchPositiveNegative = { 60 | 61 | update: function (element, value) { 62 | Tangle.classes.TKSwitch.update(element, value < 0); 63 | } 64 | }; 65 | 66 | 67 | //---------------------------------------------------------- 68 | // 69 | // TKToggle 70 | // 71 | // Click to toggle value between 0 and 1. 72 | 73 | Tangle.classes.TKToggle = { 74 | 75 | initialize: function (element, options, tangle, variable) { 76 | element.addEvent("click", function (event) { 77 | var isActive = tangle.getValue(variable); 78 | tangle.setValue(variable, isActive ? 0 : 1); 79 | }); 80 | } 81 | }; 82 | 83 | 84 | //---------------------------------------------------------- 85 | // 86 | // TKNumberField 87 | // 88 | // An input box where a number can be typed in. 89 | // 90 | // Attributes: data-size (optional): width of the box in characters 91 | 92 | Tangle.classes.TKNumberField = { 93 | 94 | initialize: function (element, options, tangle, variable) { 95 | this.input = new Element("input", { 96 | type: "text", 97 | "class":"TKNumberFieldInput", 98 | size: options.size || 6 99 | }).inject(element, "top"); 100 | 101 | var inputChanged = (function () { 102 | var value = this.getValue(); 103 | tangle.setValue(variable, value); 104 | }).bind(this); 105 | 106 | this.input.addEvent("keyup", inputChanged); 107 | this.input.addEvent("blur", inputChanged); 108 | this.input.addEvent("change", inputChanged); 109 | }, 110 | 111 | getValue: function () { 112 | var value = parseFloat(this.input.get("value")); 113 | return isNaN(value) ? 0 : value; 114 | }, 115 | 116 | update: function (element, value) { 117 | var currentValue = this.getValue(); 118 | if (value !== currentValue) { this.input.set("value", "" + value); } 119 | } 120 | }; 121 | 122 | 123 | //---------------------------------------------------------- 124 | // 125 | // TKAdjustableNumber 126 | // 127 | // Drag a number to adjust. 128 | // 129 | // Attributes: data-min (optional): minimum value 130 | // data-max (optional): maximum value 131 | // data-step (optional): granularity of adjustment (can be fractional) 132 | 133 | var isAnyAdjustableNumberDragging = false; // hack for dragging one value over another one 134 | 135 | Tangle.classes.TKAdjustableNumber = { 136 | 137 | initialize: function (element, options, tangle, variable) { 138 | this.element = element; 139 | this.tangle = tangle; 140 | this.variable = variable; 141 | 142 | this.min = (options.min !== undefined) ? parseFloat(options.min) : 1; 143 | this.max = (options.max !== undefined) ? parseFloat(options.max) : 10; 144 | this.step = (options.step !== undefined) ? parseFloat(options.step) : 1; 145 | 146 | this.initializeHover(); 147 | this.initializeHelp(); 148 | this.initializeDrag(); 149 | }, 150 | 151 | 152 | // hover 153 | 154 | initializeHover: function () { 155 | this.isHovering = false; 156 | this.element.addEvent("mouseenter", (function () { this.isHovering = true; this.updateRolloverEffects(); }).bind(this)); 157 | this.element.addEvent("mouseleave", (function () { this.isHovering = false; this.updateRolloverEffects(); }).bind(this)); 158 | }, 159 | 160 | updateRolloverEffects: function () { 161 | this.updateStyle(); 162 | this.updateCursor(); 163 | this.updateHelp(); 164 | }, 165 | 166 | isActive: function () { 167 | return this.isDragging || (this.isHovering && !isAnyAdjustableNumberDragging); 168 | }, 169 | 170 | updateStyle: function () { 171 | if (this.isDragging) { this.element.addClass("TKAdjustableNumberDown"); } 172 | else { this.element.removeClass("TKAdjustableNumberDown"); } 173 | 174 | if (!this.isDragging && this.isActive()) { this.element.addClass("TKAdjustableNumberHover"); } 175 | else { this.element.removeClass("TKAdjustableNumberHover"); } 176 | }, 177 | 178 | updateCursor: function () { 179 | var body = document.getElement("body"); 180 | if (this.isActive()) { body.addClass("TKCursorDragHorizontal"); } 181 | else { body.removeClass("TKCursorDragHorizontal"); } 182 | }, 183 | 184 | 185 | // help 186 | 187 | initializeHelp: function () { 188 | this.helpElement = (new Element("div", { "class": "TKAdjustableNumberHelp" })).inject(this.element, "top"); 189 | this.helpElement.setStyle("display", "none"); 190 | this.helpElement.set("text", "drag"); 191 | }, 192 | 193 | updateHelp: function () { 194 | var size = this.element.getSize(); 195 | var top = -size.y + 7; 196 | var left = Math.round(0.5 * (size.x - 20)); 197 | var display = (this.isHovering && !isAnyAdjustableNumberDragging) ? "block" : "none"; 198 | this.helpElement.setStyles({ left:left, top:top, display:display }); 199 | }, 200 | 201 | 202 | // drag 203 | 204 | initializeDrag: function () { 205 | this.isDragging = false; 206 | new BVTouchable(this.element, this); 207 | }, 208 | 209 | touchDidGoDown: function (touches) { 210 | this.valueAtMouseDown = this.tangle.getValue(this.variable); 211 | this.isDragging = true; 212 | isAnyAdjustableNumberDragging = true; 213 | this.updateRolloverEffects(); 214 | this.updateStyle(); 215 | }, 216 | 217 | touchDidMove: function (touches) { 218 | var value = this.valueAtMouseDown + touches.translation.x / 5 * this.step; 219 | value = ((value / this.step).round() * this.step).limit(this.min, this.max); 220 | this.tangle.setValue(this.variable, value); 221 | this.updateHelp(); 222 | }, 223 | 224 | touchDidGoUp: function (touches) { 225 | this.helpElement.setStyle("display", "none"); 226 | this.isDragging = false; 227 | isAnyAdjustableNumberDragging = false; 228 | this.updateRolloverEffects(); 229 | this.updateStyle(); 230 | } 231 | }; 232 | 233 | 234 | 235 | 236 | //---------------------------------------------------------- 237 | // 238 | // formats 239 | // 240 | // Most of these are left over from older versions of Tangle, 241 | // before parameters and printf were available. They should 242 | // be redesigned. 243 | // 244 | 245 | function formatValueWithPrecision (value,precision) { 246 | if (Math.abs(value) >= 100) { precision--; } 247 | if (Math.abs(value) >= 10) { precision--; } 248 | return "" + value.round(Math.max(precision,0)); 249 | } 250 | 251 | Tangle.formats.p3 = function (value) { 252 | return formatValueWithPrecision(value,3); 253 | }; 254 | 255 | Tangle.formats.neg_p3 = function (value) { 256 | return formatValueWithPrecision(-value,3); 257 | }; 258 | 259 | Tangle.formats.p2 = function (value) { 260 | return formatValueWithPrecision(value,2); 261 | }; 262 | 263 | Tangle.formats.e6 = function (value) { 264 | return "" + (value * 1e-6).round(); 265 | }; 266 | 267 | Tangle.formats.abs_e6 = function (value) { 268 | return "" + (Math.abs(value) * 1e-6).round(); 269 | }; 270 | 271 | Tangle.formats.freq = function (value) { 272 | if (value < 100) { return "" + value.round(1) + " Hz"; } 273 | if (value < 1000) { return "" + value.round(0) + " Hz"; } 274 | return "" + (value / 1000).round(2) + " KHz"; 275 | }; 276 | 277 | Tangle.formats.dollars = function (value) { 278 | return "$" + value.round(0); 279 | }; 280 | 281 | Tangle.formats.free = function (value) { 282 | return value ? ("$" + value.round(0)) : "free"; 283 | }; 284 | 285 | Tangle.formats.percent = function (value) { 286 | return "" + (100 * value).round(0) + "%"; 287 | }; 288 | 289 | 290 | 291 | //---------------------------------------------------------- 292 | 293 | })(); 294 | 295 | -------------------------------------------------------------------------------- /examples/tangle/Tangle-0.1.0/TangleKit/sprintf.js: -------------------------------------------------------------------------------- 1 | /** 2 | sprintf() for JavaScript 0.7-beta1 3 | http://www.diveintojavascript.com/projects/javascript-sprintf 4 | 5 | Copyright (c) Alexandru Marasteanu 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | * Neither the name of sprintf() for JavaScript nor the 16 | names of its contributors may be used to endorse or promote products 17 | derived from this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY 23 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | 31 | Changelog: 32 | 2010.09.06 - 0.7-beta1 33 | - features: vsprintf, support for named placeholders 34 | - enhancements: format cache, reduced global namespace pollution 35 | 36 | 2010.05.22 - 0.6: 37 | - reverted to 0.4 and fixed the bug regarding the sign of the number 0 38 | Note: 39 | Thanks to Raphael Pigulla (http://www.n3rd.org/) 40 | who warned me about a bug in 0.5, I discovered that the last update was 41 | a regress. I appologize for that. 42 | 43 | 2010.05.09 - 0.5: 44 | - bug fix: 0 is now preceeded with a + sign 45 | - bug fix: the sign was not at the right position on padded results (Kamal Abdali) 46 | - switched from GPL to BSD license 47 | 48 | 2007.10.21 - 0.4: 49 | - unit test and patch (David Baird) 50 | 51 | 2007.09.17 - 0.3: 52 | - bug fix: no longer throws exception on empty paramenters (Hans Pufal) 53 | 54 | 2007.09.11 - 0.2: 55 | - feature: added argument swapping 56 | 57 | 2007.04.03 - 0.1: 58 | - initial release 59 | **/ 60 | 61 | var sprintf = (function() { 62 | function get_type(variable) { 63 | return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase(); 64 | } 65 | function str_repeat(input, multiplier) { 66 | for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */} 67 | return output.join(''); 68 | } 69 | 70 | var str_format = function() { 71 | if (!str_format.cache.hasOwnProperty(arguments[0])) { 72 | str_format.cache[arguments[0]] = str_format.parse(arguments[0]); 73 | } 74 | return str_format.format.call(null, str_format.cache[arguments[0]], arguments); 75 | }; 76 | 77 | str_format.format = function(parse_tree, argv) { 78 | var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length; 79 | for (i = 0; i < tree_length; i++) { 80 | node_type = get_type(parse_tree[i]); 81 | if (node_type === 'string') { 82 | output.push(parse_tree[i]); 83 | } 84 | else if (node_type === 'array') { 85 | match = parse_tree[i]; // convenience purposes only 86 | if (match[2]) { // keyword argument 87 | arg = argv[cursor]; 88 | for (k = 0; k < match[2].length; k++) { 89 | if (!arg.hasOwnProperty(match[2][k])) { 90 | throw(sprintf('[sprintf] property "%s" does not exist', match[2][k])); 91 | } 92 | arg = arg[match[2][k]]; 93 | } 94 | } 95 | else if (match[1]) { // positional argument (explicit) 96 | arg = argv[match[1]]; 97 | } 98 | else { // positional argument (implicit) 99 | arg = argv[cursor++]; 100 | } 101 | 102 | if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) { 103 | throw(sprintf('[sprintf] expecting number but found %s', get_type(arg))); 104 | } 105 | switch (match[8]) { 106 | case 'b': arg = arg.toString(2); break; 107 | case 'c': arg = String.fromCharCode(arg); break; 108 | case 'd': arg = parseInt(arg, 10); break; 109 | case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break; 110 | case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break; 111 | case 'o': arg = arg.toString(8); break; 112 | case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break; 113 | case 'u': arg = Math.abs(arg); break; 114 | case 'x': arg = arg.toString(16); break; 115 | case 'X': arg = arg.toString(16).toUpperCase(); break; 116 | } 117 | arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg); 118 | pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' '; 119 | pad_length = match[6] - String(arg).length; 120 | pad = match[6] ? str_repeat(pad_character, pad_length) : ''; 121 | output.push(match[5] ? arg + pad : pad + arg); 122 | } 123 | } 124 | return output.join(''); 125 | }; 126 | 127 | str_format.cache = {}; 128 | 129 | str_format.parse = function(fmt) { 130 | var _fmt = fmt, match = [], parse_tree = [], arg_names = 0; 131 | while (_fmt) { 132 | if ((match = /^[^\x25]+/.exec(_fmt)) !== null) { 133 | parse_tree.push(match[0]); 134 | } 135 | else if ((match = /^\x25{2}/.exec(_fmt)) !== null) { 136 | parse_tree.push('%'); 137 | } 138 | else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) { 139 | if (match[2]) { 140 | arg_names |= 1; 141 | var field_list = [], replacement_field = match[2], field_match = []; 142 | if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { 143 | field_list.push(field_match[1]); 144 | while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { 145 | if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { 146 | field_list.push(field_match[1]); 147 | } 148 | else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) { 149 | field_list.push(field_match[1]); 150 | } 151 | else { 152 | throw('[sprintf] huh?'); 153 | } 154 | } 155 | } 156 | else { 157 | throw('[sprintf] huh?'); 158 | } 159 | match[2] = field_list; 160 | } 161 | else { 162 | arg_names |= 2; 163 | } 164 | if (arg_names === 3) { 165 | throw('[sprintf] mixing positional and named placeholders is not (yet) supported'); 166 | } 167 | parse_tree.push(match); 168 | } 169 | else { 170 | throw('[sprintf] huh?'); 171 | } 172 | _fmt = _fmt.substring(match[0].length); 173 | } 174 | return parse_tree; 175 | }; 176 | 177 | return str_format; 178 | })(); 179 | 180 | var vsprintf = function(fmt, argv) { 181 | argv.unshift(fmt); 182 | return sprintf.apply(null, argv); 183 | }; 184 | -------------------------------------------------------------------------------- /examples/tangle/Tangle-0.1.0/TangleTemplate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tangle document 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 36 | 37 | 38 | 39 | 40 |

This is a simple reactive document.

41 | 42 |

43 | When you eat cookies, you 44 | will consume calories. 45 |

46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /examples/tangle/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tangle Processing.js Sketch 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 39 | 40 | 41 | 65 | 66 | 67 | 68 | 69 |

This is a simple reactive sketch using Tangle.js. Drag the values below to alter the running sketch and sketch code.

70 | 71 | 72 | 73 |
74 |

The rectangle above has a width and height of pixels. 75 | The sketch is running at fps.

76 | 77 |
78 |       float d = 1.0;
79 | 
80 |       void setup() {
81 |         size(640, 360);
82 |         frameRate();
83 |         noStroke();
84 |         fill(255);
85 |         rectMode(CENTER);
86 |       }
87 | 
88 |       void draw() {
89 |         background(51);
90 |         translate(width/2, height/2);
91 |         d += 0.01;
92 |         rotate(d);
93 |         rect(0, 0, , );
94 |       }
95 |     
96 |
97 | 98 | 99 | -------------------------------------------------------------------------------- /examples/twitter/blprnt-twitter-demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Processing.js Twitter Demo by blprnt 5 | 12 | 13 | 14 | 15 | 16 | 22 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /examples/twitter/processing-twitter.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Based on jQuery LiveTwitter 1.7.2 https://github.com/elektronaut/jquery.livetwitter 3 | * - Live updating Twitter plugin for jQuery 4 | * 5 | * Copyright (c) 2009-2011 Inge Jørgensen (elektronaut.no) 6 | * Licensed under the MIT license (MIT-LICENSE.txt) 7 | * 8 | * Modified by David Humphrey (@humphd) for use with Processing.js 9 | */ 10 | 11 | (function (document, Processing) { 12 | 13 | function getScript(success) { 14 | var script = document.createElement('script'); 15 | script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"; 16 | var head=document.getElementsByTagName('head')[0], 17 | done=false; 18 | script.onload = script.onreadystatechange = function(){ 19 | if ( !done && (!this.readyState 20 | || this.readyState == 'loaded' 21 | || this.readyState == 'complete') ) { 22 | done=true; 23 | success(jQuery); 24 | script.onload = script.onreadystatechange = null; 25 | } 26 | }; 27 | head.appendChild(script); 28 | } 29 | 30 | // Expose two new globals to Processing sketches: 31 | // 1) loadTweets() a function to start a live-feed query 32 | // 2) tweets an ArrayList of tweets that have been loaded 33 | var Pp = Processing.prototype; 34 | 35 | Pp.tweets = new Pp.ArrayList(); 36 | 37 | Pp.loadTweets = function(query, geocode) { 38 | var options = {geocode: geocode}; 39 | getScript(function(jQuery) { 40 | loadTweets$(jQuery, query, options); 41 | }); 42 | }; 43 | 44 | function loadTweets$(jQuery, query, options, callback) { 45 | // Extend jQuery with a reverse function if it isn't already defined 46 | if (!$.fn.reverse) { 47 | $.fn.reverse = function () { 48 | return this.pushStack(this.get().reverse(), arguments); 49 | }; 50 | } 51 | 52 | $(this).each(function () { 53 | var settings = {}; 54 | 55 | // Does this.twitter already exist? Let's just change the settings. 56 | if (this.twitter) { 57 | settings = $.extend(this.twitter.settings, options); 58 | this.twitter.settings = settings; 59 | if (query) { 60 | this.twitter.query = query; 61 | } 62 | if (this.twitter.interval) { 63 | this.twitter.refresh(); 64 | } 65 | if (callback) { 66 | this.twitter.callback = callback; 67 | } 68 | // ..if not, let's initialize. 69 | } else { 70 | 71 | // These are the default settings. 72 | settings = $.extend({ 73 | mode: 'search', // Mode, valid options are: 'search', 'user_timeline', 'list', 'home_timeline' 74 | rate: 3000, // Refresh rate in ms 75 | limit: 100, // Limit number of results 76 | imageSize: 24, // Size of image in pixels 77 | refresh: true, 78 | timeLinks: true, 79 | retweets: false, 80 | service: false, 81 | localization: { 82 | seconds: 'seconds ago', 83 | minute: 'a minute ago', 84 | minutes: 'minutes ago', 85 | hour: 'an hour ago', 86 | hours: 'hours ago', 87 | day: 'a day ago', 88 | days: 'days ago' 89 | }, 90 | }, options); 91 | 92 | // showAuthor should default to true unless mode is 'user_timeline'. 93 | if (typeof settings.showAuthor === "undefined") { 94 | settings.showAuthor = (settings.mode === 'user_timeline') ? false : true; 95 | } 96 | 97 | // Set up a dummy function for the Twitter API callback. 98 | if (!window.twitter_callback) { 99 | window.twitter_callback = function () { 100 | return true; 101 | }; 102 | } 103 | 104 | this.twitter = { 105 | settings: settings, 106 | query: query, 107 | interval: false, 108 | container: this, 109 | lastTimeStamp: 0, 110 | callback: callback, 111 | 112 | // Convert the time stamp to a more human readable format 113 | relativeTime: function (timeString) { 114 | var parsedDate = Date.parse(timeString); 115 | var delta = (Date.parse(Date()) - parsedDate) / 1000; 116 | var r = ''; 117 | if (delta < 60) { 118 | r = delta + " " + settings.localization.seconds; 119 | } else if (delta < 120) { 120 | r = settings.localization.minute; 121 | } else if (delta < (45 * 60)) { 122 | r = (parseInt(delta / 60, 10)).toString() + " " + settings.localization.minutes; 123 | } else if (delta < (90 * 60)) { 124 | r = settings.localization.hour; 125 | } else if (delta < (24 * 60 * 60)) { 126 | r = '' + (parseInt(delta / 3600, 10)).toString() + " " + settings.localization.hours; 127 | } else if (delta < (48 * 60 * 60)) { 128 | r = settings.localization.day; 129 | } else { 130 | r = (parseInt(delta / 86400, 10)).toString() + " " + settings.localization.days; 131 | } 132 | return r; 133 | }, 134 | 135 | // Update the relative timestamps 136 | updateTimestamps: function () { 137 | var twitter = this; 138 | $(twitter.container).find('span.time').each(function () { 139 | var time_element = twitter.settings.timeLinks ? $(this).find('a') : $(this); 140 | time_element.html(twitter.relativeTime(this.timeStamp)); 141 | }); 142 | }, 143 | 144 | apiURL: function () { 145 | var params = {}; 146 | 147 | var protocol = (window.location.protocol === 'https:') ? 'https:' : 'http:'; 148 | var baseURL = 'api.twitter.com/1/'; 149 | var endpoint = ''; 150 | 151 | // Override for Twitter-compatible APIs like Status.net 152 | if (this.settings.service) { 153 | baseURL = this.settings.service + '/api/'; 154 | } 155 | 156 | // Search mode 157 | if (this.settings.mode === 'search') { 158 | baseURL = (this.settings.service) ? this.settings.service + '/api/' : 'search.twitter.com/'; 159 | endpoint = 'search'; 160 | params = { 161 | q: (this.query && this.query !== '') ? this.query : null, 162 | geocode: this.settings.geocode, 163 | lang: this.settings.lang, 164 | rpp: (this.settings.rpp) ? this.settings.rpp : this.settings.limit 165 | }; 166 | 167 | // User/home timeline mode 168 | } else if (this.settings.mode === 'user_timeline' || this.settings.mode === 'home_timeline') { 169 | endpoint = 'statuses/' + this.settings.mode + '/' + encodeURIComponent(this.query); 170 | params = { 171 | count: this.settings.limit, 172 | include_rts: (this.settings.mode === 'user_timeline' && this.settings.retweets) ? '1' : null 173 | }; 174 | 175 | // Favorites mode 176 | } else if (this.settings.mode === 'favorites') { 177 | endpoint = 'favorites'; 178 | params = { 179 | id: encodeURIComponent(this.query) 180 | }; 181 | 182 | // List mode 183 | } else if (this.settings.mode === 'list') { 184 | endpoint = encodeURIComponent(this.query.user) + 185 | '/lists/' + 186 | encodeURIComponent(this.query.list) + 187 | '/statuses'; 188 | params = { 189 | per_page: this.settings.limit 190 | }; 191 | } 192 | 193 | // Construct the query string 194 | var queryString = []; 195 | for (var param in params) { 196 | if (params.hasOwnProperty(param) && typeof params[param] !== 'undefined' && params[param] !== null) { 197 | queryString[queryString.length] = param + '=' + encodeURIComponent(params[param]); 198 | } 199 | } 200 | queryString = queryString.join("&"); 201 | 202 | // Return the full URL 203 | return protocol + '//' + baseURL + endpoint + '.json?' + queryString + '&callback=?'; 204 | }, 205 | 206 | // The different APIs will format the results slightly different, 207 | // so this method normalizes the tweet object. 208 | parseTweet: function (json) { 209 | var tweet = { 210 | id: (json.id_str) ? json.id_str : json.id, 211 | text: json.text, 212 | created_at: json.created_at 213 | }; 214 | 215 | // Search/regular API differences 216 | if (this.settings.mode === 'search') { 217 | tweet = $.extend(tweet, { 218 | screen_name: json.from_user, 219 | profile_image_url: json.profile_image_url 220 | }); 221 | } else { 222 | tweet = $.extend(tweet, { 223 | screen_name: json.user.screen_name, 224 | profile_image_url: json.user.profile_image_url, 225 | created_at: json.created_at.replace(/^(\w+)\s(\w+)\s(\d+)(.*)(\s\d+)$/, "$1, $3 $2$5$4") // Fix for IE 226 | }); 227 | } 228 | 229 | // Twitter/Status.net 230 | if (this.settings.service) { 231 | tweet = $.extend(tweet, { 232 | url: 'http://' + this.settings.service + '/notice/' + tweet.id, 233 | profile_url: 'http://' + this.settings.service + '/' + json.from_user 234 | }); 235 | if (window.location.protocol === 'https:') { 236 | tweet.profile_image_url = tweet.profile_image_url.replace('http:', 'https:'); 237 | } 238 | 239 | } else { 240 | tweet = $.extend(tweet, { 241 | url: 'http://twitter.com/#!/' + tweet.screen_name + '/status/' + tweet.id, 242 | profile_url: 'http://twitter.com/#!/' + tweet.screen_name 243 | }); 244 | // Someday, Twitter will add HTTPS support to twimg.com, but until then 245 | // we have to rewrite the profile image urls to the old Amazon S3 urls. 246 | if (window.location.protocol === 'https:') { 247 | var matches = tweet.profile_image_url.match(/http[s]?:\/\/a[0-9]\.twimg\.com\/(\w+)\/(\w+)\/(.*?)\.(\w+)/i); 248 | if (matches) { 249 | tweet.profile_image_url = "https://s3.amazonaws.com/twitter_production/" + matches[1] + "/" + matches[2] + "/" + matches[3] + "." + matches[4]; 250 | } else { 251 | // Failsafe, if profile image url does not match the pattern above 252 | // then, at least, change the protocol to HTTPS. 253 | // The image may not load, but at least the page stays secure. 254 | tweet.profile_image_url = tweet.profile_image_url.replace('http:', 'https:'); 255 | } 256 | } 257 | } 258 | 259 | return tweet; 260 | }, 261 | 262 | // Parses the tweet body, linking URLs, #hashtags and @usernames. 263 | parseText: function (text) { 264 | // URLs 265 | text = text.replace(/[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/g, function (m) { 266 | return '' + m + ''; 267 | }); 268 | 269 | // Twitter 270 | if (!this.settings.service) { 271 | // @usernames 272 | text = text.replace(/@[A-Za-z0-9_]+/g, function (u) { 273 | return '' + u + ''; 274 | }); 275 | // #hashtags 276 | text = text.replace(/#[A-Za-z0-9_\-]+/g, function (u) { 277 | return '' + u + ''; 278 | }); 279 | 280 | // Other APIs 281 | } else { 282 | text = text.replace(/@[A-Za-z0-9_]+/g, function (u) { 283 | return '' + u + ''; 284 | }); 285 | text = text.replace(/#[A-Za-z0-9_\-]+/g, function (u) { 286 | return '' + u + ''; 287 | }); 288 | } 289 | 290 | return text; 291 | }, 292 | 293 | // Create an object useable by Processing 294 | toP5: function (tweet) { 295 | return { 296 | id: tweet.id, 297 | profileName: tweet.screen_name, 298 | profileImageUrl: tweet.profile_image_url, 299 | text: tweet.text, 300 | date: this.relativeTime(tweet.created_at) 301 | }; 302 | }, 303 | 304 | // Handle reloading 305 | refresh: function (initialize) { 306 | var twitter = this; 307 | if (twitter.settings.refresh || initialize) { 308 | 309 | $.getJSON(twitter.apiURL(), function (json) { 310 | // The search and regular APIs differ somewhat 311 | var results = (twitter.settings.mode === 'search') ? json.results : json; 312 | 313 | $(results).reverse().each(function () { 314 | var tweet = this; // twitter.parseTweet(this); 315 | 316 | // Check if tweets should be filtered 317 | if (!twitter.settings.filter || twitter.settings.filter(this)) { 318 | // Check if this is actually a new tweet 319 | if (Date.parse(tweet.created_at) > twitter.lastTimeStamp) { 320 | Pp.tweets.add(twitter.toP5(tweet)); 321 | 322 | // Remember the last timestamp for the next refresh. 323 | twitter.lastTimeStamp = Date.parse(tweet.created_at); 324 | } 325 | } 326 | }); 327 | }); 328 | } 329 | }, 330 | 331 | // Start refreshing 332 | start: function () { 333 | var twitter = this; 334 | if (!this.interval) { 335 | this.interval = setInterval(function () { 336 | twitter.refresh(); 337 | }, twitter.settings.rate); 338 | this.refresh(true); 339 | } 340 | }, 341 | 342 | // Stop refreshing 343 | stop: function () { 344 | if (this.interval) { 345 | clearInterval(this.interval); 346 | this.interval = false; 347 | } 348 | }, 349 | 350 | // Clear all tweets 351 | clear: function () { 352 | this.lastTimeStamp = null; 353 | } 354 | }; 355 | 356 | var twitter = this.twitter; 357 | 358 | // Update the timestamps in realtime 359 | this.timeInterval = setInterval(function () { 360 | twitter.updateTimestamps(); 361 | }, 5000); 362 | 363 | this.twitter.start(); 364 | } 365 | }); 366 | return this; 367 | }; 368 | })(window.document, Processing); 369 | -------------------------------------------------------------------------------- /examples/twitter/twitter-images.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Processing.js LiveTwitter Demo 5 | 6 | 7 | 8 | 9 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Introduction to Processing.js for Web and Mobile 5 | 6 | 7 | 8 |
9 |

Introduction to Processing.js for Web and Mobile

10 |

While we're waiting to start, please download our demos and examples (.zip) as well as Processing 2.0a4 for your platform:

11 | 16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /processing-mobile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Processing.Mobile Library for Processing.js 3 | * 4 | * This library adds a number of mobile device related APIs to Processing. 5 | * These are non-standard, and are done in this library only for demonstration 6 | * purposes. 7 | * 8 | * Additional Processing APIs: 9 | * 10 | * orientation: (object) device tilt information in degrees along x, y, z 11 | * alpha: the direction the device is facing according to the compass 12 | * beta: the angle in degrees the device is tilted front-to-back 13 | * gamma the angle in degrees the device is tilted left-to-right. 14 | * compassAccuracy the iOS 5 compass accuracy (or -1) 15 | * compassHeading the iOS 5 cCompass heading in degrees or -1 16 | * 17 | * acceleration: (object) acceleration data for device along x, y, and z axes: 18 | * x: (float) device acceleration in m/s^2 along the X axis (-1.0 to 1.0) 19 | * y: (float) device acceleration in m/s^2 along the Y axis (-1.0 to 1.0) 20 | * z: (float) device acceleration in m/s^2 along the Z axis (-1.0 to 1.0) 21 | * 22 | * coords: (object) geolocation data for the device, obtained at the start of the 23 | * program (i.e., not updated during the lifetime of the program). The 24 | * properties of coords incude: 25 | * 26 | * latitude: (float) current latitude in decimal degrees (or 0 if unknown) 27 | * longitude: (float) current longitude in decimal degrees (or 0 if unknown) 28 | * altitude: (float) current height in meters above the ellipsoid (or 0 if unknown) 29 | * accuracy: (float) accuracy in meters of longitude and latitude 30 | * altitudeAccuracy: (float) accurace of the altitude value in meters (or 0 if unknown) 31 | * heading: (float) direction of travel, specified in degrees 0-360 (or -1 if unknown) 32 | * speed: (float) speed in meters per second (or -1 if unknown) 33 | * 34 | * Updates for coords are available when the locationChanged() callback is fired. 35 | * 36 | * Additional Reading: 37 | * http://www.html5rocks.com/en/tutorials/device/orientation/ 38 | * dev.w3.org/geo/api/spec-source.html 39 | **/ 40 | 41 | (function(Processing, window, navigator) { 42 | 43 | // Cache Processing ctor 44 | var P5 = Processing, 45 | Pp = Processing.prototype; 46 | 47 | var mobile = { 48 | // If we don't have support for devicemotion events, use 0 for these. 49 | acceleration: { 50 | x: 0, 51 | y: 0, 52 | z: 0 53 | }, 54 | 55 | // Defaults for geolocation data 56 | coords: { 57 | latitude: 0, 58 | longitude: 0, 59 | accuracy: 0, 60 | altitude: 0, 61 | altitudeAccuracy: 0, 62 | heading: -1, 63 | speed: -1 64 | }, 65 | 66 | // Defaults for orientation data 67 | orientation: { 68 | alpha: 0, 69 | beta: 0, 70 | gamma: 0, 71 | compassAccuracy: -1, 72 | compassHeading: -1 73 | } 74 | }; 75 | 76 | function attachLocationCallback(p) { 77 | // Start a geolocation watch timeout if a locationChanged callback is provided. 78 | if (p.locationChanged && 79 | typeof p.locationChanged === "function" && 80 | navigator.geolocation) { 81 | 82 | navigator.geolocation.watchPosition( 83 | function success(position) { 84 | var posCoords = position.coords, 85 | mCoords = mobile.coords; 86 | 87 | mCoords.latitude = posCoords.latitude; 88 | mCoords.longitude = posCoords.longitude; 89 | mCoords.altitude = posCoords.altitude || 0; // can be null, 90 | mCoords.accuracy = posCoords.accuracy; 91 | mCoords.altitudeAccuracy = posCoords.altitudeAccuracy || 0; // can be null 92 | mCoords.heading = posCoords.heading || -1; // can be null 93 | mCoords.speed = posCoords.speed || -1; // can be null 94 | 95 | p.locationChanged(); 96 | }, 97 | function error(e) { 98 | // Ignore and use defaults already set for coords 99 | console.log('Unable to get geolocation position data: ' + e); 100 | } 101 | ); 102 | } 103 | } 104 | 105 | // Extend Processing with locationChanged() callback logic. 106 | window.Processing = function() { 107 | var p5 = P5.apply(this, arguments); 108 | attachLocationCallback(p5); 109 | return p5; 110 | }; 111 | window.Processing.prototype = Pp; 112 | 113 | // Copy static properties onto new Processing 114 | for (var prop in P5) { 115 | if (!P5.hasOwnProperty(prop)) { 116 | continue; 117 | } 118 | window.Processing[prop] = P5[prop]; 119 | } 120 | 121 | // Extend any existing Processing instances with location callback, too. 122 | document.addEventListener('DOMContentLoaded', function() { 123 | Processing.instances.forEach(function(instance) { 124 | attachLocationCallback(instance); 125 | }); 126 | }, false); 127 | 128 | window.addEventListener('devicemotion', function(event) { 129 | var acceleration = event.acceleration || event.accelerationIncludingGravity, 130 | mAcceleration = mobile.acceleration; 131 | 132 | // Values are in m/s^2 133 | mAcceleration.x = acceleration.x; 134 | mAcceleration.y = acceleration.y; 135 | mAcceleration.z = acceleration.z; 136 | }, false); 137 | 138 | function orientationhandler(evt) { 139 | // For FF3.6+ 140 | if (!evt.gamma && !evt.beta) { 141 | evt.gamma = -(evt.x * (180 / Math.PI)); 142 | evt.beta = -(evt.y * (180 / Math.PI)); 143 | } 144 | 145 | var mOrientation = mobile.orientation; 146 | mOrientation.alpha = evt.alpha; 147 | mOrientation.beta = evt.beta; 148 | mOrientation.gamma = evt.gamma; 149 | mOrientation.compassAccuracy = evt.webkitCompassAccuracy ? evt.webkitCompassAccuracy : -1; 150 | mOrientation.compassHeading = evt.webkitCompassHeading ? evt.webkitCompassHeading + window.orientation : -1; 151 | } 152 | 153 | window.addEventListener('deviceorientation', orientationhandler, false); 154 | window.addEventListener('MozOrientation', orientationhandler, false); 155 | 156 | ['orientation', 'acceleration', 'coords'].forEach(function(objName) { 157 | Pp.__defineGetter__(objName, function() { 158 | return mobile[objName]; 159 | }); 160 | }); 161 | 162 | }(Processing, window, window.navigator)); 163 | -------------------------------------------------------------------------------- /processing-phonegap.js: -------------------------------------------------------------------------------- 1 | /***************************************************** 2 | 3 | Processing PhoneGap Device API for Processing.js 4 | [ http://docs.phonegap.com/en/1.1.0/index.html ] 5 | 6 | This library exposes the PhoneGap API (1.1.0) to Processing code and 7 | transforms callback and other JavaScript type constructs into Processing 8 | friendly versions. 9 | 10 | To Use: 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | ... 19 | 20 | 21 | NOTE: Create your processing instance with code so that you can wait for 22 | the deviceready event, afterwhich you should listen for DOMContentLoaded. 23 | 24 | New Processing types, constants methods, callbacks 25 | -------------------------------------------------- 26 | 27 | // These are the currently unexposed apects of PhoneGap API. All of these 28 | // can still be accessed via pure JavaScript calls. See the PhoneGap API docs. 29 | // TODO: 30 | // Camera 31 | // Capture 32 | // Contacts 33 | // File 34 | // Media 35 | // Storage 36 | 37 | // Device Strings via global device object 38 | class Device { 39 | String name; 40 | String phonegap; 41 | String platform; 42 | String uuid; 43 | Sevice version; 44 | } 45 | Device device; 46 | 47 | // Acceleration type, global variable, and callback 48 | class Acceleration { 49 | float x; 50 | float y; 51 | float z; 52 | Date timestamp; 53 | } 54 | Acceleration acceleration 55 | 56 | // Accelerometer Event callback 57 | void accelerometer() { 58 | // acceleration is ready to be used 59 | } 60 | 61 | // Geolocation types, global variable, and callback 62 | class Coords { 63 | float latitude; // Latitude in decimal degrees. 64 | float longitude; // Longitude in decimal degrees. 65 | float altitude; // Height of the position in meters above the ellipsoid. 66 | float accuracy; // Accuracy level of the latitude and longitude coordinates in meters. 67 | float altitudeAccuracy; // Accuracy level of the altitude coordinate in meters. 68 | float heading; // Direction of travel, specified in degrees counting clockwise relative to the true north. 69 | float speed; // Current ground speed of the device, specified in meters per second. 70 | } 71 | class Position { 72 | Coords coords; // The coords of the current position. 73 | Date timestamp; // The timestamp of the current position. 74 | } 75 | Position position; 76 | 77 | // Geolocation Event callback 78 | void geolocation() { 79 | // position is ready to be used 80 | } 81 | 82 | // Compass 83 | class Heading { 84 | float magneticHeading; // The heading in degrees from 0 - 359.99 at a single moment in time. 85 | float trueHeading; // The heading relative to the geographic North Pole in degrees 0 - 359.99 at a single moment in time. 86 | float headingAccuracy; // headingAccuracy: The deviation in degrees between the reported heading and the true heading. 87 | Date timestamp; // The time (ms) at which this heading was determined. 88 | } 89 | Heading heading; 90 | 91 | // Compass Event Callback 92 | void compass() { 93 | // heading is ready to be used 94 | } 95 | 96 | // New Global Constants for Connection Type 97 | UNKNOWN 98 | ETHERNET 99 | WIFI 100 | CELL_2G 101 | CELL_3G 102 | CELL_4G 103 | NONE 104 | 105 | // Current Device Connection Type (one of the constants 106 | // listed above) 107 | object connectionType 108 | 109 | // Processing's online variable is mapped to PhoneGap's 110 | // event state for online/offline) 111 | boolean online; 112 | 113 | // Device Back Button Event Callback 114 | void backButtonPressed() { 115 | } 116 | 117 | // Device Menu Button Event Callback 118 | void menuButtonPressed() { 119 | } 120 | 121 | // Device Search Button Event Callback 122 | void searchButtonPressed() { 123 | } 124 | 125 | // Device Start Call Button Event Callback 126 | void startCallButtonPressed() { 127 | } 128 | 129 | // Device Start Call Button Event Callback 130 | void endCallButtonPressed() { 131 | } 132 | 133 | // Device Volume Down Button Event Callback 134 | void volumeDownButtonPressed() { 135 | } 136 | 137 | // Device Volume Up Button Event Callback 138 | void volumeUpButtonPressed() { 139 | } 140 | 141 | // Beep method causes the device to beep the desired number of times. 142 | beep(int num); 143 | 144 | // Vibrate method causes the device to vibrate for the desired 145 | // number of ms 146 | vibrate(int ms); 147 | 148 | *****************************************************/ 149 | 150 | (function(Processing, window, navigator, device) { 151 | 152 | // Make sure we have Processing 153 | if (!window.Processing) { 154 | throw "Processing.js PhoneGap Error: Processing not loaded."; 155 | } 156 | 157 | // Make sure we're running on PhoneGap 158 | if (!(window.device && window.device.phonegap)) { 159 | throw "Processing.js PhoneGap Error: PhoneGap device API not found."; 160 | } 161 | 162 | // PhoneGap device state 163 | var phoneGap = { 164 | // The global device object 165 | device: device, 166 | 167 | // Whether or not the device is connected to the Internet 168 | online: false, 169 | 170 | // If we don't have support for acceleration events, use -1 for these. 171 | acceleration: { 172 | x: -1, 173 | y: -1, 174 | z: -1, 175 | timestamp: Date.now() 176 | }, 177 | 178 | // If we don't have support for compass events, use -1 for these. 179 | heading: { 180 | magneticHeading: -1, 181 | trueHeading: -1, 182 | headingAccuracy: -1, 183 | timestamp: Date.now() 184 | }, 185 | 186 | // Defaults for geolocation data 187 | position: { 188 | coords: { 189 | latitude: 0, 190 | longitude: 0, 191 | accuracy: 0, 192 | altitude: 0, 193 | altitudeAccuracy: 0, 194 | heading: -1, 195 | speed: -1 196 | }, 197 | timestamp: Date.now() 198 | }, 199 | }; 200 | 201 | // Cache Processing ctor, prototype since we'll wrap/alter them. 202 | var P5 = Processing, 203 | Pp = Processing.prototype, 204 | log = (console && console.log) ? console.log : function(){}; 205 | 206 | // Expose connection type constants via PConstants 207 | var PConstants = Pp.PConstants; 208 | PConstants.UNKNOWN = Connection.UNKNOWN; 209 | PConstants.ETHERNET = Connection.ETHERNET; 210 | PConstants.WIFI = Connection.WIFI; 211 | PConstants.CELL_2G = Connection.CELL_2G; 212 | PConstants.CELL_3G = Connection.CELL_3G; 213 | PConstants.CELL_4G = Connection.CELL_4G; 214 | PConstants.NONE = Connection.NONE; 215 | 216 | // Expose connection type (shared for all instances) 217 | Pp.__defineGetter__('connectionType', function() { 218 | return navigator.network.connection.type; 219 | }); 220 | 221 | // Expose beep method 222 | Pp.beep = function(n) { 223 | n = n || 1; 224 | navigator.notification.beep(n); 225 | } 226 | 227 | // Expose vibrate method 228 | Pp.vibrate = function(ms) { 229 | ms = ms || 1000; 230 | navigator.notification.vibrate(ms); 231 | } 232 | 233 | // Extend the Processing ctor. 234 | window.Processing = function() { 235 | var p5 = P5.apply(this, arguments), 236 | aWatchID, 237 | cWatchID, 238 | gWatchID; 239 | 240 | // Do we have an accelerometer callback? If so, start a watch 241 | if (p5.accelerometer) { 242 | aWatchID = navigator.accelerometer.watchAcceleration( 243 | function(acceleration) { 244 | phoneGap.acceleration = acceleration; 245 | p5.accelerometer(); 246 | }, 247 | function() { 248 | log('Processing.js PhoneGap Error: Unable to get accelerometer data.'); 249 | } 250 | ); 251 | } 252 | 253 | // Do we have a compass callback? If so, start a watch 254 | if (p5.compass) { 255 | cWatchID = navigator.compass.watchHeading( 256 | function(heading) { 257 | phoneGap.heading = heading; 258 | p5.compass(); 259 | }, 260 | function() { 261 | log('Processing.js PhoneGap Error: Unable to get compass data.'); 262 | } 263 | ); 264 | } 265 | 266 | // Do we have a geolocation callback? If so, start a watch 267 | if (p5.geolocation) { 268 | gWatchId = navigator.geolocation.watchPosition( 269 | function(position) { 270 | phoneGap.position = position; 271 | p5.geolocation(); 272 | }, 273 | function() { 274 | log('Processing.js PhoneGap Error: Unable to get geolocation data.'); 275 | } 276 | ); 277 | } 278 | 279 | // Do we have a startCallButtonPressed callback? 280 | if (p5.startCallButtonPressed) { 281 | document.addEventListener("startcallbutton", function() { 282 | p5.startCallButtonPressed(); 283 | }, false); 284 | } 285 | 286 | // Do we have an endCallButtonPressed callback? 287 | if (p5.endCallButtonPressed) { 288 | document.addEventListener("endcallbutton", function() { 289 | p5.endCallButtonPressed(); 290 | }, false); 291 | } 292 | 293 | // Do we have a searchButtonPressed callback? 294 | if (p5.searchButtonPressed) { 295 | document.addEventListener("searchbutton", function() { 296 | p5.searchButtonPressed(); 297 | }, false); 298 | } 299 | 300 | // Do we have a backButtonPressed callback? 301 | if (p5.backButtonPressed) { 302 | document.addEventListener("backbutton", function() { 303 | p5.backButtonPressed(); 304 | }, false); 305 | } 306 | 307 | // Do we have a menuButtonPressed callback? 308 | if (p5.menuButtonPressed) { 309 | document.addEventListener("menubutton", function() { 310 | p5.menuButtonPressed(); 311 | }, false); 312 | } 313 | 314 | // Do we have a volumeDownButtonPressed callback? 315 | if (p5.volumeDownButtonPressed) { 316 | document.addEventListener("volumedownbutton", function() { 317 | p5.volumeDownButtonPressed(); 318 | }, false); 319 | } 320 | 321 | // Do we have a volumeUpButtonPressed callback? 322 | if (p5.volumeUpButtonPressed) { 323 | document.addEventListener("volumeupbutton", function() { 324 | p5.volumeUpButtonPressed(); 325 | }, false); 326 | } 327 | 328 | // When the app gets paused/resumed (put into background) 329 | // stop/start our draw loop 330 | document.addEventListener('pause', function() { 331 | p5.noLoop(); 332 | }, false); 333 | document.addEventListener('resume', function() { 334 | p5.loop(); 335 | }, false); 336 | 337 | // When the device's network state changes (connection to 338 | // the Internet), change the value of Processing's online variable 339 | document.addEventListener('online', function() { 340 | phoneGap.online = true; 341 | }, false); 342 | document.addEventListener('offline', function() { 343 | phoneGap.online = false; 344 | }, false); 345 | 346 | // Need to override the instance's default 'online' getter 347 | delete p5.online; 348 | p5.__defineGetter__('online', function() { 349 | return phoneGap.online; 350 | }); 351 | 352 | // Grab a reference to the existing exit method so we can extend it. 353 | var exitFunc = p5.exit; 354 | 355 | p5.exit = function() { 356 | // Kill any running watches 357 | if (aWatchID) { 358 | navigator.accelerometer.clearWatch(aWatchID); 359 | aWatchID = null; 360 | } 361 | if (cWatchID) { 362 | navigator.compass.clearWatch(cWatchID); 363 | cWatchID = null; 364 | } 365 | if (gWatchID) { 366 | navigator.geolocation.clearWatch(gWatchID); 367 | gWatchID = null; 368 | } 369 | 370 | // TODO: should clean up all the listeners we've attached... 371 | 372 | // Do a proper clean-up using the original exit() method 373 | exitFunc.apply(p5); 374 | }; 375 | 376 | return p5; 377 | }; 378 | window.Processing.prototype = Pp; 379 | 380 | // Copy static properties onto the wrapped Processing 381 | for (var prop in P5) { 382 | if (!P5.hasOwnProperty(prop)) { 383 | continue; 384 | } 385 | window.Processing[prop] = P5[prop]; 386 | } 387 | 388 | // Attach the rest of the new global variables 389 | ['acceleration', 'heading', 'position'].forEach(function(objName) { 390 | Pp.__defineGetter__(objName, function() { 391 | return phoneGap[objName]; 392 | }); 393 | }); 394 | 395 | }(Processing, window, window.navigator, window.device)); 396 | -------------------------------------------------------------------------------- /tools/httpd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | PORT = 9914 4 | SERVER = '127.0.0.1' 5 | 6 | import SimpleHTTPServer 7 | import BaseHTTPServer 8 | import SocketServer 9 | 10 | Handler = SimpleHTTPServer.SimpleHTTPRequestHandler 11 | 12 | class Server(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer): 13 | pass 14 | 15 | httpd = Server((SERVER, PORT), Handler) 16 | print "Web Server listening on http://%s:%s/ (stop with ctrl+c)..." % (SERVER, PORT) 17 | 18 | try: 19 | httpd.serve_forever() 20 | except KeyboardInterrupt: 21 | print "Going down..." -------------------------------------------------------------------------------- /tools/processing-helper.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Processing Helper 6 | 9 | 10 | 11 |

Processing Helper

12 |

Paste your Processing code below and execute whichever options you require:

13 | 14 |

Processing Code

15 | 16 |
17 |   18 |   19 | 20 |

Canvas

21 |
22 | 23 |
24 | 25 |

Output

26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /tools/processing-helper.js: -------------------------------------------------------------------------------- 1 | (function(global) { 2 | 3 | var canvas = document.getElementById('sketch'), 4 | code = document.getElementById('code'), 5 | output = document.getElementById('output'), 6 | instance = null; 7 | 8 | function createCanvas() { 9 | // Make a new canvas, in case we're switching from 2D to 3D contexts. 10 | var container = document.getElementById('sketch-container'); 11 | var sketch = document.getElementById('sketch'); 12 | container.removeChild(sketch); 13 | 14 | sketch = document.createElement('canvas'); 15 | sketch.id = 'sketch'; 16 | container.appendChild(sketch); 17 | 18 | return sketch; 19 | } 20 | 21 | function waitForExit() { 22 | var checkbox = document.getElementById('expect-exit-callback'); 23 | if (!checkbox) { 24 | return false; 25 | } 26 | return checkbox.checked || checkbox.value; 27 | } 28 | 29 | global.runSketch = function(callback) { 30 | try { 31 | output.value = ''; 32 | canvas = createCanvas(); 33 | var sketch = Processing.compile(code.value); 34 | 35 | if (callback) { 36 | if (!/exit\(\);/.test(code.value)) { 37 | throw "exit() not found in sketch. Add the exit() command, and re-run the sketch."; 38 | } 39 | sketch.onExit = callback; 40 | instance = new Processing(canvas, sketch); 41 | } else { 42 | instance = new Processing(canvas, sketch); 43 | } 44 | } catch (e) { 45 | output.value = "Error! Error was:\n" + e.toString(); 46 | } 47 | }; 48 | 49 | global.convertToJS = function() { 50 | try { 51 | output.value = js_beautify( 52 | Processing.compile(code.value).sourceCode).replace(/\n\n\n+/g, '\n\n'); 53 | output.select(); 54 | } catch (e) { 55 | output.value = "Parser Error! Error was:\n" + e.toString(); 56 | } 57 | }; 58 | 59 | global.generateDataURI = function() { 60 | // Run the sketch first, in case the user hasn't 61 | runSketch(); 62 | output.value = canvas.toDataURL(); 63 | output.select(); 64 | }; 65 | 66 | function buildRefTest() { 67 | try { 68 | // if the test was 2d, we can just call getImageData 69 | if (!instance.use3DContext) { 70 | var context = canvas.getContext('2d'); 71 | var imgData = context.getImageData(0, 0, canvas.width, canvas.height).data; 72 | // else, we'll need to call WebGL's readPixels. 73 | } else { 74 | // The order of the pixels go from bottom to top, left to right. 75 | var context = canvas.getContext("experimental-webgl"); 76 | var imgData = new Uint8Array(canvas.width * canvas.height * 4); 77 | context.readPixels(0, 0, canvas.width, canvas.height, context.RGBA, context.UNSIGNED_BYTE, imgData); 78 | } 79 | 80 | var pixels = []; 81 | for(var i = 0, idl = imgData.length; i < idl; i++) { 82 | pixels[i] = imgData[i]; 83 | } 84 | 85 | var dimensions = "[" + canvas.width + "," + canvas.height + "]"; 86 | // Opera doesn't have btoa() so this won't work there. 87 | document.location.href= "data:text/plain;charset=utf-8;base64," + 88 | btoa('//' + dimensions + pixels + '\n' + code.value); 89 | } catch (e) { 90 | output.value = "Error creating ref test! Error was: " + e.toString(); 91 | } 92 | }; 93 | 94 | global.generateRefTest = function() { 95 | // Run the sketch first, in case the user hasn't 96 | runSketch(buildRefTest); 97 | }; 98 | 99 | }(window)); 100 | --------------------------------------------------------------------------------