cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

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

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

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

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation

     

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.

            
              <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/stats.js/r11/Stats.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/2.2.9/pixi.js"></script>
<script>
  (function (root, factory) {
    'use strict';

    if (typeof exports === 'object') {
        module.exports = factory();
    } else if (typeof define === 'function' && define.amd) {
        define(factory);
    } else {
        root.MersenneTwister = factory();
    }
}(this, function () {
    /**
     * A standalone, pure JavaScript implementation of the Mersenne Twister pseudo random number generator. Compatible
     * with Node.js, requirejs and browser environments. Packages are available for npm, Jam and Bower.
     *
     * @module MersenneTwister
     * @author Raphael Pigulla <pigulla@four66.com>
     * @license See the attached LICENSE file.
     * @version 0.2.3
     */

    /*
     * Most comments were stripped from the source. If needed you can still find them in the original C code:
     * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c
     *
     * The original port to JavaScript, on which this file is based, was done by Sean McCullough. It can be found at:
     * https://gist.github.com/banksean/300494
     */
    'use strict';

    var MAX_INT = 4294967296.0,
        N = 624,
        M = 397,
        UPPER_MASK = 0x80000000,
        LOWER_MASK = 0x7fffffff,
        MATRIX_A = 0x9908b0df;

    /**
     * Instantiates a new Mersenne Twister.
     *
     * @constructor
     * @alias module:MersenneTwister
     * @since 0.1.0
     * @param {number=} seed The initial seed value.
     */
    var MersenneTwister = function (seed) {
        if (typeof seed === 'undefined') {
            seed = new Date().getTime();
        }

        this.mt = new Array(N);
        this.mti = N + 1;

        this.seed(seed);
    };

    /**
     * Initializes the state vector by using one unsigned 32-bit integer "seed", which may be zero.
     *
     * @since 0.1.0
     * @param {number} seed The seed value.
     */
    MersenneTwister.prototype.seed = function (seed) {
        var s;

        this.mt[0] = seed >>> 0;

        for (this.mti = 1; this.mti < N; this.mti++) {
            s = this.mt[this.mti - 1] ^ (this.mt[this.mti - 1] >>> 30);
            this.mt[this.mti] =
                (((((s & 0xffff0000) >>> 16) * 1812433253) << 16) + (s & 0x0000ffff) * 1812433253) + this.mti;
            this.mt[this.mti] >>>= 0;
        }
    };

    /**
     * Initializes the state vector by using an array key[] of unsigned 32-bit integers of the specified length. If
     * length is smaller than 624, then each array of 32-bit integers gives distinct initial state vector. This is
     * useful if you want a larger seed space than 32-bit word.
     *
     * @since 0.1.0
     * @param {array} vector The seed vector.
     */
    MersenneTwister.prototype.seedArray = function (vector) {
        var i = 1,
            j = 0,
            k = N > vector.length ? N : vector.length,
            s;

        this.seed(19650218);

        for (; k > 0; k--) {
            s = this.mt[i-1] ^ (this.mt[i-1] >>> 30);

            this.mt[i] = (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1664525) << 16) + ((s & 0x0000ffff) * 1664525))) +
                vector[j] + j;
            this.mt[i] >>>= 0;
            i++;
            j++;
            if (i >= N) {
                this.mt[0] = this.mt[N - 1];
                i = 1;
            }
            if (j >= vector.length) {
                j = 0;
            }
        }

        for (k = N - 1; k; k--) {
            s = this.mt[i - 1] ^ (this.mt[i - 1] >>> 30);
            this.mt[i] =
                (this.mt[i] ^ (((((s & 0xffff0000) >>> 16) * 1566083941) << 16) + (s & 0x0000ffff) * 1566083941)) - i;
            this.mt[i] >>>= 0;
            i++;
            if (i >= N) {
                this.mt[0] = this.mt[N - 1];
                i = 1;
            }
        }

        this.mt[0] = 0x80000000;
    };

    /**
     * Generates a random unsigned 32-bit integer.
     *
     * @since 0.1.0
     * @returns {number}
     */
    MersenneTwister.prototype.int = function () {
        var y,
            kk,
            mag01 = new Array(0, MATRIX_A);

        if (this.mti >= N) {
            if (this.mti === N + 1) {
                this.seed(5489);
            }

            for (kk = 0; kk < N - M; kk++) {
                y = (this.mt[kk] & UPPER_MASK) | (this.mt[kk + 1] & LOWER_MASK);
                this.mt[kk] = this.mt[kk + M] ^ (y >>> 1) ^ mag01[y & 1];
            }

            for (; kk < N - 1; kk++) {
                y = (this.mt[kk] & UPPER_MASK) | (this.mt[kk + 1] & LOWER_MASK);
                this.mt[kk] = this.mt[kk + (M - N)] ^ (y >>> 1) ^ mag01[y & 1];
            }

            y = (this.mt[N - 1] & UPPER_MASK) | (this.mt[0] & LOWER_MASK);
            this.mt[N - 1] = this.mt[M - 1] ^ (y >>> 1) ^ mag01[y & 1];
            this.mti = 0;
        }

        y = this.mt[this.mti++];

        y ^= (y >>> 11);
        y ^= (y << 7) & 0x9d2c5680;
        y ^= (y << 15) & 0xefc60000;
        y ^= (y >>> 18);

        return y >>> 0;
    };

    /**
     * Generates a random unsigned 31-bit integer.
     *
     * @since 0.1.0
     * @returns {number}
     */
    MersenneTwister.prototype.int31 = function () {
        return this.int() >>> 1;
    };

    /**
     * Generates a random real in the interval [0;1] with 32-bit resolution.
     *
     * @since 0.1.0
     * @returns {number}
     */
    MersenneTwister.prototype.real = function () {
        return this.int() * (1.0 / (MAX_INT - 1));
    };

    /**
     * Generates a random real in the interval ]0;1[ with 32-bit resolution.
     *
     * @since 0.1.0
     * @returns {number}
     */
    MersenneTwister.prototype.realx = function () {
        return (this.int() + 0.5) * (1.0 / MAX_INT);
    };

    /**
     * Generates a random real in the interval [0;1[ with 32-bit resolution.
     *
     * @since 0.1.0
     * @returns {number}
     */
    MersenneTwister.prototype.rnd = function () {
        return this.int() * (1.0 / MAX_INT);
    };

    /**
     * Generates a random real in the interval [0;1[ with 32-bit resolution.
     *
     * Same as .rnd() method - for consistency with Math.random() interface.
     *
     * @since 0.2.0
     * @returns {number}
     */
    MersenneTwister.prototype.random = MersenneTwister.prototype.rnd;

    /**
     * Generates a random real in the interval [0;1[ with 53-bit resolution.
     *
     * @since 0.1.0
     * @returns {number}
     */
    MersenneTwister.prototype.rndHiRes = function () {
        var a = this.int() >>> 5,
            b = this.int() >>> 6;

        return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0);
    };

    var instance = new MersenneTwister();

    /**
     * A static version of [rnd]{@link module:MersenneTwister#rnd} on a randomly seeded instance.
     *
     * @static
     * @function random
     * @memberof module:MersenneTwister
     * @returns {number}
     */
    MersenneTwister.random = function () {
        return instance.rnd();
    };

    return MersenneTwister;
}));

