three打造一个三维小鱼跟随鼠标游动效果代码

代码语言:html

所属分类:三维

代码描述:three打造一个三维小鱼跟随鼠标游动效果代码

代码标签: 三维 小鱼 跟随 鼠标 游动 效果

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>

  <meta charset="UTF-8">
  


  
  
<style>
@import url(https://fonts.googleapis.com/css?family=Open+Sans:800);

#world{
  background: linear-gradient(#8ee4ae, #e9eba3);
  position:absolute;
  width:100%;
  height:100%;
  overflow:hidden;
}
#instructions{
  position:absolute;
  width:100%;
  top:50%;
  margin: auto;
  margin-top:80px;
  font-family:'Open Sans', sans-serif;
  color:#71b583;
  font-size:1.2em;
  text-transform: uppercase;
  text-align : center;
}

#credits{
  position:absolute;
  width:100%;
  margin: auto;
  bottom:0;
  margin-bottom:20px;
  font-family:'Open Sans', sans-serif;
  color:#71b583;
  font-size:0.7em;
  text-transform: uppercase;
  text-align : center;
}
#credits a {
  color:#71b583;
}
</style>




</head>

<body >
  <div id="world"></div>
<div id="instructions">Move your mouse <br/>to change speed and direction</div>


 
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/stats-min.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.72.js"></script>

      <script>
//THREEJS RELATED VARIABLES 

var scene,
camera,
fieldOfView,
aspectRatio,
nearPlane,
farPlane,
shadowLight,
light,
renderer,
container;

//SCREEN VARIABLES 
var HEIGHT,
WIDTH,
windowHalfX,
windowHalfY,
xLimit,
yLimit;

// FISH BODY PARTS
var fish,
bodyFish,
tailFish,
topFish,
rightIris,
leftIris,
rightEye,
leftEye,
lipsFish,
tooth1,
tooth2,
tooth3,
tooth4,
tooth5;

// FISH SPEED
// the colors are splitted into rgb values to facilitate the transition of the color
var fishFastColor = { r: 255, g: 0, b: 224 }; // pastel blue
fishSlowColor = { r: 0, g: 207, b: 255 }; // purple
angleFin = 0; // angle used to move the fishtail

// PARTICLES COLORS
// array used to store a color scheme to randomly tint the particles 
var colors = ['#dff69e',
'#00ceff',
'#002bca',
'#ff00e0',
'#3f159f',
'#71b583',
'#00a2ff'];

// PARTICLES
// as the particles are recycled, I use 2 arrays to store them
// flyingParticles used to update the flying particles and waitingParticles used to store the "unused" particles until we need them;
var flyingParticles = [];
waitingParticles = [];
// maximum z position for a particle
maxParticlesZ = 600;

// SPEED
var speed = { x: 0, y: 0 };
var smoothing = 10;

// MISC
var mousePos = { x: 0, y: 0 };
var stats;
var halfPI = Math.PI / 2;


function init() {
  // To work with THREEJS, you need a scene, a camera, and a renderer

  // create the scene;
  scene = new THREE.Scene();

  // create the camera
  HEIGHT = window.innerHeight;
  WIDTH = window.innerWidth;
  aspectRatio = WIDTH / HEIGHT;
  fieldOfView = 60;
  nearPlane = 1; // the camera won't "see" any object placed in front of this plane
  farPlane = 2000; // the camera wont't see any object placed further than this plane
  camera = new THREE.PerspectiveCamera(
  fieldOfView,
  aspectRatio,
  nearPlane,
  farPlane);
  camera.position.z = 1000;


  //create the renderer 
  renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
  renderer.setSize(WIDTH, HEIGHT);
  container = document.getElementById('world');
  container.appendChild(renderer.domElement);

  /*
  As I will recycle the particles, I need to know the left and right limits they can fly without disappearing from the camera field of view.
  As soon as a particle is out of the camera view, I can recycle it : remove it from the flyingParticles array and push it back in the waitingParticles array.
  I guess I can do that by raycasting each particle each frame, but I think this will be too heavy. Instead I prefer to precalculate the x coordinate from which a particle is not visible anymore. But this depends on the z position of the particle.
  Here I decided to use the furthest possible z position for a particle, to be sure that all the particles won't be recycled before they are out of the camera view. But this could be much more precise, by precalculating the x limit for each particle depending on its z position and store it in the particle when it is "fired". But today, I'll keep it simple :) 
  !!!!!! I'm really not sure this is the best way to do it. If you find a better solution, please tell me  
  */

  // convert the field of view to radians
  var ang = fieldOfView / 2 * Math.PI / 180;
  // calculate the max y position seen by the camera related to the maxParticlesZ position, I start by calculating the y limit because fielOfView is a vertical field of view. I then calculate the x Limit
  yLimit = (camera.position.z + maxParticlesZ) * Math.tan(ang); // this is a formula I found, don't ask me why it works, it just does :) 
  // Calculate the max x position seen by the camera related to the y Limit position
  xLimit = yLimit * camera.aspect;

  // precalculate the center of the screen, used to update the speed depending on the mouse position
  windowHalfX = WIDTH / 2;
  windowHalfY = HEIGHT / 2;


  // handling resize and mouse move events
  window.addEventListener('resize', onWindowResize, false);
  document.addEventListener('mousemove', handleMouseMove, false);
  // let's make it work on mobile too
  document.addEventListener('touchstart', handleTouchStart, false);
  document.addEventListener('touchend', handleTouchEnd, false);
  document.addEventListener('touchmove', handleTouchMove, false);
}

