Gradient Orientation Javascript

A solution to draw strokes in Javascript based on gradient orientation. Uses p5.js.

by frapporti

HTML

<script src="http://cdn.jsdelivr.net/p5.js/0.3.9/p5.min.js"></script>
    <img src="http://lorempixel.com/300/400/people/5" />

CSS

img, canvas {
    float: left;
}

JavaScript

var img, vectors;
    
    var cellSize = 2; // for faster rendering we can stroke less lines
    var maxLinesLength = 30;
    var noiseLevel = 4;

    var strokeThickness = 1; 
        
    function preload() { 
      img = loadImage('http://lorempixel.com/300/400/people/5');
        
      /* you can test in local if the directions are correct using a simple gradient as image
      img = loadImage('http://fornace.io/jstests/img/gradient.jpg');
      img2 = loadImage('http://fornace.io/jstests/img/gradient.jpg');
      */
    }
    
    function setup() {  
      createCanvas(img.width, img.height);
      image(img,0,0);
      img.loadPixels();
          
      
      makeLumas();
      makeVectors();
      
      for ( var xx = 0; xx < img.width; xx = xx + cellSize) {
        for ( var yy = 0; yy < img.height; yy = yy + cellSize) {
          push();
            // in p5.js you set the item's attributes stroke, strokeweight, translate, and rotate before drawing it with line(). push and pop serve to isolate these attributes.
            
            var linesLength = Math.min(vectors[yy][xx].mag*100, maxLinesLength);
            
            if (linesLength > noiseLevel) {
            
              stroke(random(40,240));  // to color with pixel color change to stroke(img.get(xx, yy));
              strokeWeight(strokeThickness);
              translate(xx,yy);
              // p5.js, like processing, works translating the coordinate system. to make rotate work we want, we need to move it over our current pixel.
              
              rotate( vectors[yy][xx].dir - PI/2 ); // here we use the rotation of the gradient. not sure about the angle correction (PI/2), it seems it gives better results.
              line(-linesLength/2, 0, linesLength/2, 0);
            }
            
          pop();
        }
      }

//      adding the image in overlay to evaluate if the map is good
//      tint(255, 255, 255, 100);
//      image(img2,0,0);


    }
    
   ...