Skip to content

Instantly share code, notes, and snippets.

@tweinfeld
Last active February 3, 2017 08:53
Show Gist options
  • Save tweinfeld/6dc8fef0f6d8b620b117a3de9101a167 to your computer and use it in GitHub Desktop.
Save tweinfeld/6dc8fef0f6d8b620b117a3de9101a167 to your computer and use it in GitHub Desktop.
A rudimentary 360° video sphere projector. Receives a source element (i.e. <video/>) to read from and a destination <canvas/> to draw into.
define([
"jquery",
"lodash",
"three"
], function(
$,
_,
Three
){
var requestAnimationFrame = (window.requestAnimationFrame || _.noop).bind(window),
cancelAnimationFrame = (window.cancelAnimationFrame || _.noop).bind(window);
var CAMERA_FIELD_OF_VIEW = 45,
SPHERE_RADIUS = 10,
SPHERE_WIDTH_SEGS = 32,
SPHERE_HEIGHT_SEGS = 32;
var toRad = function(deg){ return Math.PI / 180 * deg; };
var Constructor = function(options){
this.setSourceElement(options["sourceElement"], options["canvas"]);
this.setCameraRotation.apply(this, ["x", "y", "z"].map(_.partial(_.result, options["initialCameraRotation"], _, 0)));
};
Constructor.prototype = {
setSourceElement: function(element, canvas){
this.stop();
var $src = $(element),
width = $src.width(),
height = $src.height();
this._camera = new Three.PerspectiveCamera(CAMERA_FIELD_OF_VIEW, width / height, 0.1, 1000);
var renderer = this._renderer = new Three.WebGLRenderer({
canvas: canvas,
precision: "highp",
antialias: true
});
this.el = renderer.domElement;
var scene = this._scene = new Three.Scene(),
sphereGeometry = new Three.SphereGeometry(SPHERE_RADIUS, SPHERE_WIDTH_SEGS, SPHERE_HEIGHT_SEGS),
texture = this._texture = new Three.Texture(element),
material = new Three.MeshBasicMaterial({ map: texture }),
sphere = this._sphere = new Three.Mesh(sphereGeometry, material);
sphere.scale.x = -1;
material.side = Three.FrontSide;
texture.generateMipmaps = false;
texture.magFilter = Three.LinearFilter;
texture.minFilter = Three.LinearFilter;
scene.add(sphere);
return this.el;
},
setCameraRotation: function(x, y, z){
_.extend(this._sphere.rotation, {
x: toRad(x),
y: toRad(y),
z: toRad(z)
});
},
play: function(){
this.stop();
var run = function(){
this._texture.needsUpdate = true;
this._renderer.render(this._scene, this._camera);
this.stop = cancelAnimationFrame.bind(this, requestAnimationFrame(run));
}.bind(this);
run();
},
stop: function(){},
destroy: function(){
this.stop();
_.extend(this, {
"_texture": undefined,
"_renderer": undefined,
"_scene": undefined
});
}
};
return Constructor;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment