<canvas id="ameba"></canvas>
#ameba {
	background:#fff;
	box-shadow: 0 0 50px rgba(0,0,0,.7);
	margin: 0 auto 60px;
	display: block;
	width: 50%;
	height: 50%;
}
View Compiled
// V 1.0.1
// released under MIT license by MBMedia.cc
// documentation found at http://mbmedia.cc/stuff/ink-blob-effect

function InkBlobEffect(dObj, rect, autoUpdate, quality) {
    this.target = dObj;

    var blurFilter = new createjs.BlurFilter(20, 20, quality || 1);
    var colorFilter = new createjs.ColorFilter(1, 1, 1, 30, 0, 0, 0, -2500);
    this.target.filters = [blurFilter, colorFilter];
    this.target.cache(rect[0], rect[1], rect[2], rect[3]);

    // call this manually to update, or just allow it to autoUpdate
    this.update = function () {
        this.target.updateCache();
    }

    // toggle the ticker on and off via autoRender
    // NOTE: it is preferred that you set autoUpdate to false and
    // update the instance via  it's instance.update() function
    // in the same ticker as you update the stage, that way it
    // always updates BEFORE the stage does
    var _autoRender = false;
    var _renderListener = null;
    Object.defineProperty(this, 'autoRender', {
        get: function () {
            return _autoRender;
        },
        set: function (val) {
            if (val == _autoRender) return;
            _autoRender = val;
            if (val == true)
                _renderListener = createjs.Ticker.on('tick', this.update, this);
            else if (_renderListener)
                createjs.Ticker.off('tick', _renderListener);
        }
    });

    if (autoUpdate !== false) {
        this.autoRender = true;
    }
}

var stage = new createjs.Stage('ameba');
		
		var cont = new createjs.Container();
		cont.x = 300; cont.y = 150;
		stage.addChild(cont);
		
		makeShape(30, -20, -15);
		makeShape(10, 5, 5);
		makeShape(12, 8, 20);
		makeShape(17, -40, 10);
		makeShape(15, 40, -10);
		makeShape(15, 30, -20);
		makeShape(20, -60, 5);
		makeShape(20, 60, 10);
		
		function makeShape(size, x, y)
		{
			var c = new createjs.Shape();
			c.graphics.beginFill('#f90').drawCircle(0,0,size);
			c.x = x; c.y = y;
			cont.addChild(c);
			Math.random()>.5 ? tweenLeft(c) : tweenRight(c);
		}
		
		function tweenLeft(c) {
			createjs.Tween.get(c).to({x:-Math.random()*90}, Math.random()*1500+1000, createjs.Ease.quadInOut).call(tweenRight, [c]);
		}
		function tweenRight(c) {
			createjs.Tween.get(c).to({x:Math.random()*90}, Math.random()*1500+1000, createjs.Ease.quadInOut).call(tweenLeft, [c]);
		}
		
		var inkEffect = new InkBlobEffect(cont, [-150,-200,500,400], false, 2);
		
		createjs.Ticker.setFPS(30);
		createjs.Ticker.addEventListener('tick', onTick);
		function onTick()
		{
			inkEffect.update();
			stage.update();
		}
		stage.update();

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://code.createjs.com/easeljs-0.8.1.min.js
  2. https://code.createjs.com/tweenjs-0.6.1.min.js