Skip to content

Instantly share code, notes, and snippets.

@blackslate
Last active December 4, 2015 19:16
Show Gist options
  • Save blackslate/b6d55a9bec416abccc54 to your computer and use it in GitHub Desktop.
Save blackslate/b6d55a9bec416abccc54 to your computer and use it in GitHub Desktop.
Trackball Camera
<!-- Demo: http://lexogram.com/clara/trackballCamera/ -->
<!DOCTYPE html>
<html>
<head>
<title>THREE.JS WORLD</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r73/three.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="WebGL-output"></div>
<script>
var cube
var camera
function init() {
var scene = new THREE.Scene()
var renderer = new THREE.WebGLRenderer()
var cameras = []
var SIDE = 100
var RADIUS = Math.sqrt((SIDE/2 * SIDE/2) * 3)
var WIDTH = window.innerWidth
var HEIGHT = window.innerHeight
// For mouse interactions
var centreX
var centreY
var radius
var radius2
var start = new THREE.Vector3()
var end = new THREE.Vector3()
var angle
var rotationMatrix = new THREE.Matrix4()
;(function createOrthographicCamera(){
camera = new THREE.OrthographicCamera(
-RADIUS, RADIUS
, RADIUS, -RADIUS
, -RADIUS, RADIUS
)
var side = Math.min(WIDTH, HEIGHT)
camera.viewport = {
x: (WIDTH - side) / 2
, y: (HEIGHT - side) / 2
, width: side
, height: side
}
camera.matrixAutoUpdate = false
cameras.push(camera)
centreX = WIDTH/2
centreY = HEIGHT/2
radius = side/2
radius2 = radius * radius
})()
;(function createCubeAndSphere(){
// Something to look at
cube = new THREE.Object3D()
var cubeGeometry = new THREE.BoxGeometry( SIDE, SIDE, SIDE )
var lineMaterial = new THREE.LineBasicMaterial({
color: 0xffffff
, transparent: true
, opacity: 0.5
})
var faceMaterial = new THREE.MeshPhongMaterial({
color: 0x006699
, emissive: 0x072534
, shading: THREE.FlatShading
})
cube.add(
new THREE.LineSegments(
new THREE.WireframeGeometry( cubeGeometry )
, lineMaterial
)
)
cube.add(
new THREE.Mesh(
cubeGeometry
, faceMaterial
)
)
cube.add(new THREE.AxisHelper(RADIUS))
scene.add( cube );
var sphereGeometry = new THREE.SphereGeometry( RADIUS, 36, 36)
var sphereMaterial = new THREE.MeshBasicMaterial( {
color: 0x000000
, transparent: true
, opacity: 0.2
} )
var sphere = new THREE.Mesh( sphereGeometry, sphereMaterial )
scene.add( sphere )
})()
;(function initializeRenderer(){
renderer.setClearColor(new THREE.Color(0xEEEEFF))
renderer.setSize(WIDTH, HEIGHT)
renderer.autoClear = false;
document.getElementById("WebGL-output").appendChild(renderer.domElement)
})()
;(function render() {
var viewport
renderer.setViewport( 0, 0, WIDTH, HEIGHT );
renderer.clear();
cameras.forEach(function (camera) {
viewport = camera.viewport // custom property
renderer.setViewport(
viewport.x
, viewport.y
, viewport.width
, viewport.height
)
renderer.render(scene, camera)
})
requestAnimationFrame(render)
})()
window.addEventListener("mousedown", startDrag, false)
function startDrag(event) {
var x = event.clientX - centreX
var y = centreY - event.clientY
var delta2 = x * x + y * y
if (delta2 > radius2) {
return
}
var z = Math.sqrt(radius2 - delta2)
start.set(x, y, z)
window.addEventListener("mousemove", drag, false)
window.addEventListener("mouseup", stopDrag, false)
function drag(event) {
var delta
x = event.clientX - centreX
y = centreY - event.clientY
delta2 = x * x + y * y
if (delta2 > radius2) {
delta = Math.sqrt(delta2)
x = x / delta * radius
y = y / delta * radius
z = 0
} else {
z = Math.sqrt(radius2 - delta2)
}
end.set(x, y, z)
angle = start.angleTo(end)
start.cross(end).normalize()
rotationMatrix.makeRotationAxis(start, -angle)
camera.matrix.multiply(rotationMatrix)
camera.matrixWorldNeedsUpdate = true
start.copy(end)
}
function stopDrag(event) {
window.removeEventListener("mousemove", drag, false)
window.removeEventListener("mouseup", stopDrag, false)
}
}
}
window.onload = init
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment