Redraw three js element - javascript

I looked at this example with three js to draw particles with images and works perfectly but i want to change the image with a switch when click a button (calls this function):
const changeImg = function(num) {
switch (num)
{
case 0:
imgData ="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA....";
break;
case 1:
imgData = "data:image/png;base64,iVBORw0KGgoAAAAN..."
break;
}
img.src = imgData;
}
And works but when you click multiple times website becomes slow.
How can I update just the image without slowing down the website?
EDIT 1
I change the code like this:
var renderer, scene, camera, ww, wh, particles, mw, mh, mz, numState;
numState = 0;
mz = 6; // Matrerial size
ww = document.getElementById('map-container').offsetWidth,
wh = 450;
mw = ww * 2;
mh = wh * 2;
var centerVector = new THREE.Vector3(0, 0, 0);
var previousTime = 0
speed = 10
isMouseDown = false;
// Render
renderer = new THREE.WebGLRenderer({
canvas: document.getElementById("map"),
antialias: true
});
renderer.setSize(mw, mh);
renderer.setClearColor(0x12347C);
// Scence
scene = new THREE.Scene();
// Camera
camera = new THREE.OrthographicCamera( ww / - 2, ww / 2, wh / 2, wh / - 2, 1, 1000 );
camera.position.set(7, 0, 4);
camera.lookAt(centerVector);
scene.add(camera);
camera.zoom = 4;
camera.updateProjectionMatrix();
// Geometry
var geometry = new THREE.Geometry();
var material = new THREE.PointsMaterial({
size: mz,
color: 0xFFFFFF,
sizeAttenuation: false
});
// Particle
particles = new THREE.Points();
var getImageData = function(image) {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0);
return ctx.getImageData(0, 0, image.width, image.height);
}
var drawTheMap = function() {
geometry.dispose();
particles.material.dispose();
particles.geometry.dispose();
for (var y = 0, y2 = imagedata.height; y < y2; y += 2) {
for (var x = 0, x2 = imagedata.width; x < x2; x += 2) {
if (imagedata.data[(x * 4 + y * 4 * imagedata.width)] < 128) {
var vertex = new THREE.Vector3();
vertex.x = x - imagedata.width / 2;
vertex.y = -y + imagedata.height / 2;
vertex.z = -Math.random()*500;
vertex.speed = Math.random() / speed + 0.015;
geometry.vertices.push(vertex);
}
}
}
particles.material = material;
particles.geometry = geometry;
scene.add(particles);
requestAnimationFrame(render);
};
var init = function() {
imagedata = getImageData(image);
drawTheMap();
onResize();
window.addEventListener('mousemove', onMousemove, false);
window.addEventListener('mousedown', onMousedown, false);
window.addEventListener('mouseup', onMouseup, false);
window.addEventListener('resize', onResize, false);
};
var onResize = function(){
var mov1, mov2;
ww = document.getElementById('map-container').offsetWidth;
wh = 450;
if (window.innerWidth > 850) {
mw = ww * 2;
mh = wh * 2;
mz = 6;
mov1 = 2.2;
mov2 = 1.9;
particles.material.size = mz;
} else {
mw = ww;
mh = wh;
mz = 3;
mov1 = 2;
mov2 = 2;
particles.material.size = mz;
}
renderer.setSize(mw, mh);
camera.left = ww / - mov1;
camera.right = ww / 2;
camera.top = wh / mov2;
camera.bottom = wh / - 2;
camera.updateProjectionMatrix();
};
var onMouseup = function(){
isMouseDown = false;
}
var onMousedown = function(e){
isMouseDown = true;
lastMousePos = {x:e.clientX, y:e.clientY};
};
var onMousemove = function(e){
if(isMouseDown){
camera.position.x += (e.clientX-lastMousePos.x)/100;
camera.position.y -= (e.clientY-lastMousePos.y)/100;
camera.lookAt(centerVector);
lastMousePos = {x:e.clientX, y:e.clientY};
}
};
var render = function(a) {
requestAnimationFrame(render);
particles.geometry.verticesNeedUpdate = true;
if(!isMouseDown){
camera.position.x += (0-camera.position.x)*0.06;
camera.position.y += (0-camera.position.y)*0.06;
camera.lookAt(centerVector);
}
renderer.render(scene, camera);
};
var imgData;
var image;
imgData ="data:image/png;base64,iVBORw0KGgoAAA...";
const changeState = function(state, num) {
document.getElementById('dropbox-choose').innerHTML = state;
numState = num;
switch (numState)
{
case 0:
imgData ="data:image/png;base64,iVBORw0KGgoAAA...";
break;
case 1:
imgData = "data:image/png;base64,iVBORw0KGgoI..."
break;
}
image.src = imgData;
}
image = document.createElement("img");
image.onload = init;
image.src = imgData;
And the THREE.WebGLRenderer is only applied once but when I click to change the image, it does not update and also I still have the problem that the website slows down
it's my first time using three js and i don't know if i'm applying well what it says in the documentation
EDIT 2
var renderer, scene, camera, ww, wh, particles, mw, mh, mz, numState;
numState = 0;
mz = 6;
ww = document.getElementById('map-container').offsetWidth,
wh = 450;
mw = ww * 2;
mh = wh * 2;
var centerVector = new THREE.Vector3(0, 0, 0);
var previousTime = 0
speed = 10
isMouseDown = false;
// Render
renderer = new THREE.WebGLRenderer({
canvas: document.getElementById("map"),
antialias: true
});
renderer.setSize(mw, mh);
renderer.setClearColor(0x12347C);
// Scence
scene = new THREE.Scene();
// Camera
camera = new THREE.OrthographicCamera( ww / - 2, ww / 2, wh / 2, wh / - 2, 1, 1000 );
camera.position.set(7, 0, 4);
camera.lookAt(centerVector);
scene.add(camera);
camera.zoom = 4;
camera.updateProjectionMatrix();
// Geometry
//var geometry = new THREE.Geometry();
var material = new THREE.PointsMaterial({
size: mz,
color: 0xFFFFFF,
sizeAttenuation: false
});
// Particle
particles = new THREE.Points();
particles.material = material
scene.add(particles);
var getImageData = function(image) {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0);
return ctx.getImageData(0, 0, image.width, image.height);
}
var drawTheMap = function() {
let vertices = particles.geometry; // this acts as a REFERENCE!
vertices.length = 0; // clears the vertices array
for (var y = 0, y2 = imagedata.height; y < y2; y += 2) {
for (var x = 0, x2 = imagedata.width; x < x2; x += 2) {
if (imagedata.data[(x * 4 + y * 4 * imagedata.width)] < 128) {
var vertex = new THREE.Vector3();
vertex.x = x - imagedata.width / 2;
vertex.y = -y + imagedata.height / 2;
vertex.z = -Math.random()*500;
vertex.speed = Math.random() / speed + 0.015;
vertices.vertices.push(vertex);
}
}
}
particles.geometry.verticesNeedUpdate = true; // Inform three.js of the update
requestAnimationFrame(render);
};
var init = function() {
imagedata = getImageData(image);
drawTheMap();
onResize();
window.addEventListener('mousemove', onMousemove, false);
window.addEventListener('mousedown', onMousedown, false);
window.addEventListener('mouseup', onMouseup, false);
window.addEventListener('resize', onResize, false);
};
var onResize = function(){
var mov1, mov2;
ww = document.getElementById('map-container').offsetWidth;
wh = 450;
if (window.innerWidth > 850) {
mw = ww * 2;
mh = wh * 2;
mz = 6;
mov1 = 2.2;
mov2 = 1.9;
particles.material.size = mz;
} else {
mw = ww;
mh = wh;
mz = 3;
mov1 = 2;
mov2 = 2;
particles.material.size = mz;
}
renderer.setSize(mw, mh);
camera.left = ww / - mov1;
camera.right = ww / 2;
camera.top = wh / mov2;
camera.bottom = wh / - 2;
camera.updateProjectionMatrix();
};
var onMouseup = function(){
isMouseDown = false;
}
var onMousedown = function(e){
isMouseDown = true;
lastMousePos = {x:e.clientX, y:e.clientY};
};
var onMousemove = function(e){
if(isMouseDown){
camera.position.x += (e.clientX-lastMousePos.x)/100;
camera.position.y -= (e.clientY-lastMousePos.y)/100;
camera.lookAt(centerVector);
lastMousePos = {x:e.clientX, y:e.clientY};
}
};
var render = function(a) {
requestAnimationFrame(render);
particles.geometry.verticesNeedUpdate = true;
if(!isMouseDown){
camera.position.x += (0-camera.position.x)*0.06;
camera.position.y += (0-camera.position.y)*0.06;
camera.lookAt(centerVector);
}
renderer.render(scene, camera);
};
var imgData;
var image;
imgData ="data:image/png;base64,iVBORw0KGgoAAA...";
const changeState = function(state, num) {
document.getElementById('dropbox-choose').innerHTML = state;
numState = num;
switch (numState)
{
case 0:
imgData ="data:image/png;base64,iVBORw0KGgoAAA...";
break;
case 1:
imgData = "data:image/png;base64,iVBORw0KGgoAAA..."
break;
}
image.src = imgData;
}
image = document.createElement("img");
image.onload = init;
image.src = imgData;
When I click to change the image, it does not update and also I still have the problem that the website slows down. I cahaged vertcies.push to vertices.vertices.push()

