three.js animating ball on a plane - animation

Please i need help on three.js animation. trying to animate the ball randomly on the plane before stoping at specific or selected location on the plane. my code below please any help will be appreciates.
1: https://i.stack.imgur.com/3kXhW.png
Please i need help on three.js animation. trying to animate the ball randomly on the plane before stoping at specific or selected location on the plane. my code below please any help will be appreciates.
.
. .
import { OrbitControls } from "./libs/three128/OrbitControls.js";
import { GUI } from "./dat.gui.module.js";
class Game {
constructor() {
const container = document.createElement("div");
document.body.appendChild(container);
this.step = 0;
this.speed = 0.01;
this.camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
this.camera.position.set(-10, 150, 150);
this.scene = new THREE.Scene();
this.scene.background = new THREE.Color(0xaaaaaa);
const ambient = new THREE.HemisphereLight(0xffffff, 0xbbbbff, 0.3);
this.scene.add(ambient);
const light = new THREE.DirectionalLight();
light.position.set(0.2, 1, 1);
this.scene.add(light);
this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(this.renderer.domElement);
//Replace Box with Circle, Cone, Cylinder, Dodecahedron, Icosahedron, Octahedron, Plane, Sphere, Tetrahedron, Torus or TorusKnot
const planeGeometry = new THREE.BoxBufferGeometry(200, 200, 3);
const planeMaterial = new THREE.MeshStandardMaterial({
color: 0xff0000,
side: THREE.DoubleSide,
});
this.plane = new THREE.Mesh(planeGeometry, planeMaterial);
this.scene.add(this.plane);
const ballGeometry = new THREE.SphereGeometry(8, 100, 100);
const ballMaterial = new THREE.MeshStandardMaterial({
color: 0x0000ff,
wireframe: false,
});
this.ball = new THREE.Mesh(ballGeometry, ballMaterial);
this.scene.add(this.ball);
const controls = new OrbitControls(this.camera, this.renderer.domElement);
this.gridHelper = new THREE.GridHelper(200);
this.scene.add(this.gridHelper);
this.input();
this.renderer.setAnimationLoop(this.render.bind(this));
window.addEventListener("resize", this.resize.bind(this));
}
input() {
const gui = new GUI();
let ball = this.ball;
let plane = this.plane;
ball.position.set(0, 9.5, 0);
const options = {
ballColor: ball.material.color.getHex(),
planeColor: plane.material.color.getHex(),
positionX: ball.position.x,
positionZ: ball.position.z,
wireframe: false,
};
gui
.add(options, "positionX", -100, 100)
.name("X-coodinate")
.onChange(function (value) {
ball.position.x = value;
console.log(value);
});
gui
.add(options, "positionZ", -100, 100)
.name("Y-coodinate")
.onChange(function (value) {
ball.position.z = value;
console.log(value);
});
gui
.addColor(options, "ballColor")
.name("Ball-Color")
.onChange(function (value) {
ball.material.color.set(value);
});
gui
.addColor(options, "planeColor")
.name("Plane-Color")
.onChange(function (value) {
plane.material.color.set(value);
});
// gui.add(ball.material, "wireframe").name("Wireframe");
}
resize() {
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
this.renderer.setSize(window.innerWidth, window.innerHeight);
}
render() {
this.plane.rotation.x = -0.5 * Math.PI;
this.renderer.render(this.scene, this.camera);
}
}
export { Game };
project picture.

Related

The DOM element created by CSS3DObject cannot be obscured by the GL plane

