Golfed Codepen – 3D Spiral Thing 
copy // sort of golfed version of https://www.instagram.com/p/C1uv6Kqv19T/ // by @mewtru b =  document.body  a =  Object .assign  a( b.style ,  {  background: '#000' ,  color: '#fff' } )  w =  'snippet.zone snippet.zone' .toUpperCase ( ) .split `` F =  ( n,  O =  0 ,  C,  S,  o,  t)  =>  {     b.innerHTML  +=  `< div id= ${ n}  style= 'position:absolute;left:50%;top:50%;translate:-50% -50%;width:100% text-align:center;white-space:nowrap' ></ div> `   w.map ( l =>  this [ n] .innerHTML  +=  `< span style= 'display:inline-block;margin-right:5px;font-size:28px' > ${ l} </ span> `)    t =  O   setInterval( _ =>  {      t +=  .005     ; [ ...this [ n] .children ] .map ( ( e,  i)  =>  {         T =  t +  i /  2.7        a( e.style ,  {          translate:  `0  ${ Math .sin ( T)  *  100 } px`,          scale:  Math .cos ( T)  *  .5 +  .5} )      } ,  16 )    } )  } F( 'Z' )   F( 'X' ,  3 )  Try it out… 
“Very cool” pen by Lucas Fernando  that comes from @mewtru 
 
            
             
            Faster than save/restore HTML5 canvas 
copy const  canvas =  document.createElement ( 'canvas' ) const  c =  canvas.getContext ( '2d' )   canvas.width  =  innerWidth canvas.height  =  innerHeight   document.body .append ( canvas)    c.fillStyle  =  'black'  c.fillRect ( 0 ,  0 ,  canvas.width ,  canvas.height )    class Shooter {    constructor( )  {      this .x  =  innerWidth /  2      this .y  =  innerHeight /  2      this .vx  =  Math .random ( )  *  10  -  5      this .vy  =  Math .random ( )  *  10  -  5      this .color  =  'rgba(255, 0, 0, 0.5)'      this .size  =  10      this .halfSize  =  this .size  /  2    }    draw( )  {      this .x  +=  this .vx      this .y  +=  this .vy        if  ( this .x  <  0 )  {        this .x  =  innerWidth     }  else  if  ( this .x  >  innerWidth)  {        this .x  =  0      }        if  ( this .y  <  0 )  {        this .y  =  innerHeight     }  else  if  ( this .y  >  innerHeight)  {        this .y  =  0      }        c.fillStyle  =  this .color      c.translate ( this .x ,  this .y )      c.fillRect ( - this .halfSize ,  - this .halfSize ,  this .size ,  this .size )        c.setTransform ( 1 ,  0 ,  0 ,  1 ,  0 ,  0 )    }  }   const  NUM =  1000 const  shooters =  [ ] for  ( let  i =  0 ;  i <  NUM;  i++ )  {   shooters.push ( new  Shooter( ) )  }   function  loop( )  {   c.fillStyle  =  'rgba(0, 0, 0, 0.1)'    c.fillRect ( 0 ,  0 ,  innerWidth,  innerHeight)      for  ( let  i =  0 ;  i <  NUM;  i++ )  {      shooters[ i] .draw ( )    }    requestAnimationFrame( loop)  } loop( )  Try it out… 
Using setTransform(1, 0, 0, 1, 0, 0) is faster than using save and restore. If you don’t need to save context info like fills, line styles etc… consider this method.