function onWindowResize() {
  HEIGHT = window.innerHeight;
  WIDTH = window.innerWidth;
  windowHalfX = WIDTH / 2;
  windowHalfY = HEIGHT / 2;
  renderer.setSize(WIDTH, HEIGHT);
  camera.aspect = WIDTH / HEIGHT;
  camera.updateProjectionMatrix(); // force the camera to update its aspect ratio
  // recalculate the limits
  var ang = fieldOfView / 2 * Math.PI / 180;
  yLimit = (camera.position.z + maxPartcilesZ) * Math.tan(ang);
  xLimit = yLimit * camera.aspect;
}

function handleMouseMove(event) {
  mousePos = { x: event.clientX, y: event.clientY };
  updateSpeed();
}

function handleTouchStart(event) {
  if (event.touches.length > 1) {
    event.preventDefault();
    mousePos = { x: event.touches[0].pageX, y: event.touches[0].pageY };
    updateSpeed();
  }
}

function handleTouchEnd(event) {
  mousePos = { x: windowHalfX, y: windowHalfY };
  updateSpeed();
}

function handleTouchMove(event) {
  if (event.touches.length == 1) {
    event.preventDefault();
    mousePos = { x: event.touches[0].pageX, y: event.touches[0].pageY };
    updateSpeed();
  }
}

function updateSpeed() {
  speed.x = mousePos.x / WIDTH * 100;
  speed.y = (mousePos.y - windowHalfY) / 10;
}

function loop() {

  // Update fish position, rotation, scale... depending on the mouse position
  // To make a smooth update of each value I use this formula :
  // currentValue += (targetValue - currentValue) / smoothing

  // make the fish swing according to the mouse direction
  fish.rotation.z += (-speed.y / 50 - fish.rotation.z) / smoothing;
  fish.rotation.x += (-speed.y / 50 - fish.rotation.x) / smoothing;
  fish.rotation.y += (-speed.y / 50 - fish.rotation.y) / smoothing;

  // make the fish move according to the mouse direction
  fish.position.x += (mousePos.x - windowHalfX - fish.position.x) / smoothing;
  fish.position.y += (-speed.y * 10 - fish.position.y) / smoothing;

  // make the eyes follow the mouse direction
  rightEye.rotation.z = leftEye.rotation.z = -speed.y / 150;
  rightIris.position.x = leftIris.position.y = -10 - speed.y / 2;

  // make it look angry when the speed increases by narrowing the eyes
  rightEye.scale.set(1, 1 - speed.x / 150, 1);
  leftEye.scale.set(1, 1 - speed.x / 150, 1);

  // in order to optimize, I precalculate a smaller speed values depending on speed.x
  // these variables will be used to update the wagging of the tail, the color of the fish and the scale of the fish
  var s2 = speed.x / 100; // used for the wagging speed and color 
  var s3 = speed.x / 300; // used for the scale

  // I use an angle that I increment, and then use its cosine and sine to make the tail wag in a cyclic movement. The speed of the wagging depends on the global speed
  angleFin += s2;
  // for a better optimization, precalculate sine and cosines
  var backTailCycle = Math.cos(angleFin);
  var sideFinsCycle = Math.sin(angleFin / 5);

  tailFish.rotation.y.........完整代码请登录后点击上方下载按钮下载查看

网友评论0