I found that it seems to be solved by setting the blending attribute of material, but it still cannot be solved after trying.
Incorrect occlusion
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import {GLTFLoader} from "three/examples/jsm/loaders/GLTFLoader.js"
import {
CSS3DRenderer,
CSS3DObject
} from "three/examples/jsm/renderers/CSS3DRenderer.js"
import dat from "dat.gui"
function initThree() {
const scene = new THREE.Scene();
const scene2 = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
50,
window.innerWidth / window.innerHeight,
0.1,
10000
);
camera.position.set(0, 0, 2500);
scene.add(camera);
const renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true,
});
renderer.shadowMap.enabled = true;
renderer.setSize(window.innerWidth, window.innerHeight);
document.querySelector('#webgl').appendChild(renderer.domElement);
const labelRenderer = new CSS3DRenderer()
labelRenderer.setSize(window.innerWidth, window.innerHeight);
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = 0;
document.body.appendChild(labelRenderer.domElement);
scene.add(new THREE.AxesHelper(1000))
const controls = new OrbitControls(camera, labelRenderer.domElement);
controls.enableDamping = true;
const clock = new THREE.Clock()
window.addEventListener("resize", () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
labelRenderer.setSize(window.innerWidth, window.innerHeight);
});
return {
scene,
scene2,
camera,
renderer,
labelRenderer,
controls,
clock,
}
}
const gltfLoader = new GLTFLoader()
const textureLoader = new THREE.TextureLoader()
const gui = new dat.GUI()
const {
scene,
scene2,
camera,
renderer,
labelRenderer,
controls,
clock
} = initThree();
const ambientLight = new THREE.AmbientLight("#ffffff", 1)
scene.add(ambientLight)
const position = new THREE.Vector3(0, 900, 300);
const rotation = new THREE.Euler(0, 0, 0);
const container = document.createElement('div');
container.style.width = '1000px';
container.style.height = '1000px';
container.style.opacity = '1';
container.style.background = '#1d2e2f';
const iframe = document.createElement('iframe');
iframe.src = "http://csyedu.top"
iframe.style.width = "1000px"
iframe.style.height = "1000px"
iframe.style.padding = 10 + 'px';
iframe.style.boxSizing = 'border-box';
iframe.style.opacity = '1';
container.appendChild(iframe);
const object = new CSS3DObject(container);
// copy monitor position and rotation
object.position.copy(position);
object.rotation.copy(rotation);
// Add to CSS scene
scene2.add(object);
// Create GL plane
const material = new THREE.MeshLambertMaterial();
material.side = THREE.DoubleSide;
material.opacity = 0;
material.transparent = true;
// NoBlending allows the GL plane to occlude the CSS plane
material.blending = THREE.NoBlending;
// Create plane geometry
const geometry = new THREE.PlaneGeometry(1000, 1000);
// Create the GL plane mesh
const mesh = new THREE.Mesh(geometry, material);
// Copy the position, rotation and scale of the CSS plane to the GL plane
mesh.position.copy(object.position);
mesh.rotation.copy(object.rotation);
mesh.scale.copy(object.scale);
// Add to gl scene
scene.add(mesh);
gltfLoader.load("./models/computer_setup.glb", model => {
const texture = textureLoader.load("./models/baked_computer.jpg");
texture.flipY = false;
texture.encoding = THREE.sRGBEncoding;
const material = new THREE.MeshBasicMaterial({
map: texture,
});
model.scene.traverse((child) => {
if (child instanceof THREE.Mesh) {
child.scale.set(900, 900, 900);
child.material.map = texture;
child.material = material;
}
});
scene.add(model.scene)
})
function render() {
const elapsedTime = clock.getElapsedTime();
controls.update();
renderer.render(scene, camera);
labelRenderer.render(scene2, camera)
requestAnimationFrame(render);
}
render();
The effect I want is that the 3D mesh can correctly occlude the CSS3DObject.
I runned over the same problem, I'm trying your code and works good on my project, I think you have a styling problem.
I have separated the WebGL and CSS3DRenderer on the html.
<body>
<div id="css"></div>
<div id="webgl"></div>
</body>
#css,
#webgl
{
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
If I only put the #css on absolute this is the result
If I put both in absolute it works fine.
I wish that'll help

How to project a texture to curved surface?

Screen capture
I tried to make a 3/4 cylinder surface, and I made it from extruting by a ellipe path,
but when I tried to load a texture to the surface, It does not as I exprected: uniformly painted to the surface, it's stretched
I know it's about texture projection, But I dont know how to set options.
class EllipseCurve3 extends THREE.Curve {
ellipse = null
constructor (ellipse) {
super()
this.ellipse = ellipse
}
getPoint(t, optionalTarget = new THREE.Vector3()) {
const point = this.ellipse.getPoint(t, optionalTarget)
return new THREE.Vector3(
point.x,
point.y,
0
)
}
}
// Scene
const scene = new THREE.Scene();
var shape = new THREE.Shape();
shape.moveTo(0, 0);
shape.moveTo(0, 1);
shape.lineTo(50, 1);
shape.moveTo(50, 0);
shape.lineTo(0, 0);
// var curve = new THREE.CatmullRomCurve3([
// new THREE.Vector3(0, 0, 50),
// new THREE.Vector3(-50, 0, 0),
// new THREE.Vector3(0, 0, -50)
// ]);
const arc = new THREE.EllipseCurve(
0,
0, // ax, aY
100,
100, // xRadius, yRadius
0,
1.5 * Math.PI, // aStartAngle, aEndAngle
false, // aClockwise
0 // aRotation
),
path = new EllipseCurve3(arc)
geometry = new THREE.ExtrudeGeometry(shape, {
bevelEnabled: false,
extrudePath: path,
steps: 50,
depth: 5,
amount: 20,
material: 0,
extrudeMaterial: 1
});
// Set up lights
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambientLight);
const axesHelper = new THREE.AxesHelper(500);
scene.add(axesHelper);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.6);
directionalLight.position.set(100, 200, 100); // x, y, z
scene.add(directionalLight);
// Camera
const width = 200;
const height = width * (window.innerHeight / window.innerWidth);
const camera = new THREE.OrthographicCamera(
width / -2, // left
width / 2, // right
height / 2, // top
height / -2, // bottom
0.1, // near
1000 // far
);
camera.position.set(400, 400, 400);
camera.lookAt(0, 0, 0);
// Renderer
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
const controls = new THREE.OrbitControls(camera, renderer.domElement);
renderer.render(scene, camera);
// Add it to HTML
document.body.appendChild(renderer.domElement);
var textureLoader = new THREE.TextureLoader();
textureLoader.crossOrigin = true;
const picture = 'https://threejs.org/examples/textures/uv_grid_opengl.jpg'
textureLoader.load(picture, function(texture) {
// repeat pattern
texture.wrapS = texture.wrapT = THREE.MirroredRepeatWrapping;
// zoom in on pattern
texture.repeat.set(.01, .01);
// assign texture via MeshBasicMaterial
var material = new THREE.MeshBasicMaterial({
map: texture,
needsUpdate: true,
// transparent: true,
// premultipliedAlpha: true,
// side: THREE.DoubleSide,
// blending: THREE.AdditiveBlending
});
// var material = new THREE.MeshPhongMaterial({ color: 0x0048ff });
var mesh = new THREE.Mesh(geometry, material)
mesh.rotation.x = Math.PI / 2
// mesh.rotation.z = Math.PI / 2
scene.add(mesh)
scene.add(cube)
})
function render() {
renderer.render(scene, camera);
// Rotate out group
// svgGroup.rotation.y -= 0.005
controls.update();
requestAnimationFrame(render);
}
render();
Code here
https://codepen.io/mike-xu/pen/RwQeEXJ
"I know it's about texture projection" - It's about computing UV, based on vertices coordinates.
CylinderGeometry also may help to achieve the result you described. With less code, and more convenient and predictable way.
body{
overflow: hidden;
margin: 0;
}
<script type="module">
import * as THREE from "https://cdn.skypack.dev/three#0.136.0";
import {OrbitControls} from "https://cdn.skypack.dev/three#0.136.0/examples/jsm/controls/OrbitControls.js";
console.clear();
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(0, 10, 10);
let renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", event => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
});
let controls = new OrbitControls(camera, renderer.domElement);
scene.add(new THREE.AxesHelper(10));
let g = new THREE.CylinderGeometry(5, 5, 5, 100, 20, true, 0, Math.PI * 1.5);
let m = new THREE.MeshBasicMaterial({
side: THREE.DoubleSide,
map: new THREE.TextureLoader().load(
"https://threejs.org/examples/textures/uv_grid_opengl.jpg",
tex => {
tex.wrapS = tex.wrapT = THREE.MirroredRepeatWrapping;
tex.repeat.set(3, 1);
}
)
});
let c = new THREE.Mesh(g, m);
scene.add(c);
renderer.setAnimationLoop(() => {
renderer.render(scene, camera);
});
</script>

Render transparent bottle in threejs

I have created bottle in blender. If i test it on threejs editor it is giving right results.
But when I render it on my site it is giving
This as output. I am but new to threejs
import './style.css'
import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
const updateAllMaterials = () =>
{
scene.traverse((child) =>
{
if(child instanceof THREE.Mesh)
{
child.material.envMap = environmentMap
child.material.transparent = true
child.material.opacity = 0.1
child.material.envMapIntensity = 5
const material = new THREE.MeshPhysicalMaterial( {
transmission: 1, // use material.transmission for glass materials
opacity: 0.2,
color:"blue",
transparent: true
} );
child.material = material
}
})
}
// Canvas
const canvas = document.querySelector('canvas.webgl')
const gltfLoader = new GLTFLoader()
gltfLoader.load('/models/wine5.glb',(bottle)=>{
bottle.scene.scale.set(0.5,0.45,0.5)
bottle.scene.rotation.set(-0.5,1,0.3)
bottle.scene.position.set(-1,-1.5,2)
updateAllMaterials()
scene.add(bottle.scene)
})
// Scene
const scene = new THREE.Scene()
const axesHelper = new THREE.AxesHelper( 5 );
scene.add( axesHelper );
const directionalLights = new THREE.PointLight('#fff',4)
directionalLights.position.set(-0.4,2,5)
scene.add(directionalLights)
/**
* Sizes
*/
const sizes = {
width: window.innerWidth,
height: window.innerHeight
}
/**
* Camera
*/
// Base camera
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100)
scene.add(camera)
// ENV MAPS
const singleTextureLoader = new THREE.TextureLoader()
singleTextureLoader.load('/BG/tree.jpg',(img)=>{
scene.background = img
})
/**
* Renderer
*/
const renderer = new THREE.WebGLRenderer({
canvas: canvas,
antialias: true
})
renderer.setSize(sizes.width, sizes.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
renderer.physicallyCorrectLights = true
renderer.outputEncoding = THREE.sRGBEncoding
renderer.toneMapping = THREE.ACESFilmicToneMapping
renderer.toneMappingExposure = 1
renderer.depth = false
Your updateAllMaterials() is traversing an empty scene, thus not applying the material to anything. Just swap the calls like this:
scene.add(bottle.scene)
updateAllMaterials()
Also, inside the updateAllMaterials() function, you are changing some parameters of the child's material, and then you overwrite the material itself, losing all the changes.
It should be something like this:
const material = new THREE.MeshPhysicalMaterial({
transmission: 1,
opacity: 0.2,
color:"blue",
transparent: true,
envMap: environmentMap,
transparent: true,
opacity: 0.1,
envMapIntensity: 5
});
child.material = material

How to load texture with transparent background and make it movable?

smile on shirt has black background
smile with transparent true
GOAL: I would like users to be able to add images/colors with buttons
PROBLEM: but the png image texture(smiley face) loaded with textureLoader() has black background and lines crossing the image. :frowning:
MINOR PROBLEM:
(1) Are there any ways to match the background color of the image and the obj/gltf(shirt) that I load?
Here are my codes.
const colorSelection = {
"pink": "#ff2d55",
"purple": "#5856d6",
"blue": "#007aff",
"orange": "#ff9500",
}
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer({ antialias: true });
const loader = new THREE.OBJLoader();
const myCanvas = document.getElementById("container");
const controls = new THREE.OrbitControls(camera, renderer.domElement);
const axisHelper = new THREE.AxisHelper(5);
const hlight = new THREE.AmbientLight (0x404040);
const directionalLight = new THREE.DirectionalLight(0xffffff,0.4);
const geometry = new THREE.SphereGeometry(50,50,50);
const texture = new THREE.TextureLoader().load("assets/smile2.png");
const newMat = new THREE.MeshPhongMaterial({ map: texture });
myCanvas.appendChild( renderer.domElement );
renderer.setSize( 800, 800 );
renderer.setClearColor ("darkgrey", 1);
camera.position.set(200,300,200);
controls.addEventListener("change", animate);
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
};
// SCENES and LIGHTING
scene.add(axisHelper);
scene.add(hlight);
scene.add(directionalLight);
directionalLight.position.set(0,1155,325);
directionalLight.castShadow = true;
function changeTextureColor(color) {
loader.load("assets/standard-t-shirt/source/tshirt.obj", function(obj) {
obj.scale.set(0.4,0.4,0.4)
obj.position.set(0,-500,0)
obj.traverse((child) => {
if (child instanceof THREE.Mesh) {
child.material.emissive = new THREE.Color(colorSelection[color])
console.log(child.material)
}
})
console.log(obj.children)
obj.children[0].material = newMat
scene.add(obj)
})
}
document.querySelectorAll("button").forEach(colorBtn => colorBtn.addEventListener("click", function () {
console.log(this.id)
const userColor = this.id;
changeTextureColor(userColor);
}))
Thanks so much for reading!
You need the transparent: true setting when creating your material, like so:
const newMat = new THREE.MeshPhongMaterial({ map: texture, transparent: true });

