|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<title> equirectangular panorama to perspective </title> |
|
<meta charset="utf-8"> |
|
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> |
|
<style> |
|
body { |
|
background-color: #0000ff; |
|
margin: 0px; |
|
overflow: hidden; |
|
} |
|
|
|
#info { |
|
position: absolute; |
|
top: 20px; width: 100%; |
|
color: #ffffff; |
|
padding: 5px; |
|
font-family:Monospace; |
|
font-size:13px; |
|
font-weight: bold; |
|
text-align:center; |
|
} |
|
|
|
a { |
|
color: #ffffff; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<div><input id="userImage" type="file" /></div> |
|
|
|
<div id="container"></div> |
|
<div id="info"><a href="#nothing" id="download">click me to download a picture, set fov, w and h query params in the url</a></div> |
|
<script |
|
src="https://code.jquery.com/jquery-3.2.1.slim.min.js" |
|
integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g=" |
|
crossorigin="anonymous"></script> |
|
|
|
<script src="//cdnjs.cloudflare.com/ajax/libs/three.js/r58/three.min.js"></script> |
|
|
|
<script> |
|
$("#userImage").change(function () { |
|
var camera, scene, renderer; |
|
var strDownloadMime = "image/octet-stream"; |
|
|
|
var fov = 70, |
|
texture_placeholder, |
|
isUserInteracting = false, |
|
onMouseDownMouseX = 0, onMouseDownMouseY = 0, |
|
lon = 0, onMouseDownLon = 0, |
|
lat = 0, onMouseDownLat = 0, |
|
phi = 0, theta = 0; |
|
|
|
var image = document.createElement( 'img' ); |
|
var texture = new THREE.Texture( image ); |
|
image.onload = function() { |
|
texture.needsUpdate = true; |
|
}; |
|
|
|
userImage = $("#userImage")[0]; |
|
if (userImage.files && userImage.files[0]) { |
|
var reader = new FileReader(); |
|
|
|
reader.onload = function (e) { |
|
image.src = e.target.result; |
|
}; |
|
|
|
reader.readAsDataURL(userImage.files[0]); |
|
} |
|
|
|
function getParameterByName(name, url) { |
|
if (!url) url = window.location.href; |
|
name = name.replace(/[\[\]]/g, "\\$&"); |
|
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), |
|
results = regex.exec(url); |
|
if (!results) return null; |
|
if (!results[2]) return ''; |
|
return decodeURIComponent(results[2].replace(/\+/g, " ")); |
|
} |
|
|
|
var camera, scene, renderer; |
|
|
|
var fov = 70, |
|
texture_placeholder, |
|
isUserInteracting = false, |
|
onMouseDownMouseX = 0, onMouseDownMouseY = 0, |
|
lon = 0, onMouseDownLon = 0, |
|
lat = 0, onMouseDownLat = 0, |
|
phi = 0, theta = 0; |
|
|
|
var queryFov = getParameterByName("fov", window.location.href) |
|
if(queryFov != null && queryFov != '') { |
|
fov = parseInt(queryFov); |
|
} |
|
|
|
var w = window.innerWidth; |
|
var h = window.innerHeight; |
|
queryW = getParameterByName("fov", window.location.href) |
|
if(queryW != null && queryW != '') { |
|
w = parseInt(queryW) |
|
} |
|
|
|
queryH = getParameterByName("fov", window.location.href) |
|
if(queryH != null && queryH != '') { |
|
h = parseInt(queryH) |
|
} |
|
|
|
function init() { |
|
|
|
var container, mesh; |
|
|
|
container = document.getElementById( 'container' ); |
|
|
|
camera = new THREE.PerspectiveCamera( fov, w / h, 1, 1100 ); |
|
camera.target = new THREE.Vector3( 0, 0, 0 ); |
|
|
|
scene = new THREE.Scene(); |
|
console.log(image, texture); |
|
|
|
mesh = new THREE.Mesh( new THREE.SphereGeometry( 500, 60, 40 ), new THREE.MeshBasicMaterial( { map: texture } ) ); |
|
mesh.scale.x = -1; |
|
scene.add( mesh ); |
|
|
|
renderer = new THREE.WebGLRenderer({ |
|
preserveDrawingBuffer: true |
|
}); |
|
renderer.setSize( window.innerWidth, window.innerHeight ); |
|
|
|
document.addEventListener( 'mousedown', onDocumentMouseDown, false ); |
|
document.addEventListener( 'mousemove', onDocumentMouseMove, false ); |
|
document.addEventListener( 'mouseup', onDocumentMouseUp, false ); |
|
document.addEventListener( 'mousewheel', onDocumentMouseWheel, false ); |
|
document.addEventListener( 'DOMMouseScroll', onDocumentMouseWheel, false); |
|
|
|
$('#container').append(renderer.domElement); |
|
|
|
var butt = document.querySelector("#download"); |
|
butt.addEventListener('click', function (ev) { |
|
saveAsImage(); |
|
}) |
|
window.addEventListener( 'resize', onWindowResize, false ); |
|
|
|
} |
|
var imgData; |
|
|
|
function saveAsImage() { |
|
var imgData, imgNode; |
|
|
|
try { |
|
camera.aspect = w / h; |
|
camera.updateProjectionMatrix(); |
|
|
|
renderer.setSize( w, h ); |
|
render(); |
|
|
|
var strMime = "image/jpeg"; |
|
imgData = renderer.domElement.toDataURL(strMime); |
|
|
|
saveFile(imgData.replace(strMime, strDownloadMime), "test.jpg"); |
|
camera.aspect = window.innerWidth / window.innerHeight; |
|
camera.updateProjectionMatrix(); |
|
|
|
renderer.setSize( window.innerWidth, window.innerHeight ); |
|
|
|
} catch (e) { |
|
console.log(e); |
|
return; |
|
} |
|
|
|
} |
|
|
|
var saveFile = function (strData, filename) { |
|
var link = document.createElement('a'); |
|
if (typeof link.download === 'string') { |
|
document.body.appendChild(link); //Firefox requires the link to be in the body |
|
link.download = filename; |
|
link.href = strData; |
|
link.click(); |
|
document.body.removeChild(link); //remove the link when done |
|
} else { |
|
location.replace(uri); |
|
} |
|
} |
|
|
|
function onWindowResize() { |
|
|
|
camera.aspect = window.innerWidth / window.innerHeight; |
|
camera.updateProjectionMatrix(); |
|
|
|
renderer.setSize( window.innerWidth, window.innerHeight ); |
|
|
|
} |
|
|
|
function onDocumentMouseDown( event ) { |
|
|
|
event.preventDefault(); |
|
|
|
isUserInteracting = true; |
|
|
|
onPointerDownPointerX = event.clientX; |
|
onPointerDownPointerY = event.clientY; |
|
|
|
onPointerDownLon = lon; |
|
onPointerDownLat = lat; |
|
|
|
} |
|
|
|
function onDocumentMouseMove( event ) { |
|
|
|
if ( isUserInteracting ) { |
|
|
|
lon = ( onPointerDownPointerX - event.clientX ) * 0.1 + onPointerDownLon; |
|
lat = ( event.clientY - onPointerDownPointerY ) * 0.1 + onPointerDownLat; |
|
|
|
} |
|
} |
|
|
|
function onDocumentMouseUp( event ) { |
|
|
|
isUserInteracting = false; |
|
|
|
} |
|
|
|
function onDocumentMouseWheel( event ) { |
|
|
|
// WebKit |
|
|
|
if ( event.wheelDeltaY ) { |
|
|
|
fov -= event.wheelDeltaY * 0.05; |
|
|
|
// Opera / Explorer 9 |
|
|
|
} else if ( event.wheelDelta ) { |
|
|
|
fov -= event.wheelDelta * 0.05; |
|
|
|
// Firefox |
|
|
|
} else if ( event.detail ) { |
|
|
|
fov += event.detail * 1.0; |
|
|
|
} |
|
|
|
camera.projectionMatrix.makePerspective( fov, window.innerWidth / window.innerHeight, 1, 1100 ); |
|
render(); |
|
|
|
} |
|
|
|
function animate() { |
|
|
|
requestAnimationFrame( animate ); |
|
render(); |
|
|
|
} |
|
|
|
function render() { |
|
|
|
lat = Math.max( - 85, Math.min( 85, lat ) ); |
|
phi = THREE.Math.degToRad( 90 - lat ); |
|
theta = THREE.Math.degToRad( lon ); |
|
|
|
camera.target.x = 500 * Math.sin( phi ) * Math.cos( theta ); |
|
camera.target.y = 500 * Math.cos( phi ); |
|
camera.target.z = 500 * Math.sin( phi ) * Math.sin( theta ); |
|
|
|
camera.lookAt( camera.target ); |
|
|
|
/* |
|
// distortion |
|
camera.position.x = - camera.target.x; |
|
camera.position.y = - camera.target.y; |
|
camera.position.z = - camera.target.z; |
|
*/ |
|
|
|
renderer.render( scene, camera ); |
|
|
|
} |
|
|
|
init(); |
|
animate(); |
|
|
|
}); </script> |
|
</body> |
|
</html> |