diff --git a/100_projects/72-effects-on-mousemove-using-sketch.js/index.html b/100_projects/72-effects-on-mousemove-using-sketch.js/index.html
new file mode 100644
index 0000000..1d71db1
--- /dev/null
+++ b/100_projects/72-effects-on-mousemove-using-sketch.js/index.html
@@ -0,0 +1,155 @@
+
+
+
+
+
+
+
+ Document
+
+
+ Mouse Move
+
+
+
+
\ No newline at end of file
diff --git a/100_projects/72-effects-on-mousemove-using-sketch.js/sketch.js b/100_projects/72-effects-on-mousemove-using-sketch.js/sketch.js
new file mode 100644
index 0000000..0862cdb
--- /dev/null
+++ b/100_projects/72-effects-on-mousemove-using-sketch.js/sketch.js
@@ -0,0 +1,631 @@
+
+/* Copyright (C) 2013 Justin Windle, http://soulwire.co.uk */
+
+(function ( root, factory ) {
+
+ if ( typeof exports === 'object' ) {
+
+ // CommonJS like
+ module.exports = factory(root, root.document);
+
+ } else if ( typeof define === 'function' && define.amd ) {
+
+ // AMD
+ define( function() { return factory( root, root.document ); });
+
+ } else {
+
+ // Browser global
+ root.Sketch = factory( root, root.document );
+ }
+
+}( typeof window !== "undefined" ? window : this, function ( window, document ) {
+
+
+ "use strict";
+
+ /*
+ ----------------------------------------------------------------------
+
+ Config
+
+ ----------------------------------------------------------------------
+ */
+
+ var MATH_PROPS = 'E LN10 LN2 LOG2E LOG10E PI SQRT1_2 SQRT2 abs acos asin atan ceil cos exp floor log round sin sqrt tan atan2 pow max min'.split( ' ' );
+ var HAS_SKETCH = '__hasSketch';
+ var M = Math;
+
+ var CANVAS = 'canvas';
+ var WEBGL = 'webgl';
+ var DOM = 'dom';
+
+ var doc = document;
+ var win = window;
+
+ var instances = [];
+
+ var defaults = {
+
+ fullscreen: true,
+ autostart: true,
+ autoclear: true,
+ autopause: true,
+ container: doc.body,
+ interval: 1,
+ globals: true,
+ retina: false,
+ type: CANVAS
+ };
+
+ var keyMap = {
+
+ 8: 'BACKSPACE',
+ 9: 'TAB',
+ 13: 'ENTER',
+ 16: 'SHIFT',
+ 27: 'ESCAPE',
+ 32: 'SPACE',
+ 37: 'LEFT',
+ 38: 'UP',
+ 39: 'RIGHT',
+ 40: 'DOWN'
+ };
+
+ /*
+ ----------------------------------------------------------------------
+
+ Utilities
+
+ ----------------------------------------------------------------------
+ */
+
+ function isArray( object ) {
+
+ return Object.prototype.toString.call( object ) == '[object Array]';
+ }
+
+ function isFunction( object ) {
+
+ return typeof object == 'function';
+ }
+
+ function isNumber( object ) {
+
+ return typeof object == 'number';
+ }
+
+ function isString( object ) {
+
+ return typeof object == 'string';
+ }
+
+ function keyName( code ) {
+
+ return keyMap[ code ] || String.fromCharCode( code );
+ }
+
+ function extend( target, source, overwrite ) {
+
+ for ( var key in source )
+
+ if ( overwrite || !( key in target ) )
+
+ target[ key ] = source[ key ];
+
+ return target;
+ }
+
+ function proxy( method, context ) {
+
+ return function() {
+
+ method.apply( context, arguments );
+ };
+ }
+
+ function clone( target ) {
+
+ var object = {};
+
+ for ( var key in target ) {
+
+ if ( key === 'webkitMovementX' || key === 'webkitMovementY' )
+ continue;
+
+ if ( isFunction( target[ key ] ) )
+
+ object[ key ] = proxy( target[ key ], target );
+
+ else
+
+ object[ key ] = target[ key ];
+ }
+
+ return object;
+ }
+
+ /*
+ ----------------------------------------------------------------------
+
+ Constructor
+
+ ----------------------------------------------------------------------
+ */
+
+ function constructor( context ) {
+
+ var request, handler, target, parent, bounds, index, suffix, clock, node, copy, type, key, val, min, max, w, h;
+
+ var counter = 0;
+ var touches = [];
+ var resized = false;
+ var setup = false;
+ var ratio = win.devicePixelRatio || 1;
+ var isDiv = context.type == DOM;
+ var is2D = context.type == CANVAS;
+
+ var mouse = {
+ x: 0.0, y: 0.0,
+ ox: 0.0, oy: 0.0,
+ dx: 0.0, dy: 0.0
+ };
+
+ var eventMap = [
+
+ context.eventTarget || context.element,
+
+ pointer, 'mousedown', 'touchstart',
+ pointer, 'mousemove', 'touchmove',
+ pointer, 'mouseup', 'touchend',
+ pointer, 'click',
+ pointer, 'mouseout',
+ pointer, 'mouseover',
+
+ doc,
+
+ keypress, 'keydown', 'keyup',
+
+ win,
+
+ active, 'focus', 'blur',
+ resize, 'resize'
+ ];
+
+ var keys = {}; for ( key in keyMap ) keys[ keyMap[ key ] ] = false;
+
+ function trigger( method ) {
+
+ if ( isFunction( method ) )
+
+ method.apply( context, [].splice.call( arguments, 1 ) );
+ }
+
+ function bind( on ) {
+
+ for ( index = 0; index < eventMap.length; index++ ) {
+
+ node = eventMap[ index ];
+
+ if ( isString( node ) )
+
+ target[ ( on ? 'add' : 'remove' ) + 'EventListener' ].call( target, node, handler, false );
+
+ else if ( isFunction( node ) )
+
+ handler = node;
+
+ else target = node;
+ }
+ }
+
+ function update() {
+
+ cAF( request );
+ request = rAF( update );
+
+ if ( !setup ) {
+
+ trigger( context.setup );
+ setup = isFunction( context.setup );
+ }
+
+ if ( !resized ) {
+ trigger( context.resize );
+ resized = isFunction( context.resize );
+ }
+
+ if ( context.running && !counter ) {
+
+ context.dt = ( clock = +new Date() ) - context.now;
+ context.millis += context.dt;
+ context.now = clock;
+
+ trigger( context.update );
+
+ // Pre draw
+
+ if ( is2D ) {
+
+ if ( context.retina ) {
+
+ context.save();
+
+ if (context.autoclear) {
+ context.scale( ratio, ratio );
+ }
+ }
+
+ if ( context.autoclear )
+
+ context.clear();
+ }
+
+ // Draw
+
+ trigger( context.draw );
+
+ // Post draw
+
+ if ( is2D && context.retina )
+
+ context.restore();
+ }
+
+ counter = ++counter % context.interval;
+ }
+
+ function resize() {
+
+ target = isDiv ? context.style : context.canvas;
+ suffix = isDiv ? 'px' : '';
+
+ w = context.width;
+ h = context.height;
+
+ if ( context.fullscreen ) {
+
+ h = context.height = win.innerHeight;
+ w = context.width = win.innerWidth;
+ }
+
+ if ( context.retina && is2D && ratio ) {
+
+ target.style.height = h + 'px';
+ target.style.width = w + 'px';
+
+ w *= ratio;
+ h *= ratio;
+ }
+
+ if ( target.height !== h )
+
+ target.height = h + suffix;
+
+ if ( target.width !== w )
+
+ target.width = w + suffix;
+
+ if ( is2D && !context.autoclear && context.retina )
+
+ context.scale( ratio, ratio );
+
+ if ( setup ) trigger( context.resize );
+ }
+
+ function align( touch, target ) {
+
+ bounds = target.getBoundingClientRect();
+
+ touch.x = touch.pageX - bounds.left - (win.scrollX || win.pageXOffset);
+ touch.y = touch.pageY - bounds.top - (win.scrollY || win.pageYOffset);
+
+ return touch;
+ }
+
+ function augment( touch, target ) {
+
+ align( touch, context.element );
+
+ target = target || {};
+
+ target.ox = target.x || touch.x;
+ target.oy = target.y || touch.y;
+
+ target.x = touch.x;
+ target.y = touch.y;
+
+ target.dx = target.x - target.ox;
+ target.dy = target.y - target.oy;
+
+ return target;
+ }
+
+ function process( event ) {
+
+ event.preventDefault();
+
+ copy = clone( event );
+ copy.originalEvent = event;
+
+ if ( copy.touches ) {
+
+ touches.length = copy.touches.length;
+
+ for ( index = 0; index < copy.touches.length; index++ )
+
+ touches[ index ] = augment( copy.touches[ index ], touches[ index ] );
+
+ } else {
+
+ touches.length = 0;
+ touches[0] = augment( copy, mouse );
+ }
+
+ extend( mouse, touches[0], true );
+
+ return copy;
+ }
+
+ function pointer( event ) {
+
+ event = process( event );
+
+ min = ( max = eventMap.indexOf( type = event.type ) ) - 1;
+
+ context.dragging =
+
+ /down|start/.test( type ) ? true :
+
+ /up|end/.test( type ) ? false :
+
+ context.dragging;
+
+ while( min )
+
+ isString( eventMap[ min ] ) ?
+
+ trigger( context[ eventMap[ min-- ] ], event ) :
+
+ isString( eventMap[ max ] ) ?
+
+ trigger( context[ eventMap[ max++ ] ], event ) :
+
+ min = 0;
+ }
+
+ function keypress( event ) {
+
+ key = event.keyCode;
+ val = event.type == 'keyup';
+ keys[ key ] = keys[ keyName( key ) ] = !val;
+
+ trigger( context[ event.type ], event );
+ }
+
+ function active( event ) {
+
+ if ( context.autopause )
+
+ ( event.type == 'blur' ? stop : start )();
+
+ trigger( context[ event.type ], event );
+ }
+
+ // Public API
+
+ function start() {
+
+ context.now = +new Date();
+ context.running = true;
+ }
+
+ function stop() {
+
+ context.running = false;
+ }
+
+ function toggle() {
+
+ ( context.running ? stop : start )();
+ }
+
+ function clear() {
+
+ if ( is2D )
+
+ context.clearRect( 0, 0, context.width * ratio, context.height * ratio );
+ }
+
+ function destroy() {
+
+ parent = context.element.parentNode;
+ index = instances.indexOf( context );
+
+ if ( parent ) parent.removeChild( context.element );
+ if ( ~index ) instances.splice( index, 1 );
+
+ bind( false );
+ stop();
+ }
+
+ extend( context, {
+
+ touches: touches,
+ mouse: mouse,
+ keys: keys,
+
+ dragging: false,
+ running: false,
+ millis: 0,
+ now: NaN,
+ dt: NaN,
+
+ destroy: destroy,
+ toggle: toggle,
+ clear: clear,
+ start: start,
+ stop: stop
+ });
+
+ instances.push( context );
+
+ return ( context.autostart && start(), bind( true ), resize(), update(), context );
+ }
+
+ /*
+ ----------------------------------------------------------------------
+
+ Global API
+
+ ----------------------------------------------------------------------
+ */
+
+ var element, context, Sketch = {
+
+ CANVAS: CANVAS,
+ WEB_GL: WEBGL,
+ WEBGL: WEBGL,
+ DOM: DOM,
+
+ instances: instances,
+
+ install: function( context ) {
+
+ if ( !context[ HAS_SKETCH ] ) {
+
+ for ( var i = 0; i < MATH_PROPS.length; i++ )
+
+ context[ MATH_PROPS[i] ] = M[ MATH_PROPS[i] ];
+
+ extend( context, {
+
+ TWO_PI: M.PI * 2,
+ HALF_PI: M.PI / 2,
+ QUARTER_PI: M.PI / 4,
+
+ random: function( min, max ) {
+
+ if ( isArray( min ) )
+
+ return min[ ~~( M.random() * min.length ) ];
+
+ if ( !isNumber( max ) )
+
+ max = min || 1, min = 0;
+
+ return min + M.random() * ( max - min );
+ },
+
+ lerp: function( min, max, amount ) {
+
+ return min + amount * ( max - min );
+ },
+
+ map: function( num, minA, maxA, minB, maxB ) {
+
+ return ( num - minA ) / ( maxA - minA ) * ( maxB - minB ) + minB;
+ }
+ });
+
+ context[ HAS_SKETCH ] = true;
+ }
+ },
+
+ create: function( options ) {
+
+ options = extend( options || {}, defaults );
+
+ if ( options.globals ) Sketch.install( self );
+
+ element = options.element = options.element || doc.createElement( options.type === DOM ? 'div' : 'canvas' );
+
+ context = options.context = options.context || (function() {
+
+ switch( options.type ) {
+
+ case CANVAS:
+
+ return element.getContext( '2d', options );
+
+ case WEBGL:
+
+ return element.getContext( 'webgl', options ) || element.getContext( 'experimental-webgl', options );
+
+ case DOM:
+
+ return element.canvas = element;
+ }
+
+ })();
+
+ ( options.container || doc.body ).appendChild( element );
+
+ return Sketch.augment( context, options );
+ },
+
+ augment: function( context, options ) {
+
+ options = extend( options || {}, defaults );
+
+ options.element = context.canvas || context;
+ options.element.className += ' sketch';
+
+ extend( context, options, true );
+
+ return constructor( context );
+ }
+ };
+
+ /*
+ ----------------------------------------------------------------------
+
+ Shims
+
+ ----------------------------------------------------------------------
+ */
+
+ var vendors = [ 'ms', 'moz', 'webkit', 'o' ];
+ var scope = self;
+ var then = 0;
+
+ var a = 'AnimationFrame';
+ var b = 'request' + a;
+ var c = 'cancel' + a;
+
+ var rAF = scope[ b ];
+ var cAF = scope[ c ];
+
+ for ( var i = 0; i < vendors.length && !rAF; i++ ) {
+
+ rAF = scope[ vendors[ i ] + 'Request' + a ];
+ cAF = scope[ vendors[ i ] + 'Cancel' + a ];
+ }
+
+ scope[ b ] = rAF = rAF || function( callback ) {
+
+ var now = +new Date();
+ var dt = M.max( 0, 16 - ( now - then ) );
+ var id = setTimeout( function() {
+ callback( now + dt );
+ }, dt );
+
+ then = now + dt;
+ return id;
+ };
+
+ scope[ c ] = cAF = cAF || function( id ) {
+ clearTimeout( id );
+ };
+
+ /*
+ ----------------------------------------------------------------------
+
+ Output
+
+ ----------------------------------------------------------------------
+ */
+
+ return Sketch;
+
+}));
diff --git a/100_projects/72-effects-on-mousemove-using-sketch.js/style.css b/100_projects/72-effects-on-mousemove-using-sketch.js/style.css
new file mode 100644
index 0000000..421e1e8
--- /dev/null
+++ b/100_projects/72-effects-on-mousemove-using-sketch.js/style.css
@@ -0,0 +1,25 @@
+*{
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+body{
+ background: #000;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ min-height: 100vh;
+}
+h1{
+ position: relative;
+ color: #fff;
+ font-size: 100px;
+ text-align: center;
+}
+canvas{
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+}
\ No newline at end of file