diff --git a/app/src/processing/mode/javascript/DirectivesEditor.java b/app/src/processing/mode/javascript/DirectivesEditor.java index 8bd342ad2..eb135757d 100644 --- a/app/src/processing/mode/javascript/DirectivesEditor.java +++ b/app/src/processing/mode/javascript/DirectivesEditor.java @@ -143,6 +143,8 @@ public class DirectivesEditor { String mm = m.group(); + // TODO this urgently needs tests .. + /* remove framing */ mm = mm.replaceAll("^\\/\\*\\s*@pjs","").replaceAll("\\s*\\*\\/\\s*$",""); /* fix multiline nice formatting */ diff --git a/javascript/examples/HTML5/Video/charmyDance/charmyDance.pde b/javascript/examples/HTML5/Video/charmyDance/charmyDance.pde new file mode 100644 index 000000000..015e4e525 --- /dev/null +++ b/javascript/examples/HTML5/Video/charmyDance/charmyDance.pde @@ -0,0 +1,99 @@ +/* @pjs transparent=true; */ + +/** + *
This example shows you how to use video with a transparency + * which currently is not natively supported by web video formats (H264 / OGV).
+ * + *The "disco effects" in the back are generated by Processing code + * while Charmy dancing upfront is coming from a HTML5 video element.
+ * + *The video contains both the image and the mask side by side, have a look + * at the war file here: charmy.mp4
+ * + * Greenscreen material by mint.gs and used with permission. + * + * + */ + + Video video; + PImage frame; + float fSec = 1/25.0; + int fMillis = int(1000 * fSec); + int ts = 0; + + void setup () + { + size( 320, 240 ); + + noStroke(); + textFont(createFont("Arial", 20)); + background(255,0); + } + + void draw () + { + if ( video != null ) + { + background(255, 0); + + timeLineEffects(); + + PImage frame = getFrame(video); + PImage rgbImage = frame.get(frame.width/2,0,frame.width/2,frame.height); + PImage maskImage = frame.get(0,0,frame.width/2,frame.height); + rgbImage.mask(maskImage); + image( rgbImage, width/2-rgbImage.width/2, 0 ); + } + } + + void mousePressed () + { + if ( video != null ) + { + if ( video.paused ) video.play(); + else video.pause(); + } + } + + /* called from JavaScript to set the freshly loaded video */ + void addVideo ( Video v ) + { + v.play(); + video = v; + } + + /* copy video image to PImage */ + PImage getFrame ( Video v ) + { + return new PImage(v); // sub-optimal .. + } + + /* make Processing understand the HTMLVideoElement */ + interface Video + { + boolean autoplay; + boolean controls; + + int width; + int height; + int videoWidth; /*readonly*/ + int videoHeight; /*readonly*/ + + boolean muted; + float volume; + + boolean loop; + boolean paused; + boolean ended; + + String currentSrc; + + float duration; + float currentTime; + + void play(); + void pause(); + } diff --git a/javascript/examples/HTML5/Video/charmyDance/mov.js b/javascript/examples/HTML5/Video/charmyDance/mov.js new file mode 100644 index 000000000..37d3572d1 --- /dev/null +++ b/javascript/examples/HTML5/Video/charmyDance/mov.js @@ -0,0 +1,68 @@ + +// wait for the DOM to become ready +window.onload = function () { + + // try to find the Processing sketch instance, or retry + function tryFindSketch () { + var sketch = Processing.instances[0]; + if ( sketch == undefined ) + setTimeout(tryFindSketch, 200); // retry in 0.2 secs + else + initVideos( sketch ); + } + tryFindSketch(); +} + +// look for the video and send to sketch +function initVideos ( sketch ) { + + var video = document.getElementsByTagName("video")[0]; + + video['loop'] = true; // as "loop" is not supported by many browsers + + // similar to tryFindSketch this creates a loop that + // continues until the video becomes ready. + (function( s, v ){ + var tryAddVideo = function () { + if ( v.readyState > 0 ) { + s.addVideo(v); + } else { + setTimeout(tryAddVideo, 200); + } + } + tryAddVideo(); + })( sketch, video ); + + // force loop when set as this is currently not supported by most browsers + addEvent(video,'ended',function(){ + if ( 'loop' in this && this.loop ) { + this.currentTime = 0; + this.play(); + } + }); +} + +// http://html5demos.com/ +var addEvent = (function () { + if (document.addEventListener) { + return function (el, type, fn) { + if (el && el.nodeName || el === window) { + el.addEventListener(type, fn, false); + } else if (el && el.length) { + for (var i = 0; i < el.length; i++) { + addEvent(el[i], type, fn); + } + } + }; + } else { + return function (el, type, fn) { + if (el && el.nodeName || el === window) { + el.attachEvent('on' + type, function () { return fn.call(el, window.event); }); + } else if (el && el.length) { + for (var i = 0; i < el.length; i++) { + addEvent(el[i], type, fn); + } + } + }; + } +})(); diff --git a/javascript/examples/HTML5/Video/charmyDance/timeline.pde b/javascript/examples/HTML5/Video/charmyDance/timeline.pde new file mode 100644 index 000000000..3f359b60d --- /dev/null +++ b/javascript/examples/HTML5/Video/charmyDance/timeline.pde @@ -0,0 +1,83 @@ +void timeLineEffects () +{ + float t = video.duration/10; + float n = video.currentTime; + + fill( 255 ); + + if ( n < t ) + { + float w = map(n,0,t,100,500); + ellipse( width/2,height/2,w,w); + } + else if ( n < 2*t ) + { + float w = map(n,t,2*t,0,300); + + fill(255); + ellipse( width/2-100,height/2-100,w*0.75,w*0.75); + fill(0); + ellipse( width/2+50,height/2,w,w); + fill(255); + ellipse( width/2-100,height/2+150,w*1.5,w*1.5); + } + else if ( n < 3*t ) + { + float w = map(n,2*t,3*t,0,1); + + for ( int i = 0 ; i < 9; i++ ) + { + rect((i%3)*width/3,int(i/3)*height/3,width/3*w,height/3*w); + } + } + else if ( n < 4*t ) + { + float w = map(n,3*t,4*t,-1,0); + + fill( 0 ); + for ( int i = 0 ; i < 25; i++ ) + { + rect(((i%5)+1)*width/5,(int(i/5)+1)*height/5,width/5*w,height/5*w); + } + } + else if ( n < 5*t ) + { + float w = map(n,4*t,5*t,0,height/9); + + for ( int i = 0 ; i < 10; i++ ) + { + rect(0,i*(height/9)-w, width, height/18); + } + } + else if ( n < 7*t ) + { + float w = map(n,6*t,7*t,0,TWO_PI); + for ( int i = 0 ; i < 22; i++ ) + { + fill( cos(w) > 0 ? 255 : 0 ); + rect(i*(width/20), 0, width/40, height); + } + } + else if ( n < 8*t ) + { + int mx = int(map(n,t*7,t*8,1,20)); + + for ( int i = 0; i < mx; i++ ) + ellipse( random(width), random(height), 5*mx, 5*mx ); + } + else if ( n < 9*t ) + { + int mxx = 1+int(map(n,t*8,t*9,1,10))*2; + mx = mxx*mxx; + + for ( int i = 0 ; i < mx; i+=2 ) + { + rect( (i%mxx)*width/mxx, int(i/mxx)*height/mxx, width/mxx, height/mxx ); + } + } + else if ( n < 10*t ) + { + float w = map(n,9*t,10*t,700,100); + ellipse( width/2,height/2,w,w); + } +}