<canvas id="canvas"></canvas>
* {
	box-sizing: border-box;
}

body {
	margin: 0;
}
const canvas = document.querySelector('#canvas')
const scene = new THREE.Scene()
const width = window.innerWidth
const height = window.innerHeight
const camera = new THREE.PerspectiveCamera(50, width / height, 40, 500)
const renderer = new THREE.WebGLRenderer({ canvas })

renderer.setSize(window.innerWidth, window.innerHeight)
camera.position.z = 150

/* Light */
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.85)
// const ambientLight = new THREE.AmbientLight(0x98e0eb, 0.2)
directionalLight.position.set(-1, 2, 4)

scene.add(directionalLight)
// scene.add(ambientLight)
scene.background = new THREE.Color(0x1a2330)

const geometry = new THREE.SphereGeometry(15, 32, 12)

/* Shape */
const createSphere = (x = 0, y = 5, z = 5, t = 'https://assets.codepen.io/85648/piers%401x.jpg') => {
	const texture = new THREE.TextureLoader().load(t)
	const material = new THREE.MeshLambertMaterial({ map: texture })
	const shape = new THREE.Mesh(geometry, material)
	console.log(material)
	
	shape.position.x = x
	shape.position.y = y
	shape.position.z = z
	
	
	scene.add(shape)
	
	return shape
}

const spheres = [
	createSphere(25, 5, 0, 'https://assets.codepen.io/85648/piers%401x.jpg'),
	createSphere(-40, 35, -80, 'https://assets.codepen.io/85648/ben%401x.jpg'),
	createSphere(-80, -35, 5, 'https://assets.codepen.io/85648/michelle%401x.jpg'),
	createSphere(60, -20, -25, 'https://assets.codepen.io/85648/duncan%401x.jpg'),
	createSphere(-100, 85, -150, 'https://assets.codepen.io/85648/megan%401x.jpg'),
	createSphere(-110, 10, 5, 'https://assets.codepen.io/85648/joana%401x.jpg'),
	createSphere(-60, 5, -10, 'https://assets.codepen.io/85648/colin%401x_1.jpg'),
	createSphere(70, -10, 0, 'https://assets.codepen.io/85648/jade%401x.jpg'),
	createSphere(30, 0, -20, 'https://assets.codepen.io/85648/conor%401x.jpg'),
	createSphere(90, 0, 20, 'https://assets.codepen.io/85648/steve%401x.jpg'),
	createSphere(-130, -20, -20, 'https://assets.codepen.io/85648/matt%401x.jpg'),
	createSphere(2, -5, 15, 'https://assets.codepen.io/85648/aidan.png'),
	createSphere(40, -10, 20, 'https://assets.codepen.io/85648/kate.png'),
	createSphere(0, -25, -5, 'https://assets.codepen.io/85648/david%401x_1.jpg')
]


spheres.forEach((el, i) => {
	const { y } = el.position
	gsap.to(el.rotation, { duration: 15, y: Math.PI * 2, repeat: -1, ease: "none" })
	gsap.to(el.position, { duration: 2, y: y + 40, repeat: -1, yoyo: true, ease: "power1.out", delay: i * 0.1 })
})


function animate() {
	requestAnimationFrame(animate)
	renderer.render(scene, camera);
}

animate()

/* Render */
// renderer.render(scene, camera)

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/three.js/r119/three.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/gsap/3.4.2/gsap.min.js