how to make Panoramic view 360 with javascript,webgl - javascript

i want to make panoramic view like in this url : https://s3-eu-west-1.amazonaws.com/canonliveevents/360/ny_expo_2015/index.html
i was able to do this http://threejs.org/examples/#css3d_panorama but i need to add some button on the image for information about the image.
anyhelp will be appreciate, thanks anyway
mycode :
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body{
margin: 0;
}
canvas{
position: absolute;
width: 100%;
height: 100%
}
</style>
<script src="//cdnjs.cloudflare.com/ajax/libs/three.js/r69/three.min.js"></script>
</head>
<body>
<div id="test" style="position: absolute; left: 0px; top: 0px; width: 884px; height: 657px; overflow: hidden; -moz-user-select: none; cursor: default;">
<div id="img" stlye="position:absolute;left:0px;top:0px;">
</div>
<div id="button" style="position:absolute;left:0px;right:0px;width:100%;height:100%;overflow:hidden;">
<div style="position: absolute; z-index: 2001; overflow: visible; cursor: pointer; pointer-events: auto; opacity: 1; transform-origin: 50% 50% 0px; background-image: url("https://s3-eu-west-1.amazonaws.com/canonliveevents/360/ny_expo_2015/skin/images/info.png"); width: 100px; height: 100px; background-position: 0px 0px; background-size: 100px 200px; transform: translateZ(0px) translate(373.486px, 358.85px) translate(-50px, -50px) rotate(0deg) translate(0px, 0px) scale(0.5, 0.5) translate(0px, 0px);">
</div>
</div>
</div>
<script>
var manualControl = false;
var longitude = 0;
var latitude = 0;
var savedX;
var savedY;
var savedLongitude;
var savedLatitude;
// panoramas background
var panoramasArray = ["01.jpg","02.jpg","03.jpg","04.jpg","05.jpg","06.jpg"];
var panoramaNumber = Math.floor(Math.random()*panoramasArray.length);
// setting up the renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
var obj = document.getElementById('test');
obj.appendChild(renderer.domElement);
// creating a new scene
var scene = new THREE.Scene();
// adding a camera
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000);
camera.target = new THREE.Vector3(0, 0, 0);
// creation of a big sphere geometry
var sphere = new THREE.SphereGeometry(100, 100, 40);
sphere.applyMatrix(new THREE.Matrix4().makeScale(-1, 1, 1));
// creation of the sphere material
var sphereMaterial = new THREE.MeshBasicMaterial();
sphereMaterial.map = THREE.ImageUtils.loadTexture(panoramasArray[panoramaNumber])
// geometry + material = mesh (actual object)
var sphereMesh = new THREE.Mesh(sphere, sphereMaterial);
scene.add(sphereMesh);
// listeners
document.addEventListener("mousedown", onDocumentMouseDown, false);
document.addEventListener("mousemove", onDocumentMouseMove, false);
document.addEventListener("mouseup", onDocumentMouseUp, false);
render();
function render(){
requestAnimationFrame(render);
if(!manualControl){
longitude += 0.1;
}
// limiting latitude from -85 to 85 (cannot point to the sky or under your feet)
latitude = Math.max(-85, Math.min(85, latitude));
// moving the camera according to current latitude (vertical movement) and longitude (horizontal movement)
camera.target.x = 500 * Math.sin(THREE.Math.degToRad(90 - latitude)) * Math.cos(THREE.Math.degToRad(longitude));
camera.target.y = 500 * Math.cos(THREE.Math.degToRad(90 - latitude));
camera.target.z = 500 * Math.sin(THREE.Math.degToRad(90 - latitude)) * Math.sin(THREE.Math.degToRad(longitude));
camera.lookAt(camera.target);
// calling again render function
renderer.render(scene, camera);
}
// when the mouse is pressed, we switch to manual control and save current coordinates
function onDocumentMouseDown(event){
event.preventDefault();
manualControl = true;
savedX = event.clientX;
savedY = event.clientY;
savedLongitude = longitude;
savedLatitude = latitude;
}
// when the mouse moves, if in manual contro we adjust coordinates
function onDocumentMouseMove(event){
if(manualControl){
longitude = (savedX - event.clientX) * 0.1 + savedLongitude;
latitude = (event.clientY - savedY) * 0.1 + savedLatitude;
}
}
// when the mouse is released, we turn manual control off
function onDocumentMouseUp(event){
manualControl = false;
}
// pressing a key (actually releasing it) changes the texture map
document.onkeyup = function(event){
panoramaNumber = (panoramaNumber + 1) % panoramasArray.length
sphereMaterial.map = THREE.ImageUtils.loadTexture(panoramasArray[panoramaNumber])
}
</script>
</body>
</html>`

Related

Three.js Geometry isn't showing in browser, but the scene is

was following a tutorial and got the whole scene working in the body tag, then I tried moving it inside a div, and now only the scene will render. I'm not getting any errors, and I've console logged everything to make sure it is available to access. But I can't see why I'm nothing displayed.
// console.log ("Java Script is working!")
// get div for 3D area
const container = document.querySelector('#container')
// console.log (container)
var scene = new THREE.Scene()
var camera = new THREE.PerspectiveCamera(
75,
container.innerWidth / container.innerHeight,
0.1,
1000
)
camera.position.z = 3
var renderer = new THREE.WebGLRenderer({
antialias: true
})
renderer.setClearColor('#0D1033')
renderer.setSize(container.innerWidth, container.innerHeight)
container.appendChild(renderer.domElement)
container.addEventListener('resize', () => {
renderer.setSize(container.innerWidth, container.innerHeight)
camera.aspect = container.innerWidth / container.innerHeight
camera.updateProjectionMatrix()
})
var geometry = new THREE.BoxGeometry(10, 1, 1)
var material = new THREE.MeshLambertMaterial({
color: 0x90e9f9,
side: THREE.DoubleSide
})
var mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)
var light = new THREE.PointLight(0xffffff, 5, 500)
light.position.set(10, 0, 25)
scene.add(light)
var render = function() {
requestAnimationFrame(render)
renderer.render(scene, camera)
}
console.log(mesh)
console.log(camera)
render()
* {
box-sizing: border-box;
}
body {
padding: 0;
margin: 0;
height: 100vh;
}
canvas {
display: block;
height: 100%;
width: 100%;
}
#container {
background-color: black;
height: 100vh;
}
<!DOCTYPE html>
<body>
<div id="container">
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/102/three.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.2/TweenMax.min.js"></script>
<script src="main.js"></script>
</body>
</html>
I'm trying to get this working first so I know this can work before I move it into my main project, where I'm trying to have a 3d space inside a div on the website, but not take up the full page
You can only use innerWidth and innerHeight on the window object. Use clientWidth and clientHeight instead:
const container = document.querySelector('#container')
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(
75,
container.clientWidth / container.clientHeight,
0.1,
1000
)
camera.position.z = 3
const renderer = new THREE.WebGLRenderer({
antialias: true
})
renderer.setClearColor('#0D1033')
renderer.setSize(container.clientWidth, container.clientHeight)
container.appendChild(renderer.domElement)
container.addEventListener('resize', () => {
renderer.setSize(container.clientWidth, container.clientHeight)
camera.aspect = container.clientWidth / container.clientHeight
camera.updateProjectionMatrix()
})
const geometry = new THREE.BoxGeometry(10, 1, 1)
const material = new THREE.MeshLambertMaterial({
color: 0x90e9f9,
side: THREE.DoubleSide
})
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)
const light = new THREE.PointLight(0xffffff, 5, 500)
light.position.set(10, 0, 25)
scene.add(light)
const render = function() {
requestAnimationFrame(render)
renderer.render(scene, camera)
}
render()
* {
box-sizing: border-box;
}
body {
padding: 0;
margin: 0;
height: 100vh;
}
canvas {
display: block;
height: 100%;
width: 100%;
}
#container {
background-color: black;
height: 100vh;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.133.1/build/three.min.js"></script>
<div id="container">
</div>

Threejs, why render setSize function is being executed before the code which is before it?

Hello I have one doubt:
Today I tryed to change canvas' size dinamically. I would like to get the size of the Plane loaded and put its size into the canvas's size, to adapt canvas to whatever plane's size is.
First, debugging the program I see that the first canvas 800x600 is being created, which is correct:
Second I thougt it would be linear and go to the load function to get the model from local sotrage, however it went to the renderer.setSize()
Then the same two steps are done for the second canvas:
Then, in the fifth and sixth steps we load the model into the canvas:
Here I show you the full code, first the file being discussed, then other important files:
InitCanvas.js
// this class handles the load and the canva for a nrrd
// Using programming based on prototype: https://javascript.info/class
// This class should be improved:
// - Canvas Width and height
InitCanvas = function (IdDiv, Filename) {
this.IdDiv = IdDiv;
this.Filename = Filename
}
InitCanvas.prototype = {
constructor: InitCanvas,
init: function () {
this.container = document.getElementById(this.IdDiv);
// this should be changed.
debugger;
this.container.innerHeight = 600;
this.container.innerWidth = 800;
//These statenments should be changed to improve the image position
this.camera = new THREE.PerspectiveCamera(60, this.container.innerWidth / this.container.innerHeight, 0.01, 1e10);
this.camera.position.z = 300;
let scene = new THREE.Scene();
scene.add(this.camera);
// light
let dirLight = new THREE.DirectionalLight(0xffffff);
dirLight.position.set(200, 200, 1000).normalize();
this.camera.add(dirLight);
this.camera.add(dirLight.target);
// read file
let loader = new THREE.NRRDLoader();
loader.load(this.Filename, function (volume) {
//z plane
let sliceZ = volume.extractSlice('z', Math.floor(volume.RASDimensions[2] / 4));
debugger;
this.container.innerWidth = sliceZ.iLength;
this.container.innerHeight = sliceZ.jLength;
sliceZ.mesh.material.color.setRGB(0,1,1);
console.log('Our slice is: ', sliceZ);
scene.add(sliceZ.mesh);
}.bind(this));
this.scene = scene;
// renderer
this.renderer = new THREE.WebGLRenderer({alpha: true});
this.renderer.setPixelRatio(this.container.devicePixelRatio);
debugger;
this.renderer.setSize(this.container.innerWidth, this.container.innerHeight);
// add canvas in container
this.container.appendChild(this.renderer.domElement);
},
animate: function () {
this.renderer.render(this.scene, this.camera);
}
}
logic.js
if (!Detector.webgl) Detector.addGetWebGLMessage();
// global variables for this scripts
let OriginalImg,
SegmentImg;
var mouse = new THREE.Vector2();
var raycaster = new THREE.Raycaster();
var mousePressed = false;
var clickCount = 0;
init();
animate();
// initilize the page
function init() {
let filename = "models/nrrd/columna01.nrrd"; // change your nrrd file
let idDiv = 'original';
OriginalImg = new InitCanvas(idDiv, filename);
OriginalImg.init();
console.log(OriginalImg);
filename = "models/nrrd/columnasegmentado01.nrrd"; // change your nrrd file
idDiv = 'segment';
SegmentImg = new InitCanvas(idDiv, filename);
SegmentImg.init();
}
let originalCanvas = document.getElementById('original');
originalCanvas.addEventListener('mousedown', onDocumentMouseDown, false);
originalCanvas.addEventListener('mouseup', onDocumentMouseUp, false);
function onDocumentMouseDown(event) {
mousePressed = true;
clickCount++;
mouse.x = ( ( event.clientX - OriginalImg.renderer.domElement.offsetLeft ) / OriginalImg.renderer.domElement.clientWidth ) * 2 - 1;
mouse.y = - ( ( event.clientY - OriginalImg.renderer.domElement.offsetTop ) / OriginalImg.renderer.domElement.clientHeight ) * 2 + 1
console.log('Mouse x position is: ', mouse.x, 'the click number was: ', clickCount);
console.log('Mouse Y position is: ', mouse.y);
raycaster.setFromCamera(mouse.clone(), OriginalImg.camera);
var objects = raycaster.intersectObjects(OriginalImg.scene.children);
console.log(objects);
}
function onDocumentMouseUp(event) {
mousePressed = false
}
function animate() {
requestAnimationFrame(animate);
OriginalImg.animate();
SegmentImg.animate();
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Prototype: three.js without react.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link rel="stylesheet" href="css/styles.css">
<!-- load the libraries and js -->
<script src="js/libs/three.js"></script>
<script src="js/Volume.js"></script>
<script src="js/VolumeSlice.js"></script>
<script src="js/loaders/NRRDLoader.js"></script>
<script src="js/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="js/libs/gunzip.min.js"></script>
<script src="js/libs/dat.gui.min.js"></script>
<script src="js/InitCanvas.js"></script>
</head>
<body>
<div id="info">
<h1>Prototype: three.js without react.js</h1>
</div>
<!-- two canvas -->
<div class="row">
<div class="column" id="original">
</div>
<div class="column" id="segment">
</div>
</div>
<script src="js/logic.js"></script>
</body>
</html>
styles.css
body {
font-family: Monospace;
margin: 0px;
overflow: hidden;
}
#info {
color: rgb(137, 145, 192);
position: absolute;
top: 10px;
width: 100%;
text-align: center;
z-index: 5;
display:block;
}
.column {
float: left;
width: 50%;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
canvas {
width: 200px;
height: 200px;
margin: 100px;
padding: 0px;
position: static; /* fixed or static */
top: 100px;
left: 100px;
}
In addition other external resources being used are, NRRDLoader:
https://github.com/mrdoob/three.js/blob/dev/examples/js/loaders/NRRDLoader.js
Volume.js
https://github.com/mrdoob/three.js/blob/dev/examples/js/Volume.js
VolumeSlice.js
https://github.com/mrdoob/three.js/blob/dev/examples/js/VolumeSlice.js
Could you help me please?
This is because the load listener will fire when the loader finishes loading the file, i doesn't matter if the code is put before because you are passing a callback function as a parameter.
This might help you to understand what is going on:
Let says that you have 3 friends that you will give orders.
You tell friend No. 1 to go and fetch a ball in the distance, when it
finishes it will hand you over the ball and paint a red dot on the floor.
You tell friend No. 2 to go and start spining around it's own axis 2
times and paint a blue dot on the floor
You tell friend No. 3 to jump 2 times and paint a green dot on the floor.
Before Friend 1 comes back both friends had already finished their tasks and in the end the last dot paint will be red, but you probably were expecting it to be green, since it is the last instruction you gave.
This link will help you to better understand how the Event Loop works, and this will help you to understand closures and callbacks.

Threejs, div innerWidth and innerHeight changes by its own after setting it with plane's width and height?

Hello I have one doubt.
I am trying to set the innerWidth and innerHeight of the div, the container whichs has inside the canvas, with the following code, the important code is the inner loader.load function, which get executed when we have the plane finished loading in the page.
// this class handles the load and the canva for a nrrd
// Using programming based on prototype: https://javascript.info/class
// This class should be improved:
// - Canvas Width and height
InitCanvas = function (IdDiv, Filename) {
this.IdDiv = IdDiv;
this.Filename = Filename
}
InitCanvas.prototype = {
constructor: InitCanvas,
init: function () {
this.container = document.getElementById(this.IdDiv);
// this should be changed.
debugger;
this.container.innerHeight = 600;
this.container.innerWidth = 800;
//These statenments should be changed to improve the image position
this.camera = new THREE.PerspectiveCamera(60, this.container.innerWidth / this.container.innerHeight, 0.01, 1e10);
this.camera.position.z = 300;
let scene = new THREE.Scene();
scene.add(this.camera);
// light
let dirLight = new THREE.DirectionalLight(0xffffff);
dirLight.position.set(200, 200, 1000).normalize();
this.camera.add(dirLight);
this.camera.add(dirLight.target);
// read file
let loader = new THREE.NRRDLoader();
loader.load(this.Filename, function (volume) {
//z plane
let sliceZ = volume.extractSlice('z', Math.floor(volume.RASDimensions[2] / 4));
debugger;
this.container.innerWidth = sliceZ.iLength;
this.container.innerHeight = sliceZ.jLength;
sliceZ.mesh.material.color.setRGB(0,1,1);
console.log('Our slice is: ', sliceZ);
scene.add(sliceZ.mesh);
this.scene = scene;
// renderer
this.renderer = new THREE.WebGLRenderer({alpha: true});
this.renderer.setPixelRatio(this.container.devicePixelRatio);
debugger;
this.container.appendChild(this.renderer.domElement);
}.bind(this));
},
animate: function () {
this.renderer.render(this.scene, this.camera);
}
}
As you see I am binding this in the loader.load asynchronous call, because we would like to access this.container into it, which is a property in the class InitCanvas.
Then we are getting the width and height of the plane which has just finished loading, with the sentences:
this.container.innerWidth = sliceZ.iLength;
this.container.innerHeight = sliceZ.jLength;
And I have seen using the web debugger that it does load the plane's width and height into the container, into the div:
We see that the this.container.innerWidth is being changed with 3128 and this.container.innerHeight is being changed with 1760.
However, then we see that after plane's rendering the container div is 300x150:
How is this possible?
In addition, why our web console reports us:
Uncaught TypeError: Cannot read property 'render' of undefined
at InitCanvas.animate (InitCanvas.js:79)
at animate (logic.js:63)
I think, it is because we do have access to this.renderer into loader.load function because of we have a bind(this), however in the animate() function, the InitCanvas' class scope has been lost.
How could we fix it?
Thank you for your help!
Additional code which would be relevant:
logic.js
if (!Detector.webgl) Detector.addGetWebGLMessage();
// global variables for this scripts
let OriginalImg,
SegmentImg;
var mouse = new THREE.Vector2();
var raycaster = new THREE.Raycaster();
var mousePressed = false;
var clickCount = 0;
init();
animate();
// initilize the page
function init() {
let filename = "models/nrrd/columna01.nrrd"; // change your nrrd file
let idDiv = 'original';
OriginalImg = new InitCanvas(idDiv, filename);
OriginalImg.init();
console.log(OriginalImg);
filename = "models/nrrd/columnasegmentado01.nrrd"; // change your nrrd file
idDiv = 'segment';
SegmentImg = new InitCanvas(idDiv, filename);
SegmentImg.init();
}
let originalCanvas = document.getElementById('original');
originalCanvas.addEventListener('mousedown', onDocumentMouseDown, false);
originalCanvas.addEventListener('mouseup', onDocumentMouseUp, false);
function onDocumentMouseDown(event) {
mousePressed = true;
clickCount++;
mouse.x = ( ( event.clientX - OriginalImg.renderer.domElement.offsetLeft ) / OriginalImg.renderer.domElement.clientWidth ) * 2 - 1;
mouse.y = - ( ( event.clientY - OriginalImg.renderer.domElement.offsetTop ) / OriginalImg.renderer.domElement.clientHeight ) * 2 + 1
console.log('Mouse x position is: ', mouse.x, 'the click number was: ', clickCount);
console.log('Mouse Y position is: ', mouse.y);
raycaster.setFromCamera(mouse.clone(), OriginalImg.camera);
var objects = raycaster.intersectObjects(OriginalImg.scene.children);
console.log(objects);
}
function onDocumentMouseUp(event) {
mousePressed = false
}
function animate() {
requestAnimationFrame(animate);
OriginalImg.animate();
SegmentImg.animate();
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Prototype: three.js without react.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link rel="stylesheet" href="css/styles.css">
<!-- load the libraries and js -->
<script src="js/libs/three.js"></script>
<script src="js/Volume.js"></script>
<script src="js/VolumeSlice.js"></script>
<script src="js/loaders/NRRDLoader.js"></script>
<script src="js/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="js/libs/gunzip.min.js"></script>
<script src="js/libs/dat.gui.min.js"></script>
<script src="js/InitCanvas.js"></script>
</head>
<body>
<div id="info">
<h1>Prototype: three.js without react.js</h1>
</div>
<!-- two canvas -->
<div class="row">
<div class="column" id="original">
</div>
<div class="column" id="segment">
</div>
</div>
<script src="js/logic.js"></script>
</body>
</html>
styles.css
body {
font-family: Monospace;
margin: 0px;
overflow: hidden;
}
#info {
color: rgb(137, 145, 192);
position: absolute;
top: 10px;
width: 100%;
text-align: center;
z-index: 5;
display:block;
}
.column {
float: left;
width: 50%;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
canvas {
width: 200px;
height: 200px;
margin: 100px;
padding: 0px;
position: static; /* fixed or static */
top: 100px;
left: 100px;
}
EDIT: I have done what #Mugen87 tell us and it makes the canvas have the loaded model's width and height. However I did not expect that the model was offset from top left canvas part. It is being displayer on bottom right corner, and as there is no scrollbar it hiders most of it.
How could we add a scrollbar to the page to be able to see the canvas well?
Also here I post the code which resizes the canvas as #Mugen87 suggested:
let loader = new THREE.NRRDLoader();
loader.load(this.Filename, function (volume) {
//z plane
let sliceZ = volume.extractSlice('z', Math.floor(volume.RASDimensions[2] / 4));
debugger;
this.container.innerWidth = sliceZ.iLength;
this.container.innerHeight = sliceZ.jLength;
this.renderer.setSize(this.container.innerWidth, this.container.innerHeight);
sliceZ.mesh.material.color.setRGB(0,1,1);
console.log('Our slice is: ', sliceZ);
scene.add(sliceZ.mesh);
}.bind(this));
Just resizing the container won't resize the renderer. You have to call renderer.setSize( width, height ); otherwise the size of the respective canvas stays the same.
Besides, devicePixelRatio is a window property. this.container.devicePixelRatio returns undefined.

Why doesn't my canvas animation show?

I have been working on a canvas animation of a circle that moves in a random direction, and every second the direction changes. I do that by changing a velocity vector every second by repeatedly calling a function using setInterval, while changing the position of the circle's center and drawing it in another function using requestAnimationFrame. The result is an empty canvas, and I'm not sure why. The code is split into the following three files:
random_ball.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Random Ball</title>
<link rel="stylesheet" href="random_ball.css">
</head>
<body>
<canvas id="canvas"></canvas>
<script src="random_ball.js"></script>
</body>
</html>
random_ball.css
html, body{
height: 100%;
width: 100%;
position: absolute;
top: 0;
left: 0;
overflow: hidden;
margin: 0;
padding: 0;
}
canvas{
position: absolute;
width: 50vw;
height: 50vh;
top: 25vh;
left: 25vw;
border-style: solid;
margin: 0;
padding: 0;
}
random_ball.js
const canvas = document.getElementById('canvas')
const bounds = canvas.getBoundingClientRect()
const TWO_PI = 2*Math.Pi
const R = 25
const MAX_Y = bounds.height - R
const MAX_X = bounds.width - R
const ctx = canvas.getContext('2d')
function randomInterval(min, max){
return Math.random()*(max - min) + min
}
function randomVelocity(){ // velocity is pixels/sec
VEL.X = randomInterval(-POS.X + R, MAX_X - POS.X)
VEL.Y = randomInterval(-POS.Y + R, MAX_Y - POS.Y)
console.log('VEL: ' + JSON.stringify(VEL))
}
var POS = {X: bounds.height/2, Y: bounds.width/2}
var VEL = {X: 0, Y: 0}
var LAST_TIME = window.performance.now()
function drawCircle(color){
ctx.strokeStyle = color
ctx.beginPath()
ctx.moveTo(POS.X, POS.Y)
ctx.arc(POS.X, POS.Y, R, 0, TWO_PI, true)
ctx.stroke()
}
function draw(timestamp){
var dt = (timestamp - LAST_TIME)/1000
var dx = VEL.X*dt
var dy = VEL.Y*dt
drawCircle('#FFFFFF') // erase the old drawing by making it white
POS.X += dx
POS.Y += dy
//console.log('POS: ' + JSON.stringify(POS))
drawCircle('#000000')
LAST_TIME = timestamp
requestAnimationFrame(draw)
}
randomVelocity()
drawCircle('#000000')
setInterval(randomVelocity, 1000) //change velocity every second
requestAnimationFrame(draw)
I suspect that drawing white over the old circle means the picture is changing too fast for me to see it.
You might want to familiarize yourself with JavaScript syntax rules, and possibly a code checker like JSHint.
The main problem with your code is that you're referencing a nonexistent property of the Math object. Math has no Pi property. It's spelled PI (all caps). JavaScript is case sensitive about these things.
Next: a more common practice for clearing the canvas is to use ctx.clearRect(0, 0, width, height). Here's a JSFiddle to help you see the difference: https://jsfiddle.net/Hatchet/dy2dognp/

Is there a way to grab my location on one site and open another site on my location?

I'm playing around with this html5 script that, right now, loads a globe that and you have to click on the globe to grab the location and it opens another site with a map on the location you clicked. Here is an example of the site with the globe:
http://parameter-pollution.github.io/webgl-ingress/demo/index.html
You'll see that when you click on the globe it opens the other site with the location you clicked on. Below is the html code that makes this all happen.
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Ingress WebGL</title>
<meta charset="utf-8">
<style type="text/css">
html{
height: 100%;
}
body {
margin: 0;
padding: 0;
border: 0;
overflow-y:hidden;
overflow-x:hidden;
height: 100%;
background-color: #000000;
}
#universe{
height: 100%;
width: 100%;
margin: 0;
padding: 0;
border: 0;
}
.ada_wheel{
position:absolute;
top: 50%;
left: 50%;
height: 396px;
width: 396px;
margin-top: -198px;
margin-left: -198px;
animation-duration: 10s;
animation-iteration-count: infinite;
animation-timing-function: linear;
-webkit-animation-duration: 10s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
}
#wheel_outer{
animation-name: rotateLeft;
-webkit-animation-name: rotateLeft;
}
#keyframes rotateLeft{
from { transform:rotate(360deg); }
to { transform:rotate(0deg); }
}
#-webkit-keyframes rotateLeft{
from { -webkit-transform:rotate(360deg); }
to { -webkit-transform:rotate(0deg); }
}
#wheel_inner{
animation-name: rotateRight;
-webkit-animation-name: rotateRight;
}
#keyframes rotateRight{
from { transform:rotate(0deg); }
to { transform:rotate(360deg); }
}
#-webkit-keyframes rotateRight{
from { -webkit-transform:rotate(0deg); }
to { -webkit-transform:rotate(360deg); }
}
#border_gradient{
position:absolute;
top:0px;
left:0px;
height:100%;
width:100%;
}
#click_notify{
position:absolute;
top:20%;
left:20%;
color: white;
font-size:2em;
display:none;
}
#webgl_error{
margin-top: 10%;
text-align: center;
color:white;
display:none;
}
</style>
<script type="text/javascript" src="/Detector.js"></script>
<script type="text/javascript" src="/three.js"></script>
<script type="text/javascript" src="/Tween.js"></script>
<script type="text/javascript" src="/myOrbit.js"></script>
<script type="text/javascript" src="/myHUD.js"></script>
<script type="text/javascript">
/*
#coder paremeter-pollution / https://github.com/parameter-pollution/
*/
//audio controls:
var sounds={};
var tweenStyle={};
tweenStyle.opacity=1;
var inner_wheel, outer_wheel, border_gradient, click_notify;
// standard global variables
var container, scene, camera, renderer, clock, controls, stats, projector;
// custom global variables
var middle_earth={x:0,y:0,z:0};
var orbit;
var earth;
var earth_radius=50;
var layers= new Array(10);
var layer_distance=0.005;
var hud;
var hud_distance=30;
var crosshairTrackingPoint;
var randomPointInterval;
var numberOfTextures=3;
function init()
{
if(!Detector.webgl){ //check for webgl support
document.getElementById('webgl_error').style.display="block";
return;
}
sounds.aquiring_position=document.getElementById('aquiring_position');
sounds.crosshair_locked=document.getElementById('crosshair_locked');
sounds.logon_established=document.getElementById('logon_established');
sounds.zoom_sound=document.getElementById('zoom_sound');
sounds.downloading_latest_intel_package=document.getElementById('downloading_latest_intel_package');
sounds.ambient_space=document.getElementById('ambient_space');
inner_wheel=document.getElementById('wheel_inner');
outer_wheel= document.getElementById('wheel_outer');
border_gradient= document.getElementById('border_gradient');
click_notify=document.getElementById('click_notify');
clock = new THREE.Clock();
scene = new THREE.Scene();
// set up camera
camera = new THREE.PerspectiveCamera( 45, window.innerWidth/window.innerHeight, 0.1, 2000);
camera.up.set(0,0,1);
//HUD
hud = new myHUD(camera,hud_distance);
crosshairTrackingPoint=new THREE.Vector3(25,25,25);
//crosshair
var crosshairGeometry = new THREE.PlaneGeometry( 30, 30 );
var crosshairMaterial = new THREE.MeshLambertMaterial( { map: THREE.ImageUtils.loadTexture('img/crosshair.png', null, textureLoadComplete), transparent:true } );
crosshair = new THREE.Mesh(crosshairGeometry, crosshairMaterial);
hud.addTracked(crosshair, crosshairTrackingPoint);
//var ambientLight = new THREE.AmbientLight(0x101010,0.5);
//scene.add(ambientLight);
// spotlight
var spotlight = new THREE.SpotLight(0xffffff, 1.4);
spotlight.position.set(0,0,50);
spotlight.angle=Math.PI/6;
camera.add(spotlight);
/*
var spotlight2 = new THREE.SpotLight(0xffffff, 1.5, 40);
spotlight2.position.set(0,0,30);
spotlight2.exponent=0;
camera.add(spotlight2);
*/
// add the camera to the scene
scene.add(camera);
orbit=new myOrbit( camera, middle_earth, 500, clock );
// create renderer
renderer = new THREE.WebGLRenderer( {antialias:true} );
renderer.setSize(window.innerWidth, window.innerHeight);
// render container
container = document.getElementById( 'universe' );
// attach renderer to the container div
container.appendChild( renderer.domElement );
// sphere parameters: radius, segments along width, segments along height
var earthGeometry = new THREE.SphereGeometry( earth_radius, 64, 32 );
var earthMaterial = new THREE.MeshLambertMaterial( { map: THREE.ImageUtils.loadTexture('img/borders.jpg', null, textureLoadComplete) } );
earth = new THREE.Mesh(earthGeometry, earthMaterial);
earth.rotation.set(Math.PI/2,0,0);
// layers
var layerMaterial = new THREE.MeshLambertMaterial( { map: THREE.ImageUtils.loadTexture('img/layer.png', null, textureLoadComplete), transparent:true, opacity: 0.6 } );
//this function doesn't work when you start with adding layers with lower scale. but i have NO FUCKING IDEA why ^^
//if you decide to change it around and find yourself changing it back again increase this counter: 3
var scale=1+layer_distance*layers.length;
for (var i = 0; i < layers.length; i++) {
layers[i] = new THREE.Mesh(earthGeometry, layerMaterial);
layers[i].scale.set( scale, scale, scale );
earth.add(layers[i]);
scale -= layer_distance;
}
scene.add(earth);
renderer.initWebGLObjects( scene );
projector = new THREE.Projector();
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
window.addEventListener( 'resize', onWindowResize, false );
}
function textureLoadComplete(){
numberOfTextures--;
if( numberOfTextures === 0 ){ //all textures have been loaded, let's get this party started ;-)
var delta=clock.getDelta();
if( delta < 3000 ){ //make sure people with google fiber can also appreciate the loading animation ;-)
setTimeout( function(){startAnimation()}, 3000-delta);
}else{
startAnimation();
}
}
}
function startAnimation(){
fadeOutLoading();
orbit.tween_to_orbit( { distance: 200}, 4000, TWEEN.Easing.Exponential.Out, function(){
playSound(sounds.aquiring_position);
setTimeout( function(){
playSound(sounds.logon_established);
}, 2000);
setTimeout( function(){click_notify.style.display="inline";}, 5000);
});
randomPointInterval = setInterval( generateRandomTrackingPoint , 2000);
//start render loop
animate();
}
function fadeOutLoading(){
var fadeOutTween=new TWEEN.Tween(tweenStyle).to( {opacity: 0}, 4000);
fadeOutTween.easing(TWEEN.Easing.Cubic.In);
fadeOutTween.onUpdate(function(){
inner_wheel.style.opacity=tweenStyle.opacity;
outer_wheel.style.opacity=tweenStyle.opacity;
});
fadeOutTween.onComplete(function(){
inner_wheel.style.display="none";
outer_wheel.style.display="none";
});
fadeOutTween.start();
}
function animate()
{
requestAnimationFrame( animate );
render();
}
function render()
{
TWEEN.update();
orbit.update();
hud.update();
renderer.clear();
renderer.render( scene, orbit.camera );
}
function onDocumentMouseDown( event ) {
event.preventDefault();
var vector = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
projector.unprojectVector( vector, camera );
var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
var intersects = raycaster.intersectObject( earth );
if ( intersects.length > 0 ) { //bazinga, we found an intersection point
orbit.fixAzimuth();
orbit.autoRotate=false;
window.clearInterval(randomPointInterval);
randomPointInterval=null;
hud.updateTrackingPoint( new THREE.Vector3(intersects[0].point.x, intersects[0].point.y, intersects[0].point.z) );
var spherical=orbit.convertCartesionToSpherical( intersects[0].point );
console.log("--lat------------long------");
console.log(spherical.inclination,spherical.azimuth);
var latitude=((spherical.inclination*180/Math.PI)-90)*(-1);
var longitude=spherical.azimuth*180/Math.PI;
if( longitude > 180 ){ longitude-=360 }
console.log(latitude,longitude);
// http://www.ingress.com/intel?ll=LA.ITUDE,LO.NGITUDE&z=9
//http://www.ingress.com/intel?ll=48.729699,15.205459&z=20
playSound(sounds.zoom_sound);
playSound(sounds.downloading_latest_intel_package);
click_notify.style.display="none"
border_gradient.style.display="none";
orbit.tween_to_orbit(spherical, 3000, TWEEN.Easing.Cubic.InOut, function(){
window.location.href="http://www.ingress.com/intel?ll="+latitude+","+longitude+"&z=6";
/*orbit.reset();
hud.updateTrackingPoint(new THREE.Vector3(0,0,0));
if( randomPointInterval === null ) { randomPointInterval = setInterval( generateRandomTrackingPoint , 2000); };
//TODO: this timeout should not be necessary
setTimeout( function(){
border_gradient.style.display="inline";
orbit.tween_to_orbit( { distance: 200}, 3000, TWEEN.Easing.Exponential.Out, function(){
playSound(sounds.aquiring_position);
setTimeout( function(){
playSound(sounds.logon_established);
}, 2000);
});
}, 50);*/
});
}
}
function onWindowResize( event ) {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function generateRandomTrackingPoint(){
var min_azimuth=orbit.spherical.azimuth-0.5;
var max_azimuth=min_azimuth+Math.PI/2;
var spherical={};
spherical.azimuth = getRandomNumber(min_azimuth,max_azimuth);
spherical.inclination = getRandomNumber( 0.4, Math.PI-0.4 );
spherical.distance = earth_radius;
playSound(crosshair_locked);
var point=orbit.convertSphericalToCartesian(spherical);
hud.updateTrackingPoint(new THREE.Vector3(point.x, point.y, point.z));
}
function getRandomNumber(min, max) {
return Math.random() * (max - min) + min;
}
function playSound(sound){
var newAudio=new Audio(sound.src);
newAudio.play();
}
//chrome audio loop stops working randomly. this ugly hack fixes it
function ambient_loop_hack(){
setTimeout(function(){
playSound(sounds.ambient_space);
ambient_loop_hack();
}, 5601 );
}
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function showPosition(position) {
x.innerHTML = "Latitude: " + position.coords.latitude +
"<br>Longitude: " + position.coords.longitude;
}
</script>
<img class="ada_wheel" id="wheel_outer" src="img/ada_wheel_outer.png">
<img class="ada_wheel" id="wheel_inner" src="img/ada_wheel_inner.png">
<img id="border_gradient" src="img/border_gradient.png">
<div id="click_notify">click somewhere on the planet!</div>
<div id="webgl_error">Sorry, your graphics card and/or webbrowser don't support WebGL!</div>
<div id="universe"></div>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-42384097-1', 'github.com');
ga('send', 'pageview');
</script>
<body onload="getLocation()">
I've tried using this example to grab the current location:
http://www.w3schools.com/html/html5_geolocation.asp
and loading the function on load with this example:
http://html5hive.org/javascript-beginners-tutorial/
Is there any way to make this work where it loads the globe, grabs the location and then opens the other site with the map on the current location it grabbed from the globe? All without having to click on the globe.
This is the script I run to get the current users location coordiantes:
<body onload="getLocation()">
<p id="demo"></p>
<script>
var x = document.getElementById("demo");
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function showPosition(position) {
x.innerHTML = "Latitude: " + position.coords.latitude +
"<br>Longitude: " + position.coords.longitude;
}
</script>
Here's code that gets the users location and then redirects to the Ingress site with the right parameters:
<button onclick="getLoc()">GET LOCATION</button>
<p id="demo"></p>
<script>
var x = document.getElementById("demo");
function getLoc() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(redirectMe);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function redirectMe(position) {
document.location.href="https://www.ingress.com/intel?ll="+position.coords.latitude+","+position.coords.longitude+"&z=6";
}
</script>
This: position.coords.longitude and this position.coords.latitude are variables created by the navigator.geolocation function. You're then calling them up in the second function. document.location.href redirects to a URL you specify.
Fiddle: http://jsfiddle.net/ve0bwg24/4/

Categories

Resources