I know I mentioned disposal in a previous version of my answer, but let's instead consider re-using all of your objects.
particles - Add it to the scene immediately after creation.
material - Assign it to particles immediately; No need to re-assign it every time.
geometry - Don't create it globally, we'll let it work from within particles.
Now what we're going to do is replace the vertices and tell three.js that there are new vertices to upload to the GPU.
var drawTheMap = function() {
let vertices = particles.geometry; // this acts as a REFERENCE!
vertices.length = 0; // clears the vertices array
for (var y = 0, y2 = imagedata.height; y < y2; y += 2) {
for (var x = 0, x2 = imagedata.width; x < x2; x += 2) {
if (imagedata.data[(x * 4 + y * 4 * imagedata.width)] < 128) {
var vertex = new THREE.Vector3();
vertex.x = x - imagedata.width / 2;
vertex.y = -y + imagedata.height / 2;
vertex.z = -Math.random()*500;
vertex.speed = Math.random() / speed + 0.015;
vertices.push(vertex);
}
}
}
particles.geometry.verticesNeedUpdate = true; // Inform three.js of the update
requestAnimationFrame(render);
};
The important part here (other than replacing the contents of the vertices array) is setting particles.geometry.verticesNeedUpdate = true;. This is what triggers three.js to replace the vertices on the GPU. Everything else is re-used, not recreated, so it should run fairly smooth.

The solution is change THREE.geometry to THREE.BufferGeometry
var drawTheMap = function() {
particles.geometry = new THREE.BufferGeometry();
var positions = [];
for (var y = 0, y2 = imagedata.height; y < y2; y += 2) {
for (var x = 0, x2 = imagedata.width; x < x2; x += 2) {
if (imagedata.data[(x * 4 + y * 4 * imagedata.width)] < 128) {
positions.push(x - imagedata.width / 2);
positions.push(-y + imagedata.height / 2);
positions.push(-Math.random()*500);
particles.geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
}
}
}
particles.geometry.verticesNeedUpdate = true;
requestAnimationFrame(render);
};

Related

Raycaster malfunctioning in three.js

