-
-
Save brett-miller/9e706e56f0087715457827b7c38c08b2 to your computer and use it in GitHub Desktop.
GeoJSON Test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>ThreeGeoJSON polygons</title> | |
<style media="screen"> | |
html, body { | |
margin: 0; padding: 0 | |
} | |
</style> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js" charset="utf-8"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r82/three.js" charset="utf-8"></script> | |
<script src="threeGeoJSON.js" charset="utf-8"></script> | |
<script src="TrackballControls.js" charset="utf-8"></script> | |
</head> | |
<body> | |
<script type="text/javascript"> | |
var width = window.innerWidth; | |
var height = window.innerHeight; | |
// Earth params | |
var radius = 9.99; | |
var segments = 32; | |
var rotation = 0; | |
//New scene and camera | |
var scene = new THREE.Scene(); | |
var camera = new THREE.PerspectiveCamera(55, width / height, 0.01, 1000); | |
camera.position.z = 1; | |
camera.position.x = -.2; | |
camera.position.y = .5; | |
//New Renderer | |
var renderer = new THREE.WebGLRenderer(); | |
renderer.setSize(width, height); | |
var canvas = renderer.domElement; | |
canvas.style.display = "block"; | |
document.body.appendChild(canvas); | |
//Add lighting | |
scene.add(new THREE.AmbientLight(0x333333)); | |
var light = new THREE.DirectionalLight(0xe4eef9, .7); | |
light.position.set(12, 12, 8); | |
scene.add(light); | |
//Create a sphere to make visualization easier. | |
var geometry = new THREE.SphereGeometry(10, 32, 32); | |
var material = new THREE.MeshPhongMaterial({ | |
//wireframe: true, | |
//transparent: true | |
}); | |
//Draw the GeoJSON | |
var test_json = $.getJSON("countries_states.geojson", function(data) { | |
drawThreeGeo(data, 10, 'sphere', { | |
color: 'red' | |
}) | |
}); | |
//Set the camera position | |
camera.position.z = 30; | |
//Enable controls | |
var controls = new THREE.TrackballControls(camera); | |
//Render the image | |
function render() { | |
controls.update(); | |
requestAnimationFrame(render); | |
renderer.render(scene, camera); | |
} | |
render(); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Draw GeoJSON | |
Iterates through the latitude and longitude values, converts the values to XYZ coordinates, | |
and draws the geoJSON geometries. | |
*/ | |
var x_values = []; | |
var y_values = []; | |
var z_values = []; | |
function drawThreeGeo(json, radius, shape, options) { | |
var json_geom = createGeometryArray(json); | |
//An array to hold the feature geometries. | |
var convertCoordinates = getConversionFunctionName(shape); | |
//Whether you want to convert to spherical or planar coordinates. | |
var coordinate_array = []; | |
//Re-usable array to hold coordinate values. This is necessary so that you can add | |
//interpolated coordinates. Otherwise, lines go through the sphere instead of wrapping around. | |
for (var geom_num = 0; geom_num < json_geom.length; geom_num++) { | |
if (json_geom[geom_num].type == 'Point') { | |
convertCoordinates(json_geom[geom_num].coordinates, radius); | |
drawParticle(y_values[0], z_values[0], x_values[0], options); | |
} else if (json_geom[geom_num].type == 'MultiPoint') { | |
for (var point_num = 0; point_num < json_geom[geom_num].coordinates.length; point_num++) { | |
convertCoordinates(json_geom[geom_num].coordinates[point_num], radius); | |
drawParticle(y_values[0], z_values[0], x_values[0], options); | |
} | |
} else if (json_geom[geom_num].type == 'LineString') { | |
coordinate_array = createCoordinateArray(json_geom[geom_num].coordinates); | |
for (var point_num = 0; point_num < coordinate_array.length; point_num++) { | |
convertCoordinates(coordinate_array[point_num], radius); | |
} | |
drawLine(y_values, z_values, x_values, options); | |
} else if (json_geom[geom_num].type == 'Polygon') { | |
for (var segment_num = 0; segment_num < json_geom[geom_num].coordinates.length; segment_num++) { | |
coordinate_array = createCoordinateArray(json_geom[geom_num].coordinates[ | |
segment_num]); | |
for (var point_num = 0; point_num < coordinate_array.length; point_num++) { | |
convertCoordinates(coordinate_array[point_num], radius); | |
} | |
drawLine(y_values, z_values, x_values, options); | |
} | |
} else if (json_geom[geom_num].type == 'MultiLineString') { | |
for (var segment_num = 0; segment_num < json_geom[geom_num].coordinates.length; segment_num++) { | |
coordinate_array = createCoordinateArray(json_geom[geom_num].coordinates[ | |
segment_num]); | |
for (var point_num = 0; point_num < coordinate_array.length; point_num++) { | |
convertCoordinates(coordinate_array[point_num], radius); | |
} | |
drawLine(y_values, z_values, x_values, options); | |
} | |
} else if (json_geom[geom_num].type == 'MultiPolygon') { | |
for (var polygon_num = 0; polygon_num < json_geom[geom_num].coordinates.length; polygon_num++) { | |
for (var segment_num = 0; segment_num < json_geom[geom_num].coordinates[ | |
polygon_num].length; segment_num++) { | |
coordinate_array = createCoordinateArray(json_geom[geom_num].coordinates[ | |
polygon_num][segment_num]); | |
for (var point_num = 0; point_num < coordinate_array.length; point_num++) { | |
convertCoordinates(coordinate_array[point_num], radius); | |
} | |
drawLine(y_values, z_values, x_values, options); | |
} | |
} | |
} else { | |
throw new Error('The geoJSON is not valid.'); | |
} | |
} | |
} | |
function createGeometryArray(json) { | |
var geometry_array = []; | |
if (json.type == 'Feature') { | |
geometry_array.push(json.geometry); | |
} else if (json.type == 'FeatureCollection') { | |
for (var feature_num = 0; feature_num < json.features.length; feature_num++) { | |
geometry_array.push(json.features[feature_num].geometry); | |
} | |
} else if (json.type == 'GeometryCollection') { | |
for (var geom_num = 0; geom_num < json.geometries.length; geom_num++) { | |
geometry_array.push(json.geometries[geom_num]); | |
} | |
} else { | |
throw new Error('The geoJSON is not valid.'); | |
} | |
//alert(geometry_array.length); | |
return geometry_array; | |
} | |
function getConversionFunctionName(shape) { | |
var conversionFunctionName; | |
if (shape == 'sphere') { | |
conversionFunctionName = convertToSphereCoords; | |
} else if (shape == 'plane') { | |
conversionFunctionName = convertToPlaneCoords; | |
} else { | |
throw new Error('The shape that you specified is not valid.'); | |
} | |
return conversionFunctionName; | |
} | |
function createCoordinateArray(feature) { | |
//Loop through the coordinates and figure out if the points need interpolation. | |
var temp_array = []; | |
var interpolation_array = []; | |
for (var point_num = 0; point_num < feature.length; point_num++) { | |
var point1 = feature[point_num]; | |
var point2 = feature[point_num - 1]; | |
if (point_num > 0) { | |
if (needsInterpolation(point2, point1)) { | |
interpolation_array = [point2, point1]; | |
interpolation_array = interpolatePoints(interpolation_array); | |
for (var inter_point_num = 0; inter_point_num < interpolation_array.length; inter_point_num++) { | |
temp_array.push(interpolation_array[inter_point_num]); | |
} | |
} else { | |
temp_array.push(point1); | |
} | |
} else { | |
temp_array.push(point1); | |
} | |
} | |
return temp_array; | |
} | |
function needsInterpolation(point2, point1) { | |
//If the distance between two latitude and longitude values is | |
//greater than five degrees, return true. | |
var lon1 = point1[0]; | |
var lat1 = point1[1]; | |
var lon2 = point2[0]; | |
var lat2 = point2[1]; | |
var lon_distance = Math.abs(lon1 - lon2); | |
var lat_distance = Math.abs(lat1 - lat2); | |
if (lon_distance > 5 || lat_distance > 5) { | |
return true; | |
} else { | |
return false; | |
} | |
} | |
function interpolatePoints(interpolation_array) { | |
//This function is recursive. It will continue to add midpoints to the | |
//interpolation array until needsInterpolation() returns false. | |
var temp_array = []; | |
var point1, point2; | |
for (var point_num = 0; point_num < interpolation_array.length - 1; point_num++) { | |
point1 = interpolation_array[point_num]; | |
point2 = interpolation_array[point_num + 1]; | |
if (needsInterpolation(point2, point1)) { | |
temp_array.push(point1); | |
temp_array.push(getMidpoint(point1, point2)); | |
} else { | |
temp_array.push(point1); | |
} | |
} | |
temp_array.push(interpolation_array[interpolation_array.length - 1]); | |
if (temp_array.length > interpolation_array.length) { | |
temp_array = interpolatePoints(temp_array); | |
} else { | |
return temp_array; | |
} | |
return temp_array; | |
} | |
function getMidpoint(point1, point2) { | |
var midpoint_lon = (point1[0] + point2[0]) / 2; | |
var midpoint_lat = (point1[1] + point2[1]) / 2; | |
var midpoint = [midpoint_lon, midpoint_lat]; | |
return midpoint; | |
} | |
function convertToSphereCoords(coordinates_array, sphere_radius) { | |
var lon = coordinates_array[0]; | |
var lat = coordinates_array[1]; | |
x_values.push(Math.cos(lat * Math.PI / 180) * Math.cos(lon * Math.PI / 180) * | |
sphere_radius); | |
y_values.push(Math.cos(lat * Math.PI / 180) * Math.sin(lon * Math.PI / 180) * | |
sphere_radius); | |
z_values.push(Math.sin(lat * Math.PI / 180) * sphere_radius); | |
} | |
function convertToPlaneCoords(coordinates_array, radius) { | |
var lon = coordinates_array[0]; | |
var lat = coordinates_array[1]; | |
z_values.push((lat / 180) * radius); | |
y_values.push((lon / 180) * radius); | |
} | |
function drawParticle(x, y, z, options) { | |
var particle_geom = new THREE.Geometry(); | |
particle_geom.vertices.push(new THREE.Vector3(x, y, z)); | |
var particle_material = new THREE.ParticleSystemMaterial(options); | |
var particle = new THREE.ParticleSystem(particle_geom, particle_material); | |
scene.add(particle); | |
clearArrays(); | |
} | |
function drawLine(x_values, y_values, z_values, options) { | |
// container | |
var obj = new THREE.Object3D(); | |
// lines | |
var line_geom = new THREE.Geometry(); | |
createVertexForEachPoint(line_geom, x_values, y_values, z_values); | |
var line_material = new THREE.LineBasicMaterial({ | |
color: 'yellow' | |
}); | |
var line = new THREE.Line(line_geom, line_material); | |
obj.add(line); | |
// mesh | |
var mesh_geom = new THREE.Geometry(); | |
createVertexForEachPoint(mesh_geom, x_values, y_values, z_values); | |
var mesh_material = new THREE.MeshBasicMaterial({ | |
color: 'blue', | |
side: THREE.DoubleSide | |
}); | |
var mesh = new THREE.Mesh(mesh_geom, mesh_material); | |
obj.add(mesh); | |
scene.add(obj); | |
clearArrays(); | |
} | |
function createVertexForEachPoint(object_geometry, values_axis1, values_axis2, | |
values_axis3) { | |
for (var i = 0; i < values_axis1.length; i++) { | |
object_geometry.vertices.push(new THREE.Vector3(values_axis1[i], | |
values_axis2[i], values_axis3[i])); | |
object_geometry.faces.push(new THREE.Face3(0, i + 1, i)); // <- add faces | |
} | |
} | |
function clearArrays() { | |
x_values.length = 0; | |
y_values.length = 0; | |
z_values.length = 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author Eberhard Graether / http://egraether.com/ | |
*/ | |
THREE.TrackballControls = function ( object, domElement ) { | |
var _this = this; | |
var STATE = { NONE: -1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM: 4, TOUCH_PAN: 5 }; | |
this.object = object; | |
this.domElement = ( domElement !== undefined ) ? domElement : document; | |
// API | |
this.enabled = true; | |
this.screen = { width: 0, height: 0, offsetLeft: 0, offsetTop: 0 }; | |
this.radius = ( this.screen.width + this.screen.height ) / 4; | |
this.rotateSpeed = 1.0; | |
this.zoomSpeed = 1.2; | |
this.panSpeed = 0.3; | |
this.noRotate = false; | |
this.noZoom = false; | |
this.noPan = false; | |
this.staticMoving = false; | |
this.dynamicDampingFactor = 0.2; | |
this.minDistance = 0; | |
this.maxDistance = Infinity; | |
this.keys = [ 65 /*A*/, 83 /*S*/, 68 /*D*/ ]; | |
// internals | |
this.target = new THREE.Vector3(); | |
var lastPosition = new THREE.Vector3(); | |
var _state = STATE.NONE, | |
_prevState = STATE.NONE, | |
_eye = new THREE.Vector3(), | |
_rotateStart = new THREE.Vector3(), | |
_rotateEnd = new THREE.Vector3(), | |
_zoomStart = new THREE.Vector2(), | |
_zoomEnd = new THREE.Vector2(), | |
_touchZoomDistanceStart = 0, | |
_touchZoomDistanceEnd = 0, | |
_panStart = new THREE.Vector2(), | |
_panEnd = new THREE.Vector2(); | |
// for reset | |
this.target0 = this.target.clone(); | |
this.position0 = this.object.position.clone(); | |
this.up0 = this.object.up.clone(); | |
// events | |
var changeEvent = { type: 'change' }; | |
// methods | |
this.handleResize = function () { | |
this.screen.width = window.innerWidth; | |
this.screen.height = window.innerHeight; | |
this.screen.offsetLeft = 0; | |
this.screen.offsetTop = 0; | |
this.radius = ( this.screen.width + this.screen.height ) / 4; | |
}; | |
this.handleEvent = function ( event ) { | |
if ( typeof this[ event.type ] == 'function' ) { | |
this[ event.type ]( event ); | |
} | |
}; | |
this.getMouseOnScreen = function ( clientX, clientY ) { | |
return new THREE.Vector2( | |
( clientX - _this.screen.offsetLeft ) / _this.radius * 0.5, | |
( clientY - _this.screen.offsetTop ) / _this.radius * 0.5 | |
); | |
}; | |
this.getMouseProjectionOnBall = function ( clientX, clientY ) { | |
var mouseOnBall = new THREE.Vector3( | |
( clientX - _this.screen.width * 0.5 - _this.screen.offsetLeft ) / _this.radius, | |
( _this.screen.height * 0.5 + _this.screen.offsetTop - clientY ) / _this.radius, | |
0.0 | |
); | |
var length = mouseOnBall.length(); | |
if ( length > 1.0 ) { | |
mouseOnBall.normalize(); | |
} else { | |
mouseOnBall.z = Math.sqrt( 1.0 - length * length ); | |
} | |
_eye.copy( _this.object.position ).sub( _this.target ); | |
var projection = _this.object.up.clone().setLength( mouseOnBall.y ); | |
projection.add( _this.object.up.clone().cross( _eye ).setLength( mouseOnBall.x ) ); | |
projection.add( _eye.setLength( mouseOnBall.z ) ); | |
return projection; | |
}; | |
this.rotateCamera = function () { | |
var angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() / _rotateEnd.length() ); | |
if ( angle ) { | |
var axis = ( new THREE.Vector3() ).crossVectors( _rotateStart, _rotateEnd ).normalize(); | |
quaternion = new THREE.Quaternion(); | |
angle *= _this.rotateSpeed; | |
quaternion.setFromAxisAngle( axis, -angle ); | |
_eye.applyQuaternion( quaternion ); | |
_this.object.up.applyQuaternion( quaternion ); | |
_rotateEnd.applyQuaternion( quaternion ); | |
if ( _this.staticMoving ) { | |
_rotateStart.copy( _rotateEnd ); | |
} else { | |
quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) ); | |
_rotateStart.applyQuaternion( quaternion ); | |
} | |
} | |
}; | |
this.zoomCamera = function () { | |
if ( _state === STATE.TOUCH_ZOOM ) { | |
var factor = _touchZoomDistanceStart / _touchZoomDistanceEnd; | |
_touchZoomDistanceStart = _touchZoomDistanceEnd; | |
_eye.multiplyScalar( factor ); | |
} else { | |
var factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * _this.zoomSpeed; | |
if ( factor !== 1.0 && factor > 0.0 ) { | |
_eye.multiplyScalar( factor ); | |
if ( _this.staticMoving ) { | |
_zoomStart.copy( _zoomEnd ); | |
} else { | |
_zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor; | |
} | |
} | |
} | |
}; | |
this.panCamera = function () { | |
var mouseChange = _panEnd.clone().sub( _panStart ); | |
if ( mouseChange.lengthSq() ) { | |
mouseChange.multiplyScalar( _eye.length() * _this.panSpeed ); | |
var pan = _eye.clone().cross( _this.object.up ).setLength( mouseChange.x ); | |
pan.add( _this.object.up.clone().setLength( mouseChange.y ) ); | |
_this.object.position.add( pan ); | |
_this.target.add( pan ); | |
if ( _this.staticMoving ) { | |
_panStart = _panEnd; | |
} else { | |
_panStart.add( mouseChange.subVectors( _panEnd, _panStart ).multiplyScalar( _this.dynamicDampingFactor ) ); | |
} | |
} | |
}; | |
this.checkDistances = function () { | |
if ( !_this.noZoom || !_this.noPan ) { | |
if ( _this.object.position.lengthSq() > _this.maxDistance * _this.maxDistance ) { | |
_this.object.position.setLength( _this.maxDistance ); | |
} | |
if ( _eye.lengthSq() < _this.minDistance * _this.minDistance ) { | |
_this.object.position.addVectors( _this.target, _eye.setLength( _this.minDistance ) ); | |
} | |
} | |
}; | |
this.update = function () { | |
_eye.subVectors( _this.object.position, _this.target ); | |
if ( !_this.noRotate ) { | |
_this.rotateCamera(); | |
} | |
if ( !_this.noZoom ) { | |
_this.zoomCamera(); | |
} | |
if ( !_this.noPan ) { | |
_this.panCamera(); | |
} | |
_this.object.position.addVectors( _this.target, _eye ); | |
_this.checkDistances(); | |
_this.object.lookAt( _this.target ); | |
if ( lastPosition.distanceToSquared( _this.object.position ) > 0 ) { | |
_this.dispatchEvent( changeEvent ); | |
lastPosition.copy( _this.object.position ); | |
} | |
}; | |
this.reset = function () { | |
_state = STATE.NONE; | |
_prevState = STATE.NONE; | |
_this.target.copy( _this.target0 ); | |
_this.object.position.copy( _this.position0 ); | |
_this.object.up.copy( _this.up0 ); | |
_eye.subVectors( _this.object.position, _this.target ); | |
_this.object.lookAt( _this.target ); | |
_this.dispatchEvent( changeEvent ); | |
lastPosition.copy( _this.object.position ); | |
}; | |
// listeners | |
function keydown( event ) { | |
if ( _this.enabled === false ) return; | |
window.removeEventListener( 'keydown', keydown ); | |
_prevState = _state; | |
if ( _state !== STATE.NONE ) { | |
return; | |
} else if ( event.keyCode === _this.keys[ STATE.ROTATE ] && !_this.noRotate ) { | |
_state = STATE.ROTATE; | |
} else if ( event.keyCode === _this.keys[ STATE.ZOOM ] && !_this.noZoom ) { | |
_state = STATE.ZOOM; | |
} else if ( event.keyCode === _this.keys[ STATE.PAN ] && !_this.noPan ) { | |
_state = STATE.PAN; | |
} | |
} | |
function keyup( event ) { | |
if ( _this.enabled === false ) return; | |
_state = _prevState; | |
window.addEventListener( 'keydown', keydown, false ); | |
} | |
function mousedown( event ) { | |
if ( _this.enabled === false ) return; | |
event.preventDefault(); | |
event.stopPropagation(); | |
if ( _state === STATE.NONE ) { | |
_state = event.button; | |
} | |
if ( _state === STATE.ROTATE && !_this.noRotate ) { | |
_rotateStart = _rotateEnd = _this.getMouseProjectionOnBall( event.clientX, event.clientY ); | |
} else if ( _state === STATE.ZOOM && !_this.noZoom ) { | |
_zoomStart = _zoomEnd = _this.getMouseOnScreen( event.clientX, event.clientY ); | |
} else if ( _state === STATE.PAN && !_this.noPan ) { | |
_panStart = _panEnd = _this.getMouseOnScreen( event.clientX, event.clientY ); | |
} | |
document.addEventListener( 'mousemove', mousemove, false ); | |
document.addEventListener( 'mouseup', mouseup, false ); | |
} | |
function mousemove( event ) { | |
if ( _this.enabled === false ) return; | |
event.preventDefault(); | |
event.stopPropagation(); | |
if ( _state === STATE.ROTATE && !_this.noRotate ) { | |
_rotateEnd = _this.getMouseProjectionOnBall( event.clientX, event.clientY ); | |
} else if ( _state === STATE.ZOOM && !_this.noZoom ) { | |
_zoomEnd = _this.getMouseOnScreen( event.clientX, event.clientY ); | |
} else if ( _state === STATE.PAN && !_this.noPan ) { | |
_panEnd = _this.getMouseOnScreen( event.clientX, event.clientY ); | |
} | |
} | |
function mouseup( event ) { | |
if ( _this.enabled === false ) return; | |
event.preventDefault(); | |
event.stopPropagation(); | |
_state = STATE.NONE; | |
document.removeEventListener( 'mousemove', mousemove ); | |
document.removeEventListener( 'mouseup', mouseup ); | |
} | |
function mousewheel( event ) { | |
if ( _this.enabled === false ) return; | |
event.preventDefault(); | |
event.stopPropagation(); | |
var delta = 0; | |
if ( event.wheelDelta ) { // WebKit / Opera / Explorer 9 | |
delta = event.wheelDelta / 40; | |
} else if ( event.detail ) { // Firefox | |
delta = - event.detail / 3; | |
} | |
_zoomStart.y += delta * 0.01; | |
} | |
function touchstart( event ) { | |
if ( _this.enabled === false ) return; | |
switch ( event.touches.length ) { | |
case 1: | |
_state = STATE.TOUCH_ROTATE; | |
_rotateStart = _rotateEnd = _this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); | |
break; | |
case 2: | |
_state = STATE.TOUCH_ZOOM; | |
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; | |
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; | |
_touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy ); | |
break; | |
case 3: | |
_state = STATE.TOUCH_PAN; | |
_panStart = _panEnd = _this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); | |
break; | |
default: | |
_state = STATE.NONE; | |
} | |
} | |
function touchmove( event ) { | |
if ( _this.enabled === false ) return; | |
event.preventDefault(); | |
event.stopPropagation(); | |
switch ( event.touches.length ) { | |
case 1: | |
_rotateEnd = _this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); | |
break; | |
case 2: | |
var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX; | |
var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY; | |
_touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy ) | |
break; | |
case 3: | |
_panEnd = _this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); | |
break; | |
default: | |
_state = STATE.NONE; | |
} | |
} | |
function touchend( event ) { | |
if ( _this.enabled === false ) return; | |
switch ( event.touches.length ) { | |
case 1: | |
_rotateStart = _rotateEnd = _this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); | |
break; | |
case 2: | |
_touchZoomDistanceStart = _touchZoomDistanceEnd = 0; | |
break; | |
case 3: | |
_panStart = _panEnd = _this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ); | |
break; | |
} | |
_state = STATE.NONE; | |
} | |
this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false ); | |
this.domElement.addEventListener( 'mousedown', mousedown, false ); | |
this.domElement.addEventListener( 'mousewheel', mousewheel, false ); | |
this.domElement.addEventListener( 'DOMMouseScroll', mousewheel, false ); // firefox | |
this.domElement.addEventListener( 'touchstart', touchstart, false ); | |
this.domElement.addEventListener( 'touchend', touchend, false ); | |
this.domElement.addEventListener( 'touchmove', touchmove, false ); | |
window.addEventListener( 'keydown', keydown, false ); | |
window.addEventListener( 'keyup', keyup, false ); | |
this.handleResize(); | |
}; | |
THREE.TrackballControls.prototype = Object.create( THREE.EventDispatcher.prototype ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment