2 823 Codepen

Новогодняя ёлка на канвасе

Новогодняя ёлка на канвасе с помощью three.js



HTML

<div id="canvas"></div>

SCSS

body {
  margin: 0;
  padding: 0;
  overflow: hidden;
  background: #101011;
  box-sizing: border-box;
  width: 100vw;
  height: 100vh;
}

#canvas {
  position: absolute;
  width: 100vw;
  height: 100vh;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

button {
  position: absolute;
  bottom: -0.8rem;
  left: 50%;
  transform: translate(-50%, -50%);
    margin: .5em;
    border: solid .375em transparent;
    padding: calc(.375em + 2px);
  width: 13vh;
  min-width: 2.5em;
  height: 13vh;
  min-height: 2.5em;
    border-radius: 50%;
  box-shadow: inset 0 0 0 2.75px #a961b8;
  background: purple;
  color: white;
  background: 
linear-gradient(#523535, #211b20) padding-box,
        linear-gradient(#211b20, #523535) border-box;
    transition: .75s;
  cursor: pointer;
  opacity: 0.0;
  outline: solid 0 transparent;
}
    
button:hover {
  outline: solid 0 transparent;
  filter: saturate(120%) brightness(180%);
}
    
button:active {
  outline: solid 0 transparent;
    border-width: calc(.375em + 4px) .375em calc(.375em - 4px);
}

@media(max-width: 768px) {
  button {
    width: 5em;
    height: 5em;
  }
}

JS

Необходимо подключить three.js
https://cdnjs.cloudflare.com/ajax/libs/three.js/109/three.min.js
https://s3-us-west-2.amazonaws.com/s.cdpn.io/264161/OrbitControls.js
скрипт
/*--------------------
Settings
--------------------*/
let container, camera, scene, artwork, renderer
let windowHalfX = window.innerWidth / 2
let windowHalfY = window.innerHeight / 2


/*--------------------
Map
--------------------*/
const map = (value, x1, y1, x2, y2) => (value - x1) * (y2 - x2) / (y1 - x1) + x2;


/*--------------------
Resize
--------------------*/
const onWindowResize = () => {
  camera.aspect = container.clientWidth / container.clientHeight
  camera.updateProjectionMatrix()
  renderer.setSize( container.clientWidth, container.clientHeight )
}


/*--------------------
Init
--------------------*/
init = () => {
  container = document.querySelector( "#canvas" )
  scene = new THREE.Scene()
  createCamera()
  createControls()
  createLights()
  createMeshes()
  createRenderer()
  document.addEventListener( "mousemove", mouseMove, false )
  window.addEventListener( "resize", onWindowResize )
  renderer.setAnimationLoop(() => {
    render()
  })
}


/*--------------------
Camera
--------------------*/
createCamera = () => {
  camera = new THREE.PerspectiveCamera(
    40,
    window.innerWidth / window.innerHeight,
    0.1,
    10000,
  )
  camera.position.set( -25, 5, 20 )
}


/*--------------------
Controls
--------------------*/
function createControls() {
  controls = new THREE.OrbitControls( camera, container )
  controls.enabled = false
}


/*--------------------
Lights
--------------------*/
const createLights = () => {
  const ambientLight = new THREE.HemisphereLight( 0xddeeff, 0x202020, 5 )
  scene.add( ambientLight )
}


/*--------------------
Geometry
--------------------*/
const extraGeometry = () => {
  let geometry = new THREE.Geometry();
  const particlesLength = 2000
  
  for ( var i = 0; i < particlesLength; i++ ) {
    var vertex = new THREE.Vector3()
    var color = new THREE.Vector3()
    const d = map(i, 0, particlesLength, 0, Math.PI * 20)
    vertex.x = i * 0.003 * Math.sin(d)
    vertex.y = - i * 0.008 + (Math.sin(i * 3+ i * 0.5) * 0.2 )
    vertex.z = i * 0.003 * Math.cos(d)
    geometry.vertices.push( vertex )
    geometry.colors.push( 
      new THREE.Color( '#952300' ),
      new THREE.Color( '#dc1c27' ),
      new THREE.Color( '#135c13' ),
      new THREE.Color( '#fca12e' ),
       )
  }
  
  let particles = new THREE.Points( geometry, new THREE.PointsMaterial({ vertexColors: THREE.VertexColors, size: 0.1 }))
  let extraGroup = new THREE.Group()
  extraGroup.add( particles )
  return extraGroup
}


/*--------------------
Mesh
--------------------*/
const createMeshes = () => {
  const sparklyBall = extraGeometry()
  artwork = new THREE.Group()
  artwork.position.y = 9
  artwork.add(
    sparklyBall
  );
  scene.add( artwork )
}


/*--------------------
Animate
--------------------*/
const animate = () => {
    requestAnimationFrame(animate)
}
animate()


/*--------------------
Renderer
--------------------*/
const createRenderer = () => {
  renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } )
  renderer.setSize( window.innerWidth, window.innerHeight )
  renderer.setPixelRatio( window.devicePixelRatio )
  
  renderer.gammaFactor = 2.2
  renderer.gammaOutput = true
  renderer.physicallyCorrectLights = true
  container.appendChild( renderer.domElement )
}


/*--------------------
Mousemove
--------------------*/
let mouseX = mouseY = 1
const mouseMove = ( event ) => {
  isMouseMoved = true;
    mouseX = ( event.clientX - windowHalfX );
    mouseY = ( event.clientY - windowHalfY );
}


/*--------------------
Render
--------------------*/
const render = () => {
  if ( artwork ) {
     artwork.rotation.y += 0.001
    }
  renderer.render( scene, camera )
}
init()

Комментарии

  • Facebook
  • Вконтакте

Похожие статьи