I am creating a game where players can move around from first-person perspective, where the ground is generated with Perlin noise and therefore uneven. I would like to simulate gravity in the game. Hence, a raycasting thing has been implemented, which is supposed to find the player's distance from the ground and stop them from falling when they hit the ground. Here is my code (if the snipper is unclear visit https://3d.211368e.repl.co):
const scene = new THREE.Scene(), camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000000000000), renderer = new THREE.WebGLRenderer(), canvas = renderer.domElement;
camera.rotation.order = "YXZ";
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
renderer.shadowMapType = THREE.PCFSoftShadowMap;
document.body.appendChild(canvas);
const light = new THREE.DirectionalLight( 0xffffff, 1);
light.position.set(0, 10000, 0);
light.castShadow = true;
light.shadow.camera.top = 10000;
light.shadow.camera.right = 10000;
light.shadow.camera.bottom = -10000;
light.shadow.camera.left = -10000;
light.shadow.camera.far = 100000;
wwwww
scene.add(light);
var sky = new THREE.Mesh(new THREE.SphereGeometry(100000, 3, 3, 0, Math.PI, 0, Math.PI), new THREE.MeshBasicMaterial({color: 0x579ebb}));
sky.material.side = THREE.BackSide;
sky.rotateX(-Math.PI / 2);
scene.add(sky);
class Vector2{
constructor(x, y){
this.x = x;
this.y = y;
}
dot(other){
return this.x * other.x + this.y * other.y;
}
}
function Shuffle(tab){
for(let e = tab.length-1; e > 0; e--){
let index = Math.round(Math.random() * (e-1)),
temp = tab[e];
tab[e] = tab[index];
tab[index] = temp;
}
}
function MakePermutation(){
let P = [];
for(let i = 0; i < 256; i++){
P.push(i);
}
Shuffle(P);
for(let i = 0; i < 256; i++){
P.push(P[i]);
}
return P;
}
let P = MakePermutation();
function GetConstantVector(v){
let h = v & 3;
if(h == 0) return new Vector2(1.0, 1.0);
if(h == 1) return new Vector2(-1.0, 1.0);
if(h == 2) return new Vector2(-1.0, -1.0);
return new Vector2(1.0, -1.0);
}
function Fade(t){
return ((6 * t - 15) * t + 10) * t ** 3;
}
function Lerp(t, a1, a2){
return a1 + t*(a2-a1);
}
function Noise2D(x, y){
let X = Math.floor(x) & 255;
let Y = Math.floor(y) & 255;
let xf = x - Math.floor(x);
let yf = y - Math.floor(y);
let topRight = new Vector2(xf - 1, yf - 1);
let topLeft = new Vector2(xf, yf - 1);
let bottomRight = new Vector2(xf - 1, yf);
let bottomLeft = new Vector2(xf, yf);
let valueTopRight = P[P[X+1]+Y+1];
let valueTopLeft = P[P[X]+Y+1];
let valueBottomRight = P[P[X+1]+Y];
let valueBottomLeft = P[P[X]+Y];
let dotTopRight = topRight.dot(GetConstantVector(valueTopRight));
let dotTopLeft = topLeft.dot(GetConstantVector(valueTopLeft));
let dotBottomRight = bottomRight.dot(GetConstantVector(valueBottomRight));
let dotBottomLeft = bottomLeft.dot(GetConstantVector(valueBottomLeft));
let u = Fade(xf);
let v = Fade(yf);
return Lerp(u, Lerp(v, dotBottomLeft, dotTopLeft), Lerp(v, dotBottomRight, dotTopRight));
}
const plane = new THREE.Mesh(new THREE.PlaneGeometry(10000, 10000, 500, 500), new THREE.MeshPhongMaterial({color: 0x00aa00}));
plane.rotateX(-Math.PI / 2 + 0.00001);
plane.receiveShadow = true;
for (let y = 0, i = 0; y < 501; y++){
for(let x = 0; x < 501; x++, i++){
let n = 0.0, a = 1.0, f = 0.005;
for (let o = 0; o < 3; o++){
let v = a*Noise2D(x*f, y*f);
n += v;
a *= 0.5;
f *= 2.0;
}
n += 1;
n /= 2;
plane.geometry.vertices[i].z = n * 1000;
}
}
scene.add(plane);
const point = plane.geometry.vertices[Math.floor(Math.random() * 1000)];
camera.position.set(point.x, point.z + 2, point.y);
const geo = new THREE.Mesh(new THREE.BoxGeometry(10, 10, 10), new THREE.MeshBasicMaterial({color: 0xff0000}));
geo.castShadow = true;
scene.add(geo);
const render = () => {
requestAnimationFrame(render);
const below = new THREE.Vector3(camera.position.x, -1000000, camera.position.y), cast = new THREE.Raycaster(camera.position, below), intersect = cast.intersectObject(plane);
if (intersect.length > 0){
if (intersect[0].distance < 3) camera.translateY(-1);
}else{
camera.translateY(-1);
}
renderer.render(scene, camera);
}
render();
onmousemove = () => {
if (camera.rotation._x > -0.8 || camera.rotation._y > -0.8){
camera.rotateX(-Math.atan(event.movementY / 300));
camera.rotateY(-Math.atan(event.movementX / 300));
}else{
if (Math.atan(event.movementY / 300) < 0) camera.rotateX(-Math.atan(event.movementY / 300));
if (Math.atan(event.movementX / 300) < 0) camera.rotateY(-Math.atan(event.movementX / 300));
}
camera.rotation.z = 0;
}
onresize = () => {
renderer.setSize(window.innerWidth, window.innerHeight);
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
}
onkeydown = (event) => {
if (event.key == "w") camera.translateZ(-10);
if (event.key == "a") camera.translateX(-1);
if (event.key == "s") camera.translateZ(1);
if (event.key == "d") camera.translateX(1);
if (event.key == "ArrowUp") camera.translateY(1);
if (event.key == "ArrowDown") camera.translateY(-1);
}
body{
margin: 0;
background-color: black;
overflow: hidden;
}
canvas{
border: none;
}
<meta name="viewport" content="width=device-width">
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/94/three.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/0949e59f/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/0949e59f/examples/js/utils/SceneUtils.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/0949e59f/examples/js/libs/dat.gui.min.js"></script>
If the ground is not detected at least 3 units below the camera, the player will continue falling. However, sometimes nothing is spotted below the camera, while the player is clearly hovering over the ground. This is extremely frustrating. Is there any reliable alternative method to solve this problem, such as using something other than raycasting? Or is there a bug in the code? TIA
See the Raycaster documentation. The constructor takes the origin, the direction and near and far parameters. So you could do:
const gravityDirection = new THREE.Vector3(0, -1, 0);
cast = new THREE.Raycaster(camera.position, gravityDirection, 0, 3);
and this also makes the distance check redundant, as the far parameter already filters out hits further away than 3 units.

Rotating an object with spherifical coordinates Three js

