/Force-Field-JS

This emulates a force field to visualize how a heavy mass would interact with it. You can change this behaviour by plugging in your own equation which controls the field.

Primary LanguageJavaScriptMIT LicenseMIT

Welcome

A brief demo of what this code actually does ... hover your mouse over the field !

See the Pen Force Field by Adk (@adk96r) on CodePen.

<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

Let's dive straight into the code!

Trust me, it's dead simple to use ! ( Just make sure you have JQuery )

1. Create an # element:

This will host your force field grid. Make sure to assign it a unique ID , as it will be used later. Keep the block empty.

      <div id="Grid"></div>

2. Start the field:

In order to start the field, you need to an object having the ID of the field grid element that was created earlier. It can be created as -

      settings = new Object({
          "fgrid" : "Grid ( your ID )"
          ...
      });

Now start the field by calling initGrid which takes the settings object as the only argument.

      initGrid( settings );

That's it. You have your own force field! But if you want to make it even more epic, scroll down.

3. Tweak the settings ( Even Better ! )

The field has a ton of settings which you can tweak! You can change the following -

Field Grid -

  1. fieldHeight :  Height of the grid.
  2. fieldWidth :   Width of the grid.
  3. fgridClassArray : An array of strings which represent the classes to be applied to FGrid Object.
    var settings = new Object({
        'fgrid' : 'Grid',
        ...
        'fieldHeight' : 300,
        'fieldWidth' : 300,
        'fgridClassArray' : ['classA', 'classB',   ....   , 'classC']
        ...
    }));

Field Dots

Each Field dot is basically -

    .fdot{
        margin: 8px;
        height: 4px;
        width: 4px;
        border-radius: 2px;
        position: absolute;
        background-color: rgba(0,190,145,255);
    }
  1. dotMargin :  The margin for the dot.
  2. size :   The Width & Height of the dot ( both are equal ) .
  3. fdotClassArray : An array of strings which represent the classes to be applied to FGrid Object. ( similar to fgridClassArray.
  4. rgbaStateFalse : An array contaning the rgba values of the dot when it is being not active ( not under the effect of field ).
  5. rgbaStateTrue : An array contaning the rgba values of the dot when it is being active ( under the effect of field ).
    var settings = new Object({
        'fgrid' : 'Grid',
        ...
        'dotMargin' : 6,
        'size' : 4,
        'fdotClassArray' : ['dotClassA',   ...   , 'dotClassN'],
        'rgbaStateFalse' : [255, 0, 0, 255],
        'rgbaStateTrue' : [0, 0, 255, 255],
        ...
    }));
  • border-radius is generated as size/2 . Try to keep size an even integer as it will be halved.
  • dotSize is generated as 2 * margin + size .

Field Properties

These properties control the field itself, i.e, how the dots will react upon a movement of another body ( in this case the mouse ) .

  1. forceSpread: This will specify how many of the surrounding dots are affected ( in physical terms it is analogous to the mass of the moving body in a field ). Larger the no. wider the scope. eg- spread = 3 means 3 dots on each side will be effected.
  2. fieldEqn: This is the equation of the field. By default it is $$f(dx,dy) = margin - 10 * Max(0 , 7 - 1.5*log ( dx^2 + dy^2))$$.
    function newForceField (delta_x, delta_y) {
        // Let this be the new field equation.
        return delta_x * delta_y + margin;
    }
    
    var settings = new Object({
        'fgrid' : 'Grid',
        ...
        'forceSpread' : 15,
        'fieldEqn' : newForceField,
        ...
    }));
  • The field equation accepts exactly 2 arguments, delta_x and delta_y which are the x and y distances between the field dot's location and the mouse pointer's location.

Voilà !

That's it. Now just run this,

    initGrid( settings );

and you're good to go.

A brief note & default values :

The default values for the various properties mentioned above are :

    fgridHeight = 300;
    fgridWidth = 300;
    
    margin = 5;
    size = 4;
    rgba_state_true = [255, 150, 255, 255];
    rgba_state_false = [0, 190, 145, 255];
    
    spread = 10;
    FieldEqn = sensitivityVal;
    
    function sensitivityVal(delta_x, delta_y){
        return margin + 10*Math.max(0, 7 + Math.log(1/Math.pow(Math.hypot(delta_x,delta_y),1.5)));
    }

You can tweak them further to suit your tastes ! Hope you like using this code !