Moving an object using three.js

I am very much new to this three.js. I want to create two cubes. I am least interested in its animation. So, i want cube 1 to move towards cube 2 without any keyboard inputs. I am also providing image for better understanding.
Thanks in advance
On possibility to animate objects, is to use THREE.Tween
Create the 2 cubes:
var material1 = new THREE.MeshPhongMaterial({color:'#2020ff'});
var geometry1 = new THREE.BoxGeometry( 1, 1, 1 );
cube1 = new THREE.Mesh(geometry1, material1);
cube1.position.set(0.0, 0.0, 2.0);
var material2 = new THREE.MeshPhongMaterial({color:'#ff2020'});
var geometry2 = new THREE.BoxGeometry( 1, 1, 1 );
cube2 = new THREE.Mesh(geometry2, material2);
cube2.position.set(2.0, 0.0, 0.0);
Create a Tween, which rotates the cube and continuously restarts:
tweenStart = { value: 0 };
var finish = { value: Math.PI/2 };
cubeTween = new TWEEN.Tween(tweenStart);
cubeTween.to(finish, 3000)
cubeTween.onUpdate(function() {
cube1.position.set(0.0, 0.0, 0.0);
cube1.rotation.y = tweenStart.value;
cube1.translateZ( 2.0 );
});
cubeTween.onComplete( function() {
tweenStart.value = 0;
requestAnimationFrame(function() {
cubeTween.start();
});
});
cubeTween.start();
(function onLoad() {
var container, loader, camera, scene, renderer, controls, cube1, cube2, cubeTween, tweenStart;
init();
animate();
animateCube();
function init() {
container = document.getElementById('container');
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
container.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 100);
camera.position.set(0, 6, 0);
camera.lookAt( 0, 0, 0 );
loader = new THREE.TextureLoader();
loader.setCrossOrigin("");
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
scene.add(camera);
window.onresize = resize;
var ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.set(1,2,1.5);
scene.add( directionalLight );
controls = new THREE.OrbitControls(camera);
addGridHelper();
createModel();
}
function createModel() {
var material1 = new THREE.MeshPhongMaterial({color:'#2020ff'});
var geometry1 = new THREE.BoxGeometry( 1, 1, 1 );
cube1 = new THREE.Mesh(geometry1, material1);
cube1.position.set(0.0, 0.0, 2.0);
var material2 = new THREE.MeshPhongMaterial({color:'#ff2020'});
var geometry2 = new THREE.BoxGeometry( 1, 1, 1 );
cube2 = new THREE.Mesh(geometry2, material2);
cube2.position.set(2.0, 0.0, 0.0);
scene.add(cube1);
scene.add(cube2);
tweenStart = { value: 0 };
var finish = { value: Math.PI/2 };
cubeTween = new TWEEN.Tween(tweenStart);
cubeTween.to(finish, 3000)
cubeTween.onUpdate(function() {
cube1.position.set(0.0, 0.0, 0.0);
cube1.rotation.y = tweenStart.value;
cube1.translateZ( 2.0 );
});
cubeTween.onComplete( function() {
tweenStart.value = 0;
requestAnimationFrame(function() {
cubeTween.start();
});
});
cubeTween.start();
}
function addGridHelper() {
var helper = new THREE.GridHelper(100, 100);
helper.material.opacity = 0.25;
helper.material.transparent = true;
scene.add(helper);
var axis = new THREE.AxesHelper(1000);
scene.add(axis);
}
function resize() {
var aspect = window.innerWidth / window.innerHeight;
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = aspect;
camera.updateProjectionMatrix();
}
function animate() {
requestAnimationFrame(animate);
TWEEN.update();
render();
}
function render() {
renderer.render(scene, camera);
}
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.js"></script>
<div id="container"></div>
Alternatively you can slightly change the position of the cube by changing the position property of the cube in the animate function:
function animate() {
requestAnimationFrame(animate);
if ( cube1.position.z > 0.0 ) {
cube1.position.set(0.0, 0.0, cube1.position.z-0.01);
} else if ( cube1.position.x < 2.0 ) {
cube1.position.set(cube1.position.x+0.01, 0.0, 0.0);
} else {
cube1.position.set(0.0, 0.0, 2.0);
}
render();
}
(function onLoad() {
var container, loader, camera, scene, renderer, controls, cube1, cube2, cubeTween, tweenStart;
init();
animate();
animateCube();
function init() {
container = document.getElementById('container');
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
container.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 100);
camera.position.set(0, 6, 0);
camera.lookAt( 0, 0, 0 );
loader = new THREE.TextureLoader();
loader.setCrossOrigin("");
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
scene.add(camera);
window.onresize = resize;
var ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.set(1,2,1.5);
scene.add( directionalLight );
controls = new THREE.OrbitControls(camera);
addGridHelper();
createModel();
}
function createModel() {
var material1 = new THREE.MeshPhongMaterial({color:'#2020ff'});
var geometry1 = new THREE.BoxGeometry( 1, 1, 1 );
cube1 = new THREE.Mesh(geometry1, material1);
cube1.position.set(0.0, 0.0, 2.0);
var material2 = new THREE.MeshPhongMaterial({color:'#ff2020'});
var geometry2 = new THREE.BoxGeometry( 1, 1, 1 );
cube2 = new THREE.Mesh(geometry2, material2);
cube2.position.set(2.0, 0.0, 0.0);
scene.add(cube1);
scene.add(cube2);
}
function addGridHelper() {
var helper = new THREE.GridHelper(100, 100);
helper.material.opacity = 0.25;
helper.material.transparent = true;
scene.add(helper);
var axis = new THREE.AxesHelper(1000);
scene.add(axis);
}
function resize() {
var aspect = window.innerWidth / window.innerHeight;
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = aspect;
camera.updateProjectionMatrix();
}
function animate() {
requestAnimationFrame(animate);
if ( cube1.position.z > 0.0 ) {
cube1.position.set(0.0, 0.0, cube1.position.z-0.01);
} else if ( cube1.position.x < 2.0 ) {
cube1.position.set(cube1.position.x+0.01, 0.0, 0.0);
} else {
cube1.position.set(0.0, 0.0, 2.0);
}
render();
}
function render() {
renderer.render(scene, camera);
}
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<div id="container"></div>
There are a few different ways you could do this.
It will also be easier to answer this by assuming axes and both cube's starting position.
Let's say cube1 position is:
x: 0
y: 0
z: 0
Cube2 position is:
x: 10
y: 20
z: 0
In the render loop, move cube1 along the y-axis until it reaches the same value as cube2 (20), then move cube1 along the x-axis until it reaches cube2 x position. So cube1 would then be sitting on top of cube2. You would need the code to move cube1 to be present, but only run when certain conditions are met.
E.g, only move in the y-axis if cube1.position.y is less than or equal to cube2.position.y
Movement speed can be increased or decreased by changing the increment value. So an update on the y-axis could look like this:
cube1.position.y += 0.1;
This way could be harder to manage though, as you will need to constantly check the cube1 position in relation to cube2, and because the cube needs to move in two directions this could get messy in the long-run.
You can see an example of this update in the loop concept here - https://jsfiddle.net/f2Lommf5/
I would look at using an animation library such as Tween.js or Greensock which in my opinion would be much better suited. You can specify an axis to move along, the start and end position, animation duration and easing. When the animation on the y-axis is complete, you can start the animation on the x-axis.
Some useful links:
Tween.js - http://learningthreejs.com/blog/2011/08/17/tweenjs-for-smooth-animation/
Greensock - http://www.kadrmasconcepts.com/blog/2012/05/29/greensock-three-js/

Resources