Im trying to roatate this space ship that i created, the rotation itself works the problem is that whenever i rotate it with the left and right arrow keys i want the spaceship to rotate just like with cartesian coordinates the problem is that whenever the objects rotates around the planet, the spaceship inclination doesnt change at all, like it would with cartesian coordinates and i dont get why really because the rotation around the planet itself works.
Sorry if the code is too long most of it is just to create the spaceship itself, i think the problem itself is in the update function itself.
Program:
/*global THREE*/
var camera = [];
var scene, renderer, currentCamera = 0;
var viewSize = 40;
var aspectRatio;
var geometry, material, mesh;
var wiredObjects = [];
var leftArrow, rightArrow, upArrow, downArrow;
var clock = new THREE.Clock();
//!!var controls;
var defaultScale = 1;
var planetRadius = 12;
var rocketHeight = planetRadius/12;
var rocketPartHeight = rocketHeight/2;
var rocketInfRadius = rocketPartHeight;
var rocketMidRadius = rocketPartHeight/2;
var rocketSupRadius = 0;
var boosterRadius = rocketInfRadius/5;
var boosterHeight = rocketInfRadius/4;
var rocketTrashDistance = 1.2 * planetRadius;
var objPositions = [];
var objAngles = [];
var nrTrash = 20;
var floatingTrash = [];
var trashSizes = [];
var minTrashSize = planetRadius/24;
var maxTrashSize = planetRadius/20;
var trashGeometries = [];
var copyVideo;
var universe;
var planet;
var rocket;
var loader = new THREE.TextureLoader();
var space_texture = new THREE.TextureLoader().load(
"https://wallpaperaccess.com/full/1268183.jpg"
);
'use strict';
function addObjPart(obj, geometry, mater, hex, x, y, z, rotX, rotY, rotZ) {
material = (mater != null)? mater : new THREE.MeshBasicMaterial({color: hex, wireframe: wires});
mesh = new THREE.Mesh(geometry, material);
mesh.rotateX(rotX);
mesh.rotateY(rotY);
mesh.rotateZ(rotZ);
mesh.position.set(x, y, z);
obj.add(mesh);
wiredObjects.push(mesh);
return mesh;
}
function getObjPositions() {
var i;
var nrObj = nrTrash+1;
var angleTheta, anglePhi;
var objX, objY, objZ;
var posVector = new THREE.Vector3(0,0,0); // spherical coordinates vector
var angleVector = new THREE.Vector2(0,0); // angles Theta and Phi for spherical coordinates
for (i = 0; i < nrObj; i++) {
angleTheta = Math.random() * 2*Math.PI;
anglePhi = Math.random() * 2*Math.PI;
angleVector.set(angleTheta, anglePhi);
objAngles.push(angleVector);
objX = rocketTrashDistance * Math.sin(angleTheta) * Math.sin(anglePhi);
objY = rocketTrashDistance * Math.cos(angleTheta);
objZ = rocketTrashDistance * Math.sin(angleTheta) * Math.cos(anglePhi);
posVector.set(objX, objY, objZ);
objPositions.push(posVector);
}
}
function createUniverse(x, y, z, scale) {
wires = true;
universe = new THREE.Object3D();
universe.scale.set(scale, scale, scale);
var rocketPos = objPositions[0];
addPlanet(universe, 0, 0, 0);
addRocket(universe, rocketPos.x, rocketPos.y, rocketPos.z);
addAux(universe);
universe.position.set(x, y, z);
scene.add(universe);
return universe;
}
function addPlanet(obj, x, y, z) {
planet = new THREE.Object3D();
geometry = new THREE.SphereGeometry(planetRadius);
var planetTexture = new THREE.TextureLoader().load(
"https://st2.depositphotos.com/5171687/44380/i/450/depositphotos_443805316-stock-photo-equirectangular-map-clouds-storms-earth.jpg"
);
var planetMaterial = new THREE.MeshBasicMaterial( {
map: planetTexture,
transparent:true,
side:THREE.DoubleSide,
} );
addObjPart(obj, geometry, planetMaterial, 0x0000ff, x, y, z, 0, 0, 0);
}
function addRocket(obj, x, y, z) {
rocket = new THREE.Group();
var n_rocket = new THREE.Object3D();
addRocketTop(n_rocket, 0, 0, -rocketPartHeight/2);
addRocketBottom(n_rocket, 0, 0, rocketPartHeight/2);
addRocketBooster(n_rocket, 0, rocketInfRadius-boosterRadius, rocketPartHeight+0.5*boosterHeight);
addRocketBooster(n_rocket, 0, -rocketInfRadius+boosterRadius,rocketPartHeight+0.5*boosterHeight);
addRocketBooster(n_rocket, rocketInfRadius-boosterRadius, 0, rocketPartHeight+0.5*boosterHeight);
addRocketBooster(n_rocket, -rocketInfRadius+boosterRadius, 0, rocketPartHeight+0.5*boosterHeight);
rocket.add(n_rocket);
rocket.position.set(x, y, z);
obj.add(rocket);
return rocket;
}
function addRocketTop(obj, x, y, z) {
geometry = new THREE.CylinderGeometry(rocketMidRadius, rocketSupRadius, rocketPartHeight, 41,1);
addObjPart(obj, geometry, null, 0xff0000, x, y, z, Math.PI/180*90, 0, 0);
}
function addRocketBottom(obj, x, y, z) {
geometry = new THREE.CylinderGeometry(rocketInfRadius, rocketMidRadius, rocketPartHeight, 41,1);
addObjPart(obj, geometry, null, 0x000fff, x, y, z, Math.PI/180*90, 0, 0);
}
function addRocketBooster(obj, x, y, z) {
geometry = new THREE.CapsuleGeometry(boosterRadius, boosterHeight, 0.5, 20);
addObjPart(obj, geometry, null, 0xff0000, x, y, z, Math.PI/180*90, 0, 0);
}
function addTrash(x, y, z) {
}
function render() {
renderer.render(scene, camera[currentCamera]); // tells 3js renderer to draw scene visualization based on camera
}
function onResize() {
if (window.innerWidth > 0 && window.innerHeight > 0){
var i;
var val = 2;
aspectRatio = window.innerWidth / window.innerHeight;
renderer.setSize(window.innerWidth, window.innerHeight);
var nrCameras = camera.length;
for (i = 0; i < 1; i++) { // Ortographic Cameras
camera[i].left = -viewSize * aspectRatio / val;
camera[i].right = viewSize * aspectRatio / val;
camera[i].top = viewSize / val;
camera[i].bottom = viewSize / -val;
camera[i].updateProjectionMatrix();
}
for (i=1; i < nrCameras; i++) { // Perspective cameras
camera[i].aspect = aspectRatio;
camera[i].updateProjectionMatrix();
}
}
}
function update()
{
var timeOccurred = clock.getDelta();
var rocketSpeed = Math.PI/180 * 40;
if (rightArrow || leftArrow || upArrow || downArrow) { // rocket movement flags
var rocketTheta = objAngles[0].x;
var rocketPhi = objAngles[0].y;
var rocketX, rocketY, rocketZ;
if (leftArrow){
rocketPhi += rocketSpeed * timeOccurred;
}
if (rightArrow){
//n_rocket.rotation.x += - rocketSpeed * timeOccurred;
rocketPhi += - rocketSpeed * timeOccurred;
}
if (upArrow){
//n_rocket.rotation.z += - rocketSpeed * timeOccurred;
rocketTheta += -rocketSpeed * timeOccurred;
}
if (downArrow){
//n_rocket.rotation.z += rocketSpeed * timeOccurred;
rocketTheta += rocketSpeed * timeOccurred;
}
rocketX = rocketTrashDistance * Math.sin(rocketTheta) * Math.sin(rocketPhi);
rocketY = rocketTrashDistance * Math.cos(rocketTheta);
rocketZ = rocketTrashDistance * Math.sin(rocketTheta) * Math.cos(rocketPhi);
rocket.position.set(rocketX, rocketY, rocketZ);
objAngles[0].set(rocketTheta, rocketPhi);
objPositions[0].set(rocketX, rocketY, rocketZ);
}
}
function animate() {
update();
requestAnimationFrame(animate);
// controls.update();
render();
}
function addAux(obj) {
geometry = new THREE.SphereGeometry(5);
addObjPart(obj, geometry, null, 0xffc0cb, 15, 0, 0);
addObjPart(obj, geometry, null, 0xffff00, 15, 0, 0);
addObjPart(obj, geometry, null, 0x0000ff, 15, 0, 0);
}
function createScene() {
scene = new THREE.Scene();
scene.add(new THREE.AxesHelper(100));
scene.background = space_texture;
getObjPositions();
universe = createUniverse(0, 0, 0, defaultScale);
}
function createOrtographicCamera(x, y, z) {
var val = 2;
aspectRatio = window.innerWidth / window.innerHeight;
var camera = new THREE.OrthographicCamera( viewSize * aspectRatio/-val,
viewSize * aspectRatio / val,
viewSize / val,
viewSize / -val,
1,
1000);
camera.position.x = x;
camera.position.y = y;
camera.position.z = z;
camera.lookAt(scene.position);
return camera;
}
function onKeyDown(e) {
var keyName = e.keyCode;
switch (keyName) {
case 49://1
currentCamera = 0;
break;
case 37 : // left arrow key
leftArrow = true;
break;
case 38: // up arrow key
upArrow = true;
break;
case 39: // right arrow key
rightArrow = true;
break;
case 40: // down arrow key
downArrow = true;
break;
default:
break;
}
}
function onKeyUp(e) {
var keyName = e.keyCode;
switch (keyName) {
case 37 : // left arrow key
leftArrow = false;
break;
case 38: // up arrow key
upArrow = false;
break;
case 39: // right arrow key
rightArrow = false;
break;
case 40: // down arrow key
downArrow = false;
break;
default:
break;
}
}
function init() {
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
createScene();
camera[0] = createOrtographicCamera(viewSize, 0, 0);
//!! controls = new THREE.OrbitControls(camera[0], renderer.domElement);
animate();
window.addEventListener("resize", onResize);
window.addEventListener("keydown", onKeyDown);
window.addEventListener("keyup", onKeyUp);
}

