First checkout this demo link on your cell phone: https://sreenath.net/demos/animation.htm

On a normal desktop browser with no Vibration hardware, you will see a ball simply bouncing on a black background. On a device with Vibration hardware and a supporting browser, you will feel the ball bounce off the sides of the window with a short vibration.

That’s new in HTML5 and JavaScript. Here how its done:

navigator.vibrate Sample Code. function vibrate(){ if(navigator.vibrate){ navigator.vibrate(100); } } 1 2 3 4 5 function vibrate ( ) { if ( navigator . vibrate ) { navigator . vibrate ( 100 ) ; } }

It’s that simple. 100 here is the duration to vibrate. You can also pass in an array of milliseconds, duration of vibration followed by duration of silence and so on as follows:

navigator.vibrate([100,300,100,100,300,100]); 1 navigator . vibrate ( [ 100 , 300 , 100 , 100 , 300 , 100 ] ) ;

Now about timing the vibrations with the animation:

I use a JSON object as a Singleton for storing data about the window height, width, position of the ball, direction etc.

JSON Singleton for configuration data var singleton = { clientH:0, clientW:0, box:"", timer:null, hdirection:1, vdirection:1, step:1, offset:50}; 1 2 3 4 5 6 7 8 var singleton = { clientH : 0 , clientW : 0 , box : "" , timer : null , hdirection : 1 , vdirection : 1 , step : 1 , offset : 50 } ;

I have the following event handlers attached to the window load event and the window resize event: (Note that this code wont gracefully degrade in IE8 and older browsers)

Load and Resize Event Listeners window.addEventListener("load",function(){ startAnimation("box1",2); }); window.addEventListener("resize",function(){ setDimensions(); }); 1 2 3 4 5 6 7 window . addEventListener ( "load" , function ( ) { startAnimation ( "box1" , 2 ) ; } ) ; window . addEventListener ( "resize" , function ( ) { setDimensions ( ) ; } ) ;

My startAnimation function:

startAnimation Function function startAnimation(id, s){ setDimensions(); singleton.box = document.getElementById(id); singleton.box.style.left = "1px"; singleton.box.style.top = "1px"; singleton.step = s; singleton.timer = setInterval(animate, 10); } 1 2 3 4 5 6 7 8 function startAnimation ( id , s ) { setDimensions ( ) ; singleton . box = document . getElementById ( id ) ; singleton . box . style . left = "1px" ; singleton . box . style . top = "1px" ; singleton . step = s ; singleton . timer = setInterval ( animate , 10 ) ; }

It is important that the CSS for the box1 object to move is to set its position as absolute. Otherwise the best code won’t work on it. So here’s the CSS:

CSS for movable box .box { display:block; height:50px; width:50px; background:#C0D617 url('images/ball.png'); line-height:50px; left:0; position:absolute; color:black; text-align:center; border-radius:50px; } 1 2 3 4 5 6 7 8 9 10 11 12 13 .box { display : block ; height : 50px ; width : 50px ; background : #C0D617 url ( 'images/ball.png' ) ; line-height : 50px ; left : 0 ; position : absolute ; color : black ; text-align : center ; border-radius : 50px ; }

Finally my Animate function.

Animate function function animate(){ var l = parseInt(singleton.box.style.left); var t = parseInt(singleton.box.style.top); if((singleton.hdirection == 1) && ((l+singleton.offset) > singleton.clientW)) { singleton.hdirection = -1; vibrate(); } else if((singleton.hdirection == -1)&&(l<=0)) { singleton.hdirection = 1; vibrate(); } if((singleton.vdirection==1) && ((t+singleton.offset) > singleton.clientH)) { singleton.vdirection = -1; vibrate(); } else if((singleton.vdirection == -1)&&(t<=0)) { singleton.vdirection = 1; vibrate(); } if(singleton.hdirection==1) l+=singleton.step; else l-=singleton.step; if(singleton.vdirection==1) t+=singleton.step; else t-=singleton.step; singleton.box.style.left = l+"px"; singleton.box.style.top = t+"px"; //window.scrollTo(0, document.body.scrollHeight); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 function animate ( ) { var l = parseInt ( singleton . box . style . left ) ; var t = parseInt ( singleton . box . style . top ) ; if ( ( singleton . hdirection == 1 ) && ( ( l + singleton . offset ) > singleton . clientW ) ) { singleton . hdirection = - 1 ; vibrate ( ) ; } else if ( ( singleton . hdirection == - 1 ) && ( l <= 0 ) ) { singleton . hdirection = 1 ; vibrate ( ) ; } if ( ( singleton . vdirection == 1 ) && ( ( t + singleton . offset ) > singleton . clientH ) ) { singleton . vdirection = - 1 ; vibrate ( ) ; } else if ( ( singleton . vdirection == - 1 ) && ( t <= 0 ) ) { singleton . vdirection = 1 ; vibrate ( ) ; } if ( singleton . hdirection == 1 ) l += singleton . step ; else l -= singleton . step ; if ( singleton . vdirection == 1 ) t += singleton . step ; else t -= singleton . step ; singleton . box . style . left = l + "px" ; singleton . box . style . top = t + "px" ; //window.scrollTo(0, document.body.scrollHeight); }

Its important to update the direction of the movement of the box once it hits the edge and to check the direction each time before moving the box to determine which way it should be headed – to decide whether to increment or decrement the left/top property.

And my setDimensions function, required for initial loading and handling browser resize events:

setDimensions Function function setDimensions(){ if (window.innerWidth) { singleton.clientW = window.innerWidth-10; singleton.clientH = window.innerHeight-10; } else if (document.body.clientWidth) { singleton.clientW = document.body.clientWidth-10; singleton.clientH = document.body.clientHeight-10; } } 1 2 3 4 5 6 7 8 9 10 function setDimensions ( ) { if ( window . innerWidth ) { singleton . clientW = window . innerWidth - 10 ; singleton . clientH = window . innerHeight - 10 ; } else if ( document . body . clientWidth ) { singleton . clientW = document . body . clientWidth - 10 ; singleton . clientH = document . body . clientHeight - 10 ; } }

Known Issues with the demo:

Doesn’t handle resize due to re-orientation event of your device. As of publishing time, Safari doesn’t support the Vibration API. That leaves out all iOS devices from enjoying this demo.