WEBデザインの勉強

初心者が1からWEBデザインを勉強するブログ。

Canvasを使って雪を降らせるSnow in 3D

f:id:mmmmofu:20161130201533p:plain

マウスを動かすと立体的に移動する。

HTML

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>JavaScript HTML5 Canvas Snow in 3D</title>
  <style>
    body {
      background-color: #000;
      color:#fff;
    }
    #snow_canvas{
      z-index: 30000000000000;
      position: fixed;
      top:0;
      left: 0;
    }
  </style>
  <script src="js/ThreeCanvas.js"></script>
  <script src="js/Snow.js"></script>
  <script src="js/script.js"></script>
</head>
<body>

</body>
</html>

JS

var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;

var container;
var particle;
var camera;
var scene;
var renderer;

var mouseX = 0;
var mouseY = 0;
var snownum = 500;

var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;

var particles = [];
var particleImage = new Image();
particleImage.src = 'http://efu.sakura.ne.jp/web/snow3/img/ParticleSmoke.png'; //雪の画像

function init() {
  container = document.createElement('div');
  //自動で作成されるdiv要素にid追加
  container.id = 'snow_canvas';
  document.body.appendChild(container);
  camera = new THREE.PerspectiveCamera( 75, SCREEN_WIDTH / SCREEN_HEIGHT, 1, 10000 );
  camera.position.z = 1000;

  scene = new THREE.Scene();
  scene.add(camera);

  renderer = new THREE.CanvasRenderer();
  renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
  var material = new THREE.ParticleBasicMaterial( { map: new THREE.Texture(particleImage) } );

  for (var i = 0; i < snownum; i++) {
    particle = new Particle3D( material);
    particle.position.x = Math.random() * 2000 - 1000;
    particle.position.y = Math.random() * 2000 - 1000;
    particle.position.z = Math.random() * 2000 - 1000;
    particle.scale.x = particle.scale.y =  1;
    scene.add( particle );

    particles.push(particle);
  }

  container.appendChild( renderer.domElement );

  //マウスクリックでcanvasを削除するイベント登録
  container.addEventListener( 'click', function(){container.parentNode.removeChild(container)}, false );
  container.addEventListener( 'touchstart', function(){container.parentNode.removeChild(container)}, false );
  container.addEventListener( 'mousemove', onDocumentMouseMove, false );
  container.addEventListener( 'touchstart', onDocumentTouchStart, false );
  container.addEventListener( 'touchmove', onDocumentTouchMove, false );
  setInterval( loop, 1000 / 60 );

}

function onDocumentMouseMove( event ) {
  mouseX = event.clientX - windowHalfX;
  mouseY = event.clientY - windowHalfY;
}

function onDocumentTouchStart( event ) {
  if ( event.touches.length == 1 ) {
    event.preventDefault();
    mouseX = event.touches[ 0 ].pageX - windowHalfX;
    mouseY = event.touches[ 0 ].pageY - windowHalfY;
  }
}

function onDocumentTouchMove( event ) {
  if ( event.touches.length == 1 ) {
    event.preventDefault();
    mouseX = event.touches[ 0 ].pageX - windowHalfX;
    mouseY = event.touches[ 0 ].pageY - windowHalfY;
  }
}

function loop() {

  for(var i = 0; i<particles.length; i++)
  {
    var particle = particles[i];
    particle.updatePhysics();

    with(particle.position)
    {
      if(y<-1000) y+=2000;
      if(x>1000) x-=2000;
      else if(x<-1000) x+=2000;
      if(z>1000) z-=2000;
      else if(z<-1000) z+=2000;
    }
  }

  camera.position.x += ( mouseX - camera.position.x ) * 0.05;
  camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
  camera.lookAt(scene.position);

  renderer.render( scene, camera );


}
//initの呼び出し
if (window.addEventListener) {
  window.addEventListener("load", init, false);
} else if (window.attachEvent) {
  window.attachEvent("onload", init);
} else  {
  window.onload = init;
}


雪の画像はアップロードしたものを使用しないとエラーになった。