THREE.js - shooting a ball with a curve ( X / Z axis)

I'm new to THREE.js and with a very poor knowledge in physics but still I want to make a football manager game (played from top view) and I need to know that the kick of the ball is realistic as possible.
I was able to make the ball move and rotate in the correct direction while changing the position of the movement when the ball hits its boundaries.
now I need to deal with a issue of the curve of the ball and how do I make it so the ball with move in an arc to the top and to the sides (X / Y) depending of the angle of the foot hitting the ball
lets just say, I need to know how to handle two scenarios:
1) when kick start from the near bottom axis of the ball
2) when kick start from the near right axis of the ball
your help is highly appropriated. Thank you!
**
- I've added a code showing what i have so far
- I've added an image illustrating my goal (or this person scoring a goal)
/*
*
* SET UP MOTION PARAMS
*
*/
var boundries = [40, 24] //indicate where the ball needs to move in mirror position
var completeFieldDistance = boundries[0] * 2;
var fullPower = 1.8; //the power needed to move the ball the enitre field in one kick
var power = null; //will be set when the kick set in depending on the distance
var isKickStop = false; //indicate the renderer weather to stop the kick
var velocityX = null;
var velocityY = null;
//*** this is where i need help! ***
//how can I make the ball move in the Z axis with a nice curv up depending on a given angle
var curv = 15;
var peak = curv;
var velocityZ = 0;
var friction = 0.98;
var gravity = 0.5;
var bounciness = 0.8;
var minVelocity = 0.035; //for when it need to stop the kick rendering
var ballRadius = 3;
var ballCircumference = Math.PI * ballRadius * 2;
var ballVelocity = new THREE.Vector3();
var ballRotationAxis = new THREE.Vector3(0, 1, 0);
//world meshes
var ball = {};
var field = {};
/*
*
* THE KICK HANDLERS
*
*/
function onKick(angleDeg, distance) {
isKickStop = true;
peak = curv;
power = (distance / completeFieldDistance) * fullPower;
velocityX = Math.cos(angleDeg) * power;
velocityY = Math.sin(angleDeg) * power;
velocityZ = peak / (distance / 2);
requestAnimationFrame(function (params) {
isKickStop = false;
animateKick();
})
}
//** THIS IS WHERE I NEED HELP - how do I make the ball move
// render the movements of the ball
var animateKick = function (params) {
if (isKickStop) { return; }
ball.position.x += velocityX;
ball.position.z += velocityZ;
ball.position.y += velocityY;
if (Math.abs(velocityX) < minVelocity && Math.abs(velocityY) < minVelocity) {
ball.position.z = ball.bottom;
isKickStop = true;
console.log("DONE!");
return;
}
if (ball.position.z >= peak) {
ball.position.z = peak;
velocityZ *= -1;
}
if (ball.position.z < ball.bottom) {
peak *= gravity;
velocityZ *= -1;
ball.position.z = ball.bottom;
}
// Figure out the rotation based on the velocity and radius of the ball...
ballVelocity.set(velocityX, velocityY, 0);
ballRotationAxis.set(0, 0, 1).cross(ballVelocity).normalize();
var velocityMag = ballVelocity.length();
var rotationAmount = velocityMag * (Math.PI * 2) / ballCircumference;
ball.rotateOnWorldAxis(ballRotationAxis, rotationAmount);
//reduce velocity due to friction
velocityX *= friction;
velocityY *= friction;
//making sure ball is not outside of its boundries
if (Math.abs(ball.position.x) > boundries[0]) {
velocityX *= -1;
ball.position.x = (ball.position.x < 0) ? boundries[0] * -1 : boundries[0];
}
if (Math.abs(ball.position.y) > boundries[1]) {
velocityY *= -1;
ball.position.y = (ball.position.y < 0) ? boundries[1] * -1 : boundries[1];
}
}
window.onload = (function (params) {
/*
*
* SET UP THE WORLD
*
*/
//set up the ratio
var gWidth = window.innerWidth;
var gHeight = window.innerHeight;
var ratio = gWidth / gHeight;
//set the scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0xeaeaea);
//set the camera
var camera = new THREE.PerspectiveCamera(35, ratio, 0.1, 1000);
camera.position.z = 120;
//set the light
var light = new THREE.SpotLight(0xffffff, 1);
light.castShadow = true;
light.position.set(0, 0, 35);
scene.add(light);
// set the renderer
var renderer = new THREE.WebGLRenderer();
//properties for casting shadow
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setSize(gWidth, gHeight);
document.body.appendChild(renderer.domElement);
/*
*
* ADD MESH TO SCENE
*
*/
// create and add the ball
var geometry = new THREE.SphereGeometry(ballRadius, 8, 8);
//make a checkerboard texture for the ball...
var canv = document.createElement('canvas')
canv.width = canv.height = 256;
var ctx = canv.getContext('2d')
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, 256, 256);
ctx.fillStyle = 'black';
for (var y = 0; y < 16; y++)
for (var x = 0; x < 16; x++)
if ((x & 1) != (y & 1)) ctx.fillRect(x * 16, y * 16, 16, 16);
var ballTex = new THREE.Texture(canv);
ballTex.needsUpdate = true;
var material = new THREE.MeshLambertMaterial({
map: ballTex
});
ball = new THREE.Mesh(geometry, material);
ball.castShadow = true;
ball.receiveShadow = false;
ball.bottom = ballRadius / 2;
scene.add(ball);
// create and add the field
var margin = 20;
var fieldRatio = 105 / 68;
var width = 90;
var height = width / fieldRatio;
var material = new THREE.MeshLambertMaterial({ color: 'green' });
var geometry = new THREE.BoxGeometry(width, height, 1);
field = new THREE.Mesh(geometry, material);
field.receiveShadow = true;
field.position.z = -1;
scene.add(field);
/*
*
* HANDLING EVENTS
*
*/
var domEvents = new THREEx.DomEvents(camera, renderer.domElement);
domEvents.addEventListener(field, 'click', function (e) {
//set points 1 and 2
var p1 = { x: e.intersect.point.x, y: e.intersect.point.y };
var p2 = { x: ball.position.x, y: ball.position.y };
var angleDeg = Math.atan2(p1.y - p2.y, p1.x - p2.x);
var a = p1.x - p2.x;
var b = p1.y - p2.y;
var distance = Math.sqrt(a * a + b * b);
window.onKick(angleDeg, distance);
}, false);
/*
*
* ANIMATION STEP
*
*/
var render = function (params) {
//render kick if it is on the go
if(!isKickStop){
animateKick();
}
//render the page
renderer.render(scene, camera);
requestAnimationFrame(render);
}
render();
})()
body {
padding: 0;
margin: 0;
}
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script>
<script src="https://www.klika.co.il/scripts/three.events.js"></script>
</head>
<body>
</body>
</html>
I build a model to mock this, the model accept several parameters, initial velocity and angular velocity, there are three force on the ball, gravity, air resistance force and Magnus force.
v0_x = 0; //initial velocity
v0_y = 4;
v0_z = 1;
w_x = 0 * Math.PI; // initial angular velocity
w_y = 2 * Math.PI;
w_z = 0 * Math.PI;
m = 2; //weight
rho = 1.2; // air density
g = 9.8; // gravity
f = 10; //frequency of the rotation of the ball
cl = 1.23; //horizontal tension coefficient
cd = 0.5; //air resistance coefficient
D = 0.22; // diameter of the ball
A = Math.PI * Math.pow((0.5 * D), 2); //cross-sectional area of the ball
t_step = 1 / 60;
b = (1 / 2) * cd * rho * A; //for convenience
c = cl * rho * Math.pow(D, 3) * f; // for convenience
vt_x = v0_x
vt_y = v0_y
vt_z = v0_z
animateKick = function() {
if (ball.position.y < 0) {
return;
}
tmp_1 = c * Math.pow(Math.pow(vt_x, 2) + Math.pow(vt_z, 2) + Math.pow(vt_y, 2), 2)
tmp_2 = (Math.sqrt(Math.pow(w_z * vt_y - w_y * vt_z, 2) + Math.pow(w_y * vt_x - w_x * vt_y, 2) + Math.pow(w_x * vt_z - w_z * vt_x, 2)))
tmp = tmp_1 / tmp_2
Fl_x = tmp * (w_z * vt_y - w_y * vt_z)
Fl_z = tmp * (w_y * vt_x - w_x * vt_y)
Fl_y = tmp * (w_x * vt_z - w_z * vt_y)
//Motion differential equation
a_x = -(b / m) * Math.sqrt((Math.pow(vt_z, 2) + Math.pow(vt_y, 2) + Math.pow(vt_x, 2))) * vt_x + (Fl_x / m)
a_z = -(b / m) * Math.sqrt((Math.pow(vt_z, 2) + Math.pow(vt_y, 2) + Math.pow(vt_x, 2))) * vt_z + (Fl_z / m)
a_y = -g - (b / m) * Math.sqrt((Math.pow(vt_z, 2) + Math.pow(vt_y, 2) + Math.pow(vt_x, 2))) * vt_y + (Fl_y / m)
//use formula : s_t = s_0 + v_0 * t to update the position
ball.position.x = ball.position.x + vt_x * t_step
ball.position.z = ball.position.z + vt_z * t_step
ball.position.y = ball.position.y + vt_y * t_step
//use formula : v_t = a * t to update the velocity
vt_x = vt_x + a_x * t_step
vt_z = vt_z + a_z * t_step
vt_y = vt_y + a_y * t_step
}
window.onload = (function() {
gWidth = window.innerWidth;
gHeight = window.innerHeight;
ratio = gWidth / gHeight;
scene = new THREE.Scene();
scene.background = new THREE.Color(0xeaeaea);
camera = new THREE.PerspectiveCamera(35, ratio, 0.1, 1000);
camera.position.z = -15;
light = new THREE.SpotLight(0xffffff, 1);
light.castShadow = true;
light.position.set(0, 5, -10);
scene.add(light);
renderer = new THREE.WebGLRenderer();
//properties for casting shadow
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setSize(gWidth, gHeight);
document.body.appendChild(renderer.domElement);
geometry = new THREE.SphereGeometry(D, 8, 8);
//make a checkerboard texture for the ball...
canv = document.createElement('canvas')
canv.width = canv.height = 256;
ctx = canv.getContext('2d')
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, 256, 256);
ctx.fillStyle = 'black';
for (y = 0; y < 16; y++)
for (x = 0; x < 16; x++)
if ((x & 1) != (y & 1)) ctx.fillRect(x * 16, y * 16, 16, 16);
ballTex = new THREE.Texture(canv);
ballTex.needsUpdate = true;
material = new THREE.MeshLambertMaterial({
map: ballTex
});
ball = new THREE.Mesh(geometry, material);
ball.castShadow = true;
ball.receiveShadow = false;
ball.bottom = D / 2;
scene.add(ball);
camera.lookAt(ball.position);
plane_geometry = new THREE.PlaneGeometry(20, 100, 32);
plane_material = new THREE.MeshBasicMaterial({
color: 'green',
side: THREE.DoubleSide
});
ground_plane = new THREE.Mesh(plane_geometry, plane_material);
ground_plane.rotation.x = 0.5 * Math.PI
ground_plane.position.y = -1
ground_plane.position.z = 20
scene.add(ground_plane);
render = function(params) {
animateKick();
renderer.render(scene, camera);
requestAnimationFrame(render);
};
render();
})
body {
padding: 0;
margin: 0;
}
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script>
<script src="https://www.klika.co.il/scripts/three.events.js"></script>
</head>
<body>
</body>
</html>