</script>
<canvas id="canvas"></canvas> 
            
          
!
            
               body {
   margin: 0;
   padding: 0;
   background-color: #000;
 }
 
 canvas {
   position: absolute;
   top: 0; left: 0;
   display: block;
   width: 100%;
   height: 100%;
 }
 
 #stats {
   position: absolute;
   top: 0;
   left: 0;
   z-index: 666
 }
 
 .dg.ac {
   z-index: 666!important;
 }
            
          
!
            
              
/*
 * SPURM
 * Copyright MIT © <2014> Andrea Bovo <i@spleen.noo.name>
 **/

if (!Date.now)
  Date.now = function () {
    return new Date().getTime();
  };

(function () {
  var lastTime = 0;
  var vendors = ["ms", "moz", "webkit", "o"];
  for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
    window.requestAnimationFrame = window[vendors[x] + "RequestAnimationFrame"];
    window.cancelAnimationFrame =
      window[vendors[x] + "CancelAnimationFrame"] ||
      window[vendors[x] + "CancelRequestAnimationFrame"];
  }

  if (!window.requestAnimationFrame)
    window.requestAnimationFrame = function (callback, element) {
      var currTime = new Date().getTime();
      var timeToCall = Math.max(0, 16 - (currTime - lastTime));
      var id = window.setTimeout(function () {
        callback(currTime + timeToCall);
      }, timeToCall);
      lastTime = currTime + timeToCall;
      return id;
    };

  if (!window.cancelAnimationFrame)
    window.cancelAnimationFrame = function (id) {
      clearTimeout(id);
    };
})();

/*
 * SPURM CLASS
 */

var SPURM = {};

SPURM.Tentacle = function (obj) {
  this.init = function () {
    PIXI.Graphics.call(this);
    this.interactive = true;
    this.is_mouse_moving = false;
    this.rnd = obj.randomizer;
    this.head = 10 + this.rnd.random() * 4;
    this.nodes = [];
    this.num_nodes = 100;
    this.theta = 0;
    this.theta_muscle = 0;
    this.tv = 0;
    this.x = 0;
    this.y = 0;
    this.vx = this.rnd.random() - 0.5;
    this.vy = this.rnd.random() - 0.5;
    this.head = 2 + this.rnd.random();
    this.speed = 8 + this.rnd.random() * 12;
    this.speed_cf = 9.0e-2 + this.rnd.random() * 10 / 50;
    this.friction = this.min_friction + this.rnd.random() * 10 / 100;
    this.muscle_rg = this.min_muscle_rg + this.rnd.random() * 50;
    this.count = 0;
    this.muscle_fq = this.min_muscle_fq + this.rnd.random() * 100 / 250;
    for (var i = 0; i < this.num_nodes; i++) {
      this.nodes.push({
        x: 0,
        y: 0
      });
    }
    this.beginFill(0xff0000);
  };

  this.init();
};

