var audio, peaks, duration;
var showPlayHead = false;
audio = loadSound('./PinkFloyd_WishYouWereHere.mp3');
title = "wish you were here";
scribble = new Scribble();
createCanvas(windowWidth, windowHeight);
peaks = audio.getPeaks(density);
duration = audio.duration();
function drawBackground() {
for (var y = 0; y < height; y++) {
for (var x = 0; x < width; x++) {
noiseVal = noise(x * noiseScale, y * noiseScale);
stroke(255 - noiseVal * 25);
text(title, width / 2, height * 0.8);
function drawPlayHead() {
var pos = (audio.currentTime() / duration) * width * 0.8 + width * 0.1 ;
line(pos, height * 0.2, pos, height * 0.6);
rect(width - buttonWidth, 0, buttonWidth, buttonHeight);
rect(width - buttonWidth * 0.75, buttonWidth * 0.25, buttonWidth / 2, buttonHeight / 2);
width - buttonWidth * 0.75, buttonHeight * 0.25,
width - buttonWidth * 0.25, buttonHeight * 0.5,
width - buttonWidth * 0.75, buttonHeight * 0.75);
for (var i = 0; i < peaks.length; i++) {
x = width / 10 + i / peaks.length * width * 0.8;
h = peaks[i] * (height / 4);
noiseVal = noise(i * noiseScale, h * noiseScale);
stroke(fillGrey + noiseVal);
scribble.scribbleLine(x, c - h, x, c + h)
function isStopButton() {
return mouseY < 100 && mouseX > width - 200;
function mouseReleased() {
this.sketch = p || window;
this.numEllipseSteps = 9;
this.ellipseInc = (Math.PI*2)/this.numEllipseSteps;
this.getOffset = function( minVal, maxVal ) {
return this.roughness*(this.sketch.random()*(maxVal-minVal)+minVal);
this.buildEllipse = function( cx, cy, rx, ry, offset, overlap ) {
var radialOffset = this.getOffset( -0.5, 0.5 )-Math.PI/2;
this.sketch.beginShape();
this.sketch.curveVertex( this.getOffset( -offset, offset )+cx+0.9*rx*Math.cos( radialOffset-this.ellipseInc ),
this.getOffset( -offset, offset )+cy+0.9*ry*Math.sin( radialOffset-this.ellipseInc ) );
for ( var theta = radialOffset; theta < Math.PI*2+radialOffset-0.01; theta+=this.ellipseInc ) {
this.sketch.curveVertex( this.getOffset( -offset, offset )+cx+rx*Math.cos( theta ),
this.getOffset( -offset, offset )+cy+ry*Math.sin( theta ) );
this.sketch.curveVertex( this.getOffset( -offset, offset )+cx+rx*Math.cos( radialOffset+Math.PI*2+overlap*0.5 ),
this.getOffset( -offset, offset )+cy+ry*Math.sin( radialOffset+Math.PI*2+overlap*0.5 ) );
this.sketch.curveVertex( this.getOffset( -offset, offset )+cx+0.98*rx*Math.cos( radialOffset+overlap ),
this.getOffset( -offset, offset )+cy+0.98*ry*Math.sin( radialOffset+overlap ) );
this.sketch.curveVertex( this.getOffset( -offset, offset )+cx+0.9*rx*Math.cos( radialOffset+overlap*0.5 ),
this.getOffset( -offset, offset )+cy+0.9*ry*Math.sin( radialOffset+overlap*0.5 ) );
this.getIntersectingLines = function( lineCoords, xCoords, yCoords ) {
var s1 = new Segment( lineCoords[0], lineCoords[1], lineCoords[2], lineCoords[3] );
for ( var i = 0; i < xCoords.length; i++ ) {
var s2 = new Segment( xCoords[i], yCoords[i], xCoords[(i+1)%xCoords.length], yCoords[(i+1)%xCoords.length] );
if ( s1.compare(s2) == Relation.INTERSECTS ) {
intersections.push( [s1.getIntersectionX(), s1.getIntersectionY()] );
this.scribbleLine = function( x1, y1, x2, y2 ) {
var lenSq = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2);
var offset = this.maxOffset;
if ( this.maxOffset*this.maxOffset*100 > lenSq ) {
offset = Math.sqrt( lenSq )/10;
var halfOffset = offset/2;
var divergePoint = 0.2 + this.sketch.random()*0.2;
var midDispX = this.bowing*this.maxOffset*(y2-y1)/200;
var midDispY = this.bowing*this.maxOffset*(x1-x2)/200;
midDispX = this.getOffset( -midDispX, midDispX );
midDispY = this.getOffset( -midDispY, midDispY );
this.sketch.beginShape();
this.sketch.vertex( x1 + this.getOffset( -offset, offset ), y1 + this.getOffset( -offset, offset ) );
this.sketch.curveVertex(x1 + this.getOffset( -offset, offset ), y1 + this.getOffset( -offset, offset ) );
this.sketch.curveVertex(midDispX+x1+(x2 -x1)*divergePoint + this.getOffset( -offset, offset ), midDispY+y1 + (y2-y1)*divergePoint + this.getOffset( -offset, offset ) );
this.sketch.curveVertex(midDispX+x1+2*(x2-x1)*divergePoint + this.getOffset( -offset, offset ), midDispY+y1+ 2*(y2-y1)*divergePoint + this.getOffset( -offset,offset ) );
this.sketch.curveVertex(x2 + this.getOffset( -offset, offset ), y2 + this.getOffset( -offset, offset ) );
this.sketch.vertex( x2 + this.getOffset( -offset, offset ), y2 + this.getOffset( -offset, offset ) );
this.sketch.beginShape();
this.sketch.vertex( x1 + this.getOffset( -halfOffset, halfOffset ), y1 + this.getOffset( -halfOffset, halfOffset ) );
this.sketch.curveVertex(x1 + this.getOffset( -halfOffset, halfOffset ), y1 + this.getOffset( -halfOffset, halfOffset ) );
this.sketch.curveVertex(midDispX+x1+(x2 -x1)*divergePoint + this.getOffset( -halfOffset, halfOffset ), midDispY+y1 + (y2-y1)*divergePoint + this.getOffset( -halfOffset, halfOffset ) );
this.sketch.curveVertex(midDispX+x1+2*(x2-x1)*divergePoint + this.getOffset( -halfOffset, halfOffset ), midDispY+y1+ 2*(y2-y1)*divergePoint + this.getOffset( -halfOffset, halfOffset ) );
this.sketch.curveVertex(x2 + this.getOffset( -halfOffset, halfOffset ), y2 + this.getOffset( -halfOffset, halfOffset ) );
this.sketch.vertex( x2 + this.getOffset( -halfOffset, halfOffset ), y2 + this.getOffset( -halfOffset, halfOffset ) );
this.scribbleCurve = function( x1, y1, x2, y2, x3, y3, x4, y4 ) {
this.sketch.bezier( x1+this.getOffset( -2, 2 ), y1+this.getOffset( -2, 2 ),
x3+this.getOffset( -4, 4 ), y3+this.getOffset( -3, 3 ),
x4+this.getOffset( -3, 3 ), y4+this.getOffset( -3, 3 ),
x2+this.getOffset( -1, 1 ), y2+this.getOffset( -1, 1 ) );
this.sketch.bezier( x1+this.getOffset( -2, 2 ), y1+this.getOffset( -2, 2 ),
x3+this.getOffset( -3, 3 ), y3+this.getOffset( -3, 3 ),
x4+this.getOffset( -3, 3 ), y4+this.getOffset( -4, 4 ),
x2+this.getOffset( -2, 2 ), y2+this.getOffset( -2, 2 ) );
this.scribbleRect = function( x, y, w, h ) {
var left = Math.min( x-halfWidth, x+halfWidth );
var right = Math.max( x-halfWidth, x+halfWidth );
var top = Math.min( y-halfHeight, y+halfHeight );
var bottom = Math.max( y-halfHeight, y+halfHeight );
this.scribbleLine( left, top, right, top );
this.scribbleLine( right, top, right, bottom );
this.scribbleLine( right, bottom, left, bottom );
this.scribbleLine( left, bottom, left, top );
this.scribbleRoundedRect = function( x, y, w, h, radius ) {
if ( radius == 0 || radius > halfWidth || radius > halfHeight ) {
this.scribbleRect( x, y, w, h );
var left = Math.min( x-halfWidth, x+halfWidth );
var right = Math.max( x-halfWidth, x+halfWidth );
var top = Math.min( y-halfHeight, y+halfHeight );
var bottom = Math.max( y-halfHeight, y+halfHeight );
this.scribbleLine( left+radius, top, right-radius, top, 1.5 );
this.scribbleLine( right, top+radius, right, bottom-radius, 1.5 );
this.scribbleLine( right-radius, bottom, left+radius, bottom, 1.5 );
this.scribbleLine( left, bottom-radius, left, top+radius, 1.5 );
this.scribbleCurve( left+radius, top, left, top+radius, left+radius*0.1, top+radius*0.1, left+radius*0.1, top+radius*0.1 );
this.scribbleCurve( right-radius, top, right, top+radius, right-radius*0.1, top+radius*0.1, right-radius*0.1, top+radius*0.1 );
this.scribbleCurve( left+radius, bottom, left, bottom-radius, left+radius*0.1, bottom-radius*0.1, left+radius*0.1, bottom-radius*0.1 );
this.scribbleCurve( right-radius, bottom, right, bottom-radius, right-radius*0.1, bottom-radius*0.1, right-radius*0.1, bottom-radius*0.1 );
this.scribbleEllipse = function( x, y, w, h ) {
rx += this.getOffset( -rx*0.05, rx*0.05 );
ry += this.getOffset( -ry*0.05, ry*0.05 );
this.buildEllipse( x, y, rx, ry, 1, this.ellipseInc*this.getOffset( 0.1, this.getOffset( 0.4, 1 ) ) );
this.buildEllipse( x, y, rx, ry, 1.5, 0 );
this.scribbleFilling = function( xCoords, yCoords, gap, angle ) {
if ((xCoords == null) || (yCoords == null) || (xCoords.length == 0) || (yCoords.length == 0)) {
var hachureAngle = this.sketch.radians( angle%180 );
var cosAngle = Math.cos( hachureAngle );
var sinAngle = Math.sin( hachureAngle );
var tanAngle = Math.tan( hachureAngle );
for ( var i = 1; i < xCoords.length; i++ ) {
left = Math.min( left, xCoords[i] );
right = Math.max( right, xCoords[i] );
top = Math.min( top, yCoords[i] );
bottom = Math.max( bottom, yCoords[i] );
var it = new HachureIterator( top-1, bottom+1, left-1, right+1, gap, sinAngle, cosAngle, tanAngle );
while ( (rectCoords = it.getNextLine()) != null ) {
var lines = this.getIntersectingLines( rectCoords, xCoords, yCoords );
for ( var i = 0; i < lines.length; i+=2 ) {
if ( i < lines.length-1 ) {
this.scribbleLine( p1[0], p1[1], p2[0], p2[1], 2 );
function HachureIterator( _top, _bottom, _left, _right, _gap, _sinAngle, _cosAngle, _tanAngle ) {
var sinAngle = _sinAngle;
var tanAngle = _tanAngle;
if (Math.abs(sinAngle) < 0.0001) {
} else if (Math.abs(sinAngle) > 0.9999) {
deltaX = (bottom-top)*Math.abs(tanAngle);
pos = left-Math.abs(deltaX);
hGap = Math.abs(gap / _cosAngle);
sLeft = new Segment(left, bottom, left, top);
sRight = new Segment(right, bottom, right, top);
this.getNextLine = function() {
if (Math.abs(sinAngle) < 0.0001) {
var line = [pos, top, pos, bottom];
} else if (Math.abs(sinAngle) > 0.9999) {
var line = [left, pos, right, pos];
var xLower = pos-deltaX/2;
var xUpper = pos+deltaX/2;
if (pos < right+deltaX) {
while (((xLower < left) && (xUpper < left)) || ((xLower > right) && (xUpper > right))) {
if (pos > right+deltaX) {
var s = new Segment(xLower, yLower, xUpper, yUpper);
if (s.compare(sLeft) == Relation.INTERSECTS) {
xLower = s.getIntersectionX();
yLower = s.getIntersectionY();
if (s.compare(sRight) == Relation.INTERSECTS) {
xUpper = s.getIntersectionX();
yUpper = s.getIntersectionY();
xLower = right-(xLower-left);
xUpper = right-(xUpper-left);
var line = [xLower, yLower, xUpper, yUpper];
function Segment( _x1, _y1, _x2, _y2 ) {
var xi = Number.MAX_VALUE;
var yi = Number.MAX_VALUE;
if ((a==0) && (b==0) && (c==0)) {
this.compare = function( otherSegment ) {
if ((this.isUndefined()) || (otherSegment.isUndefined())) {
return Relation.UNDEFINED;
var grad1 = Number.MAX_VALUE;
var grad2 = Number.MAX_VALUE;
if (Math.abs(b) > 0.00001) {
if (Math.abs(otherSegment.getB()) > 0.00001) {
grad2 = -otherSegment.getA()/otherSegment.getB();
int2 = -otherSegment.getC()/otherSegment.getB();
if (grad1 == Number.MAX_VALUE) {
if (grad2 == Number.MAX_VALUE) {
if (-c/a != -otherSegment.getC()/otherSegment.getA()) {
return Relation.SEPARATE;
if ((y1 >= Math.min(otherSegment.getPy1(),otherSegment.getPy2())) &&
(y1 <= Math.max(otherSegment.getPy1(),otherSegment.getPy2()))) {
return Relation.INTERSECTS;
if ((y2 >= Math.min(otherSegment.getPy1(),otherSegment.getPy2())) &&
(y2 <= Math.max(otherSegment.getPy1(),otherSegment.getPy2()))) {
return Relation.INTERSECTS;
return Relation.SEPARATE;
if (((y1-yi)*(yi-y2) < -0.00001) || ((otherSegment.getPy1()-yi)*(yi-otherSegment.getPy2()) < -0.00001)) {
return Relation.SEPARATE;
if (Math.abs(otherSegment.getA()) < 0.00001) {
if ((otherSegment.getPx1()-xi)*(xi-otherSegment.getPx2()) < -0.00001) {
return Relation.SEPARATE;
return Relation.INTERSECTS;
return Relation.INTERSECTS;
if (grad2 == Number.MAX_VALUE) {
xi = otherSegment.getPx1();
if (((otherSegment.getPy1()-yi)*(yi-otherSegment.getPy2()) < -0.00001) || ((y1-yi)*(yi-y2) < -0.00001)) {
return Relation.SEPARATE;
if (Math.abs(a) < 0.00001) {
if ((x1-xi)*(xi-x2) < -0.00001) {
return Relation.SEPARATE;
return Relation.INTERSECTS;
return Relation.INTERSECTS;
return Relation.SEPARATE;
if ((x1 >= Math.min(otherSegment.getPx1(),otherSegment.getPx2())) &&
(x1 <= Math.max(otherSegment.getPy1(),otherSegment.getPy2()))) {
return Relation.INTERSECTS;
if ((x2 >= Math.min(otherSegment.getPx1(),otherSegment.getPx2())) &&
(x2 <= Math.max(otherSegment.getPx1(),otherSegment.getPx2()))) {
return Relation.INTERSECTS;
return Relation.SEPARATE;
xi = (int2-int1)/(grad1-grad2);
if (((x1-xi)*(xi-x2) < -0.00001) || ((otherSegment.getPx1()-xi)*(xi-otherSegment.getPx2()) < -0.00001)) {
return Relation.SEPARATE;
return Relation.INTERSECTS;
this.getPx1 = function() {
this.getPy1 = function() {
this.getPx2 = function() {
this.getPy2 = function() {
this.isUndefined = function() {
this.getIntersectionX = function() {
this.getIntersectionY = function() {
this.getLength = function( tx1, ty1, tx2, ty2 ) {
return Math.sqrt(dx*dx + dy*dy);
var Relation = { LEFT:1, RIGHT:2, INTERSECTS:3, AHEAD:4, BEHIND:5, SEPARATE:6, UNDEFINED:7 };