Changing input from text to radio stops existing code working

I have some code which works perfect from a tutorial site. It shows RSVP and updates the text when you type in the input box. This is the code working:
https://jsfiddle.net/spadez/7gyrd08w/6/
Current it works with an input box as such:
<input id="input" type="text" value="EDIT ME">
And then the following JS:
function initInput() {
input = document.getElementById('input');
input.addEventListener('keyup', updateText);
input.value = 'RSVP';
}
I wanted to change it to pull the value from the radio box when one was selected. So I changed the html to this:
<input id="input" type="radio" name="rsvp" value="Yay!">
<input id="input" type="radio" name="rsvp" value="Oh no!">
And the JavaScript to this (line 167):
function initInput() {
input = document.getElementById('input');
input.addEventListener('change', updateText);
input.value = 'RSVP';
}
However, this doesn't work, and when I select a radio box the text doesn't update. Is there any obvious reason why? This code can be seen here (not working with the radio field):
https://jsfiddle.net/spadez/7gyrd08w/7/
Use the following code. This should help you solve the problem.
var height,
width,
container,
scene,
camera,
renderer,
particles = [],
mouseVector = new THREE.Vector3(0, 0, 0),
mousePos = new THREE.Vector3(0, 0, 0),
cameraLookAt = new THREE.Vector3(0, 0, 0),
cameraTarget = new THREE.Vector3(0, 0, 800),
textCanvas,
textCtx,
textPixels = [],
input;
var colors = ['#F7A541', '#F45D4C', '#FA2E59', '#4783c3', '#9c6cb7'];
function initStage() {
width = window.innerWidth;
height = window.innerHeight;
container = document.getElementById('stage');
window.addEventListener('resize', resize);
container.addEventListener('mousemove', mousemove);
}
function initScene() {
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({
alpha: true,
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(width, height);
container.appendChild(renderer.domElement);
}
function randomPos(vector) {
var radius = width * 3;
var centerX = 0;
var centerY = 0;
// ensure that p(r) ~ r instead of p(r) ~ constant
var r = width + radius * Math.random();
var angle = Math.random() * Math.PI * 2;
// compute desired coordinates
vector.x = centerX + r * Math.cos(angle);
vector.y = centerY + r * Math.sin(angle);
}
function initCamera() {
fieldOfView = 75;
aspectRatio = width / height;
nearPlane = 1;
farPlane = 3000;
camera = new THREE.PerspectiveCamera(
fieldOfView,
aspectRatio,
nearPlane,
farPlane);
camera.position.z = 800;
console.log(camera.position);
console.log(cameraTarget);
}
function createLights() {
shadowLight = new THREE.DirectionalLight(0xffffff, 2);
shadowLight.position.set(20, 0, 10);
shadowLight.castShadow = true;
shadowLight.shadowDarkness = 0.01;
scene.add(shadowLight);
light = new THREE.DirectionalLight(0xffffff, .5);
light.position.set(-20, 0, 20);
scene.add(light);
backLight = new THREE.DirectionalLight(0xffffff, 0.8);
backLight.position.set(0, 0, -20);
scene.add(backLight);
}
function Particle() {
this.vx = Math.random() * 0.05;
this.vy = Math.random() * 0.05;
}
Particle.prototype.init = function(i) {
var particle = new THREE.Object3D();
var geometryCore = new THREE.BoxGeometry(20, 20, 20);
var materialCore = new THREE.MeshLambertMaterial({
color: colors[i % colors.length],
shading: THREE.FlatShading
});
var box = new THREE.Mesh(geometryCore, materialCore);
box.geometry.__dirtyVertices = true;
box.geometry.dynamic = true;
particle.targetPosition = new THREE.Vector3((textPixels[i].x - (width / 2)) * 4, (textPixels[i].y) * 5, -10 * Math.random() + 20);
particle.position.set(width * 0.5, height * 0.5, -10 * Math.random() + 20);
randomPos(particle.position);
for (var i = 0; i < box.geometry.vertices.length; i++) {
box.geometry.vertices[i].x += -10 + Math.random() * 20;
box.geometry.vertices[i].y += -10 + Math.random() * 20;
box.geometry.vertices[i].z += -10 + Math.random() * 20;
}
particle.add(box);
this.particle = particle;
}
Particle.prototype.updateRotation = function() {
this.particle.rotation.x += this.vx;
this.particle.rotation.y += this.vy;
}
Particle.prototype.updatePosition = function() {
this.particle.position.lerp(this.particle.targetPosition, 0.02);
}
function render() {
renderer.render(scene, camera);
}
function updateParticles() {
for (var i = 0, l = particles.length; i < l; i++) {
particles[i].updateRotation();
particles[i].updatePosition();
}
}
function setParticles() {
for (var i = 0; i < textPixels.length; i++) {
if (particles[i]) {
particles[i].particle.targetPosition.x = (textPixels[i].x - (width / 2)) * 4;
particles[i].particle.targetPosition.y = (textPixels[i].y) * 5;
particles[i].particle.targetPosition.z = -10 * Math.random() + 20;
} else {
var p = new Particle();
p.init(i);
scene.add(p.particle);
particles[i] = p;
}
}
for (var i = textPixels.length; i < particles.length; i++) {
randomPos(particles[i].particle.targetPosition);
}
}
function initCanvas() {
textCanvas = document.getElementById('text');
textCanvas.style.width = width + 'px';
textCanvas.style.height = 200 + 'px';
textCanvas.width = width;
textCanvas.height = 200;
textCtx = textCanvas.getContext('2d');
textCtx.font = '700 100px Arial';
textCtx.fillStyle = '#555';
}
//function initInput() {
// input = document.getElementById('input');
// input.addEventListener('keyup', updateText);
// input.value = 'RSVP';
//}
function initInput() {
radios = document.getElementsByName('rsvp');
for (radio in radios) {
(radios[radio]).onclick = updateText;
}
//input.value = 'RSVP';
}
function updateText() {
var value = (this.value != undefined) ? this.value : '';
var fontSize = (width / (value * 1.3));
if (fontSize > 120) fontSize = 120;
textCtx.font = '700 ' + fontSize + 'px Arial';
textCtx.clearRect(0, 0, width, 200);
textCtx.textAlign = 'center';
textCtx.textBaseline = "middle";
textCtx.fillText(value.toUpperCase(), width / 2, 50);
var pix = textCtx.getImageData(0, 0, width, 200).data;
textPixels = [];
for (var i = pix.length; i >= 0; i -= 4) {
if (pix[i] != 0) {
var x = (i / 4) % width;
var y = Math.floor(Math.floor(i / width) / 4);
if ((x && x % 6 == 0) && (y && y % 6 == 0)) textPixels.push({
x: x,
y: 200 - y + -120
});
}
}
setParticles();
}
function animate() {
requestAnimationFrame(animate);
updateParticles();
camera.position.lerp(cameraTarget, 0.2);
camera.lookAt(cameraLookAt);
render();
}
function resize() {
width = window.innerWidth;
height = window.innerHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
textCanvas.style.width = width + 'px';
textCanvas.style.height = 200 + 'px';
textCanvas.width = width;
textCanvas.height = 200;
updateText();
}
function mousemove(e) {
//var x = e.pageX - width/2;
//var y = e.pageY - height/2;
//cameraTarget.x = x*-1;
//cameraTarget.y = y;
}
initStage();
initScene();
initCanvas();
initCamera();
createLights();
initInput();
animate();
setTimeout(function() {
updateText();
}, 40);
body {
overflow: hidden;
}
div,
canvas {
position: absolute;
}
#text {
z-index: 200;
display: none;
}
form {
z-index: 400;
position: absolute;
text-transform: uppercase;
font-size: 30px;
color: #222;
font-weight: bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.min.js"></script>
<div id="stage"></div>
<canvas id="text" width="700" height="150"></canvas>
<form>
<!--<input id="input" type="text" value="EDIT ME">-->
<input id="input" type="radio" name="rsvp" value="Yay!">
<input id="input" type="radio" name="rsvp" value="Oh no!">
</form>

onLoad function to onClick only

This code causes a particle explosion on my page.
I attached the onClick function to a button in my HTML so it runs when I click that certain button. But when I load the HTML it automatically runs this function and after that only when I click the button.
What I need is that it wont rune when you run the HTML. The function may only run when the button is clicked.
I also would like to ask how I can change te canvas size. Since this function automatically creates a canvas where the function loads in but this one is bigger than the div with the sizes I want it to run in.
//////////////settings/////////
var movementSpeed = 30;
var totalObjects = 500;
var objectSize = 70;
var sizeRandomness = 0;
var color = 0x00BEE0;
/////////////////////////////////
var dirs = [];
var parts = [];
//var container = document.createElement('div');
//document.body.appendChild( container );
var container = document.getElementById('header');
//document.body.appendChild( header );
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000)
camera.position.z = 1000;
var scene = new THREE.Scene();
function ExplodeAnimation(x, y) {
var geometry = new THREE.Geometry();
for (i = 0; i < totalObjects; i++) {
var vertex = new THREE.Vector3();
vertex.x = x;
vertex.y = y;
vertex.z = 0;
geometry.vertices.push(vertex);
dirs.push({
x: (Math.random() * movementSpeed) - (movementSpeed / 2),
y: (Math.random() * movementSpeed) - (movementSpeed / 2),
z: (Math.random() * movementSpeed) - (movementSpeed / 2)
});
}
var material = new THREE.ParticleBasicMaterial({
size: objectSize,
color: color
});
var particles = new THREE.ParticleSystem(geometry, material);
this.object = particles;
this.status = true;
this.xDir = (Math.random() * movementSpeed) - (movementSpeed / 2);
this.yDir = (Math.random() * movementSpeed) - (movementSpeed / 2);
this.zDir = (Math.random() * movementSpeed) - (movementSpeed / 2);
scene.add(this.object);
this.update = function() {
if (this.status == true) {
var pCount = totalObjects;
while (pCount--) {
var particle = this.object.geometry.vertices[pCount]
particle.y += dirs[pCount].y;
particle.x += dirs[pCount].x;
particle.z += dirs[pCount].z;
}
this.object.geometry.verticesNeedUpdate = true;
}
}
}
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
renderer.render(scene, camera);
parts.push(new ExplodeAnimation(0, 0));
render();
function render() {
requestAnimationFrame(render);
var pCount = parts.length;
while (pCount--) {
parts[pCount].update();
}
renderer.render(scene, camera);
}
window.addEventListener('mousedown', onclick, false);
window.addEventListener('resize', onWindowResize, false);
function onClick() {
event.preventDefault();
parts.push(new ExplodeAnimation((Math.random() * sizeRandomness) - (sizeRandomness / 2), (Math.random() * sizeRandomness) - (sizeRandomness / 2)));
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
As I saw you code , I think you should only put your bellow trigger code inside the click button :
renderer.render(scene, camera);
parts.push(new ExplodeAnimation(0, 0));
render();
because it's executed automatically when loading .
See My below Snippet , I ve added a sample button and run() function to show animation on click :
//////////////settings/////////
var movementSpeed = 30;
var totalObjects = 500;
var objectSize = 70;
var sizeRandomness = 0;
var color = 0x00BEE0;
/////////////////////////////////
var dirs = [];
var parts = [];
//var container = document.createElement('div');
//document.body.appendChild( container );
var container = document.getElementById('header');
//document.body.appendChild( header );
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000)
camera.position.z = 1000;
var scene = new THREE.Scene();
function ExplodeAnimation(x, y) {
var geometry = new THREE.Geometry();
for (i = 0; i < totalObjects; i++) {
var vertex = new THREE.Vector3();
vertex.x = x;
vertex.y = y;
vertex.z = 0;
geometry.vertices.push(vertex);
dirs.push({
x: (Math.random() * movementSpeed) - (movementSpeed / 2),
y: (Math.random() * movementSpeed) - (movementSpeed / 2),
z: (Math.random() * movementSpeed) - (movementSpeed / 2)
});
}
var material = new THREE.ParticleBasicMaterial({
size: objectSize,
color: color
});
var particles = new THREE.ParticleSystem(geometry, material);
this.object = particles;
this.status = true;
this.xDir = (Math.random() * movementSpeed) - (movementSpeed / 2);
this.yDir = (Math.random() * movementSpeed) - (movementSpeed / 2);
this.zDir = (Math.random() * movementSpeed) - (movementSpeed / 2);
scene.add(this.object);
this.update = function() {
if (this.status == true) {
var pCount = totalObjects;
while (pCount--) {
var particle = this.object.geometry.vertices[pCount]
particle.y += dirs[pCount].y;
particle.x += dirs[pCount].x;
particle.z += dirs[pCount].z;
}
this.object.geometry.verticesNeedUpdate = true;
}
}
}
var renderer = new THREE.WebGLRenderer();
function render() {
requestAnimationFrame(render);
var pCount = parts.length;
while (pCount--) {
parts[pCount].update();
}
renderer.render(scene, camera);
}
window.addEventListener('mousedown', onclick, false);
window.addEventListener('resize', onWindowResize, false);
function onClick() {
event.preventDefault();
parts.push(new ExplodeAnimation((Math.random() * sizeRandomness) - (sizeRandomness / 2), (Math.random() * sizeRandomness) - (sizeRandomness / 2)));
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
document.getElementById("btn").addEventListener('click',run);
function run() {
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
renderer.render(scene, camera);
parts.push(new ExplodeAnimation(0, 0));
render();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js"></script>
<button id="btn">Click to run </button>
<div id="header">

Categories