/*jshint laxcomma: true, laxbreak: true, asi: true, undef: true*/
/*global THREE: true, jQuery:true, requestAnimationFrame:true */

(function ($) {
  
  // set the scene size
  var WIDTH = 400
    , HEIGHT = 300
  
  // set some camera attributes
  var VIEW_ANGLE = 45
    , ASPECT = WIDTH / HEIGHT
    , NEAR = 0.1
    , FAR = 10000
  
  var $container = $('#container')
  
  var renderer = new THREE.WebGLRenderer({antialias: true})
    , camera = new THREE.PerspectiveCamera(
        VIEW_ANGLE
      , ASPECT
      , NEAR
      , FAR
      )
    , scene = new THREE.Scene()
    
  scene.add(camera)
  camera.position.set(0,100,200)
  camera.lookAt(new THREE.Vector3(0,0,0))
  renderer.setSize(WIDTH, HEIGHT)
  $container.append(renderer.domElement)
  
  /* ----------------- Plane ------------------------- */
  
  var plane = new THREE.Mesh(
      new THREE.PlaneGeometry(400, 400)
    , new THREE.MeshBasicMaterial({color: 0x3E454F})
    )
  scene.add(plane)
  plane.rotation.x = - Math.PI / 2
  plane.position.y = -50
  
  /* ----------------- Sphere ------------------------- */
  
  var radius = 50
    , segments = 16
    , rings = 16
    , sphereMaterial = new THREE.MeshLambertMaterial({color: 0x677982})
    , sphere = new THREE.Mesh(
        new THREE.SphereGeometry(radius, segments, rings)
      , sphereMaterial
      )
  //sphere.geometry.dynamic = true
  scene.add(sphere)
  
  /* ----------------- Curve ------------------------- */
  
  var parent = new THREE.Object3D()
  
  parent.add(createHelixMesh(Math.acos(3/5), 50, 2))
  scene.add(parent)
  parent.rotation.x = Math.PI / 2
  parent.rotation.z = Math.PI / 6
  
  /* ------------ LIGHT ------------------- */
  
  var pointLight = new THREE.PointLight(0xFFFFFF)
  pointLight.position.set(10, 100, 130)
  scene.add(pointLight)
  
  /* ------------ SLIDER ------------------- */
  
  $('#slider').slider({
    min: 0
  , max: Math.PI/2
  , slide: function (e, ui) {
      $.each(parent.children, function (idx, obj) {
        parent.remove(obj)
        renderer.deallocateObject(obj)
        obj.deallocate()
      })
      parent.add(createHelixMesh(ui.value, 50, 2))
    }
  , value: Math.acos(3/5)
  , step: Math.acos(3/5) / 35
  })
  
  /* -------------- RENDER LOOP ---------------- */
  
  var startTime = Date.now();
  
  function render() {
    requestAnimationFrame(render);
    renderer.render(scene, camera);
  }
  
  // begin rendering
  render();
  
  function createHelixMesh(phi, rad, rot) {
    var extrudePath = new THREE.TubeGeometry(
        new THREE.SphericalHelix(phi, rad, rot)
      , 300, 1, 8
      )
   
    return new THREE.Mesh( extrudePath
        , new THREE.MeshLambertMaterial({
            color: 0xDB2B35
          , opacity: 0.8
          , transparent: true
          })
        )
  }
})(jQuery);
<!DOCTYPE html>
<html>

  <head lang="en">
    <meta charset="utf-8">
    <title>My First three.js Plunk</title>
    <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" />
  </head>
  
  <body>
    
    <div id="container"></div>
    <div id="slider" width="50"></div>
    
    <!-- Load JS last -->
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/three.js/r53/three.min.js"></script>
    <script src="//raw.github.com/mrdoob/three.js/master/examples/js/CurveExtras.js"></script>
    <script src="anim-frame-pf.js"></script>
    <script src="Helices.js"></script>
    <script src="scene.js"></script>
  
  </body>
  
</html>
/***
 * 
 * requestAnimationFrame polyfill by Erik Möller
 * source: http://paulirish.com/2011/requestanimationframe-for-smart-animating/
 * 
 */

(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);
        };
}());
(function (){
  var C = Math.cos,
      S = Math.sin;

  THREE.SphericalHelix = THREE.Curve.create(
    
    function (phi, radius, revolutions) {
      this.phi = phi;
      this.radius = radius || 50;
      this.revolutions = revolutions || 2;
    },
    
    function (t) {
      t *= 2 * Math.PI * this.revolutions;
      
      var r = this.radius,
        p = this.phi,
        tx = 0.5*r*(1+C(p))*C(t) - 0.5*r*(1-C(p))*C(t*(1+C(p))/(1-C(p))),
        ty = 0.5*r*(1+C(p))*S(t) - 0.5*r*(1-C(p))*S(t*(1+C(p))/(1-C(p))),
        tz = r*S(p)*C(t*C(p)/(1-C(p)));
        
      return new THREE.Vector3(tx, ty, tz);
    }
  );

})();