Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                
              
            
!

CSS

              
                body {
  padding: 0; 
  margin: 0;
} 
canvas {
  vertical-align: top;
}

              
            
!

JS

              
                ////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//    M A G N E T R I X                                                       //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// parameters                                                                 //
////////////////////////////////////////////////////////////////////////////////


// diameter of the canvas
var dcanvas = 300;

// 400 compass needles in a 20 x 20 grid
var cols = 15;
var rows = 15;

// size of a compass
var s = 20;

// distance from the bordr
var gap = 30;


////////////////////////////////////////////////////////////////////////////////
// globals
////////////////////////////////////////////////////////////////////////////////

var canvas;

// alignment factor
var alignment = 0.5;

// compass array
var c = [];

////////////////////////////////////////////////////////////////////////////////
// GUI
////////////////////////////////////////////////////////////////////////////////

var gui;
var Rows, Columns, Gap;

////////////////////////////////////////////////////////////////////////////////
// main
////////////////////////////////////////////////////////////////////////////////

function setup() {

  angleMode(DEGREES);

  // create a div that filld the window
  div = createDiv('');
  div.size(windowWidth, windowHeight);

  // create a canvas centered inside the div
  canvas = createCanvas(dcanvas, dcanvas);
  canvas.parent(div);
  canvas.center();

  // create all the compass needles
  for (row = 0; row < rows; row++) {
    for (col = 0; col < cols; col++) {

      // random angle
      var d = random(360);

      // calculate screen position of the corrent compass
      var x = map(col, 0, cols - 1, gap, width - gap);
      var y = map(row, 0, cols - 1, gap, height - gap);

      // create new compass and add it to the list
      c.push(new Compass(x, y, s, d));

    }
  }

  Rows = rows;
  Columns = cols;
  Gap = gap;

  gui = createGui('Parameters', 0, 10);
  gui.addGlobals('Rows', 'Columns', 'Gap');
  sliderRange(0, 1, 0.1);
 

}

// update layout of magnets
function update() {
  if (Rows != rows || Columns != cols || Gap != gap) {
    c.splice(0, c.length);
    clear();

    rows = Rows;
    cols = Columns;
    gap = Gap;

    for (row = 0; row < rows; row++) {
      for (col = 0; col < cols; col++) {

        // random angle
        var d = random(360);

        // calculate screen position of the corrent compass
        var x = map(col, 0, cols - 1, gap, width - gap);
        var y = map(row, 0, cols - 1, gap, height - gap);

        // create new compass and add it to the list
        c.push(new Compass(x, y, s, d));

      }
    }
  }
}

function draw() {

  // clear all graphics
  clear();
  update();

  // make every compass calculate its new state
  for (var i = 0; i < c.length; i++) {
    c[i].tick();
  }

  // update states and draw the result on screen
  for (i = 0; i < c.length; i++) {
    c[i].update();
    c[i].draw();
  }

}

////////////////////////////////////////////////////////////////////////////////
// interaction
////////////////////////////////////////////////////////////////////////////////

// reset everything when a key is pressed
function keyPressed() {
  for (var i = 0; i < c.length; i++) {
    c[i].reset();
  }
}

// makeing circular pattern with needles around mouse pointer
function mouseDragged() {

  var moux = mouseX;
  var mouy = mouseY;

  for (var i = 0; i < c.length; i++) {
    var dirToMouse = atan2(moux- c[i], mouy  -c[i]) ;
    var distToMouse = dist(moux, mouy, c[i].x, c[i].y);

    if (distToMouse < 80) {
      c[i].nextx = lerp(cos(c[i].dir), cos(dirToMouse), constrain(alignment * 1.5, 0.1, 0.9));
      c[i].nexty = lerp(sin(c[i].dir), sin(dirToMouse), constrain(alignment * 1.5, 0.1, 0.9));
    }



  }

  for (var k = 0; k < c.length; k++) {
    c[k].update();
    c[k].draw();
  }

}

////////////////////////////////////////////////////////////////////////////////
// objects
////////////////////////////////////////////////////////////////////////////////

function Compass(x, y, size, direction) {

  this.x = x;
  this.y = y;
  this.size = size;
  this.dir = direction;

  // reset to random direction
  this.reset = function() {
    this.dir = random(360);
  };

  // draw the compass needle
  this.draw = function() {
    noFill();
    stroke(0, 50);
    ellipse(this.x, this.y, this.size);
    var x2 = this.x + cos(this.dir) * this.size / 2;
    var y2 = this.y + sin(this.dir) * this.size / 2;
    stroke(0);
    line(this.x, this.y, x2, y2);
  };

  // update value, by interpolating between our own direction and that of our neighbors
  this.tick = function() {

    // counter for number of neighbor comapsses
    var n = 0;

    // vector components
    var sumx = 0;
    var sumy = 0;

    // look at all the compasses (not very efficient)
    for (i = 0; i < c.length; i++) {

      // get distance to the other compass
      var other = c[i];
      var d = dist(this.x, this.y, other.x, other.y);

      // if the compasses touch they are neighbors - make them interact!
      if (d < this.size / 2 + other.size / 2) {

        // add vector components of the neighbor to the sum
        sumx = sumx + cos(other.dir);
        sumy = sumy + sin(other.dir);
        n++;

      }

      // add noise field with offset to the sum

      sumx += noise((this.x + frameCount * 2) / 30) * 2 - 1;
      sumy += noise((this.y + frameCount * 2) / 30) * 2 - 1;
      n += 1;

    }

    // interpolate between current vector and the median vector of the neighbors
    // (dividing the vector sum by n to get the centroid)
    this.nextx = lerp(cos(this.dir), sumx / n, alignment);
    this.nexty = lerp(sin(this.dir), sumy / n, alignment);

  };

  this.update = function() {
    // get direction from vector components
    this.dir = atan2(this.nexty, this.nextx);

  };

}
              
            
!
999px

Console