<section>
<!-- three.js goes here!	 -->
</section>
canvas {
  vertical-align: bottom;
}

html, body {
  position:  fixed;
  padding: 0;
  margin: 0;
}
// set up a renderer
const renderer = new THREE.WebGLRenderer({
  antialias: true
})
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.setPixelRatio(window.devicePixelRatio)
// THREE colours look like 0x (0x = #)
renderer.setClearColor(0x333333, 1)

// find the element to add the renderer to!
const section = document.querySelector("section")
section.appendChild(renderer.domElement)

// let's create a scene
const scene = new THREE.Scene()

// let's create a camera
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 5000)
camera.position.z = -50
camera.lookAt(scene.position)

// lighting!
const light = new THREE.DirectionalLight(0xffffff, 1)
light.position.set(0, 0, -1)
scene.add(light)

// hold some data about the shapes being added
const shapes = []

//let's add an animation loop!
const animate = function () {
  renderer.render(scene, camera)
  requestAnimationFrame(animate)
  
  camera.position.setZ(camera.position.z + 1)

  
  // rotate the shapes each frame
  shapes.forEach(shape => {
    shape.rotateX(0.01)
//     shape.position.setZ(shape.position.z - 1)
  })
}
//start the animation
animate()

// let's hold a state of hue
let hue = 0

// let's make a function that makes a shape
const createShape = function (x, y) {
  const geometries = [
    new THREE.ConeGeometry(10, 20, 30),
 		new THREE.BoxGeometry(15, 15, 15),
    new THREE.TorusGeometry(5, 3, 16, 100),
    new THREE.SphereGeometry(8, 32, 32)
  ]
  
  const randNumber = Math.floor(Math.random() * geometries.length)
  const geometry = geometries[randNumber]
  
  const emissiveColor = new THREE.Color("hsl(" + hue + ", 100%, 50%)")
  const material = new THREE.MeshLambertMaterial({
    color: 0xffffff,
    emissive: emissiveColor,
  })
  const shape = new THREE.Mesh(geometry, material)
  
  shape.position.set((window.innerWidth / 2) - x, (window.innerHeight / 2) - y, camera.position.z + 500)
  shape.rotateX(0.5)
  shape.rotateZ(0.5)

  // add to scene and the array of shapes
  shapes.push(shape)
  scene.add(shape)
  
  // add 1 to hue each time
  hue = hue + 1
}

// let's add shapes on draw
let isMouseDown = false


document.addEventListener("mousemove", function (event) {
  if (isMouseDown) {
  	createShape(event.pageX, event.pageY)
  }
})

document.addEventListener("mousedown", function () {
  isMouseDown = true
})

document.addEventListener("mouseup", function () {
  isMouseDown = false
})

document.addEventListener("touchmove", function (event) {
  if (isMouseDown) {
  	createShape(event.pageX, event.pageY)
  }
})

document.addEventListener("touchstart", function () {
  isMouseDown = true
})

document.addEventListener("touchend", function () {
  isMouseDown = false
})

window.addEventListener("resize", function () {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()
  renderer.setSize(window.innerWidth, window.innerHeight)
})

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