SPURM.Tentacle.prototype = Object.create(PIXI.Graphics.prototype);
SPURM.Tentacle.constructor = SPURM.Tentacle;
SPURM.Tentacle.prototype.rnd = {};
SPURM.Tentacle.prototype.min_friction = 9.0e-1;
SPURM.Tentacle.prototype.min_muscle_rg = 20;
SPURM.Tentacle.prototype.min_muscle_fq = 1.0e-1;
SPURM.Tentacle.prototype.move = function (pos) {
  var dy = pos.y - this.position.y,
    dx = pos.x - this.position.x,
    dist = dx * dx + dy * dy,
    deg = Math.atan2(dy, dx) * (180 / Math.PI);

  this.theta = deg;
  this.position.y = pos.y;
  this.position.x = pos.x;
};

SPURM.Tentacle.prototype.update = function () {
  this.tv += 0.5 * this.rnd.random();
  this.tv *= this.friction;
  this.nodes[0].x = this.head * Math.cos(Math.PI / 180 * this.theta);
  this.nodes[0].y = this.head * Math.sin(Math.PI / 180 * this.theta);
  this.count += this.muscle_fq;
  this.theta_muscle = this.muscle_rg * Math.sin(this.count);
  this.nodes[1].x =
    (0 - this.head) *
    Math.cos(Math.PI / 180 * (this.theta + this.theta_muscle));
  this.nodes[1].y =
    (0 - this.head) *
    Math.sin(Math.PI / 180 * (this.theta + this.theta_muscle));

  var i = 1,
    dx,
    dy,
    dist;
  while (++i < this.num_nodes) {
    dx = this.nodes[i].x - this.nodes[i - 2].x;
    dy = this.nodes[i].y - this.nodes[i - 2].y;
    dist = Math.sqrt(dx * dx + dy * dy);

    this.nodes[i].x = this.nodes[i - 1].x + dx * this.speed / dist;
    this.nodes[i].y = this.nodes[i - 1].y + dy * this.speed / dist;
  }

  this.clear();
  this.moveTo(this.nodes[1].x, this.nodes[1].y);
  i = 1;
  while (++i < this.num_nodes) {
    this.lineStyle(this.num_nodes / (i - 1), 0x000000, 0.95);
    this.moveTo(this.nodes[i].x, this.nodes[i].y);

    if (i == 2) {
      //head
      this.lineStyle(0, 0x000000, 0.7);
      this.beginFill(0x000000, 0.7);
      this.drawCircle(this.nodes[i].x, this.nodes[i].y, 5, 5);
      this.endFill();
    } else {
      this.lineTo(this.nodes[i - 1].x, this.nodes[i - 1].y);
    }
  }
};

// /SPURM CLASS

var AI = function () {
  this.friction = 9.0e-1;
  this.muscle_fq = 1.0e-1;
  this.muscle_rg = 20;
  this.head = 10;
};

AI.prototype.update = function (t) {
  t.friction = this.friction;
  t.muscle_fq = this.muscle_fq;
  t.muscle_rg = this.muscle_rg;
  t.head = this.head;
};

/* SPURM */

var stage,
  stats,
  renderer,
  t,
  ui,
  ai,
  view,
  position = {
    x: 0,
    y: 0
  },
  path = [],
  tween,
  mt = new MersenneTwister(),
  random_range = function (min, max) {
    return mt.random() * (max - min) + min;
  };

ai = new AI();

ui = new dat.GUI();
ui.add(ai, "friction", 1, 20);
ui.add(ai, "muscle_fq", 0.1, 0.5);
ui.add(ai, "head", 0, 20);
ui.add(ai, "muscle_rg", 0, 40);

mt.seed(20);
view = document.getElementById("canvas");
renderer = PIXI.autoDetectRenderer(window.innerWidth, window.innerHeight, document.getElementById("canvas"));
stage = new PIXI.Stage(0xff0000);

stats = new Stats();
stats.setMode(0);

document.body.appendChild(renderer.view);
document.body.appendChild(stats.domElement);

t = new SPURM.Tentacle({
  randomizer: mt
});
t.position.x = window.innerWidth / 2;
t.position.y = window.innerHeight / 2;
t.theta = 0;

stage.addChild(t);

for (var i = 0; i < 15; i++) {
  path[i] = {
    x: random_range(0, window.innerWidth),
    y: random_range(0, window.innerHeight )
  };
}

tween = TweenMax.to(position, 25, {
  bezier: {
    type: "soft",
    values: path,
    autoRotate: true
  },
  onUpdateParams: [t, position],
  onUpdate: function (t, position) {
    t.move(position);
  },
  repeat: -1,
  yoyo: true
});

elapsed = Date.now()
now = 0;
render();

var fps = 60,
  now,
  delta,
  elapsed = 0;

function render() {
  requestAnimationFrame(render);
  now = Date.now();
  delta = now - elapsed;
  if (delta > 1000 / fps) {
    t.update();
    ai.update(t);
    stats.update();
    elapsed = now - (delta % (1000 / fps));
    renderer.render(stage);
  }
}

            
          
!
999px
🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.
Loading ..................

Console