圣诞树灯光跟随音乐节拍一起呼吸点亮下雪动画效果代码

代码语言:html

所属分类:动画

代码描述:圣诞树灯光跟随音乐节拍一起呼吸点亮下雪动画效果代码

代码标签: 音乐 节拍 一起 呼吸 点亮 下雪 动画 效果

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

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

<head>

  <meta charset="UTF-8">


  
  
<style>
* {
  box-sizing: border-box;
}

body {
  margin: 0;
  height: 100vh;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #161616;
  color: #c5a880;
  font-family: sans-serif;
}

label {
  display: inline-block;
  background-color: #161616;
  padding: 16px;
  border-radius: 0.3rem;
  cursor: pointer;
  margin-top: 1rem;
  width: 300px;
  border-radius: 10px;
  border: 1px solid #c5a880;
  text-align: center;
}

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
}

.btn {
  background-color: #161616;
  border-radius: 10px;
  color: #c5a880;
  border: 1px solid #c5a880;
  padding: 16px;
  width: 300px;
  margin-bottom: 16px;
  line-height: 1.5;
  cursor: pointer;
}
.separator {
  font-weight: bold;
  text-align: center;
  width: 300px;
  margin: 16px 0px;
  color: #a07676;
}

.title {
  color: #a07676;
  font-weight: bold;
  font-size: 1.25rem;
  margin-bottom: 16px;
}

.text-loading {
  font-size: 2rem;
}
</style>


</head>

<body  >
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.r118.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/EffectComposer.110.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/RenderPass.110.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/ShaderPass.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/CopyShader.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/LuminosityHighPassShader.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/UnrealBloomPass.110.js"></script>

<div id="overlay">
  <ul>
    <li class="title">选择圣诞背景音乐</li>
   
    <li><button class="btn" id="btnD" type="button">Jingle Bell </button></li>
    <li class="separator">或者</li>
    <li>
      <input type="file" id="upload" hidden />
      <label for="upload">上传音乐</label>
    </li>
  </ul>
</div>

  
      <script >
const { PI, sin, cos } = Math;
const TAU = 2 * PI;

const map = (value, sMin, sMax, dMin, dMax) => {
  return dMin + (value - sMin) / (sMax - sMin) * (dMax - dMin);
};

const range = (n, m = 0) =>
Array(n).
fill(m).
map((i, j) => i + j);

const rand = (max, min = 0) => min + Math.random() * (max - min);
const randInt = (max, min = 0) => Math.floor(min + Math.random() * (max - min));
const randChoise = arr => arr[randInt(arr.length)];
const polar = (ang, r = 1) => [r * cos(ang), r * sin(ang)];

let scene, camera, renderer, analyser;
let step = 0;
const uniforms = {
  time: { type: "f", value: 0.0 },
  step: { type: "f", value: 0.0 } };

const params = {
  exposure: 1,
  bloomStrength: 0.9,
  bloomThreshold: 0,
  bloomRadius: 0.5 };

let composer;

const fftSize = 2048;
const totalPoints = 4000;

const listener = new THREE.AudioListener();

const audio = new THREE.Audio(listener);

document.querySelector("input").addEventListener("change", uploadAudio, false);

const buttons = document.querySelectorAll(".btn");
buttons.forEach((button, index) =>
button.addEventListener("click", () => loadAudio(index)));


function init() {
  const overlay = document.getElementById("overlay");
  overlay.remove();

  scene = new THREE.Scene();
  renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  camera = new THREE.PerspectiveCamera(
  60,
  window.innerWidth / window.innerHeight,
  1,
  1000);

  camera.position.set(-0.09397456774197047, -2.5597086635726947, 24.420789670889008);
  camera.rotation.set(0.10443543723052419, -0.003827152981119352, 0.0004011488708739715);

  const format = renderer.capabilities.isWebGL2 ?
  THREE.RedFormat :
  THREE.LuminanceFormat;

  uniforms.tAudioData = {
    value: new THREE.DataTexture(analyser.data, fftSize / 2, 1, format) };


  addPlane(scene, uniforms, 3000);
  addSnow(scene, uniforms);

  range(10).map(i => {
    addTree(scene, uniforms, totalPoints, [20, 0, -20 * i]);
    addTree(scene, uniforms, totalPoints, [-20, 0, -20 * i]);
  });

  const renderScene = new THREE.RenderPass(scene, camera);

  const bloomPass = new THREE.UnrealBloomPass(
  new THREE.Vector2(window.innerWidth, window.innerHeight),
  1.5,
  0.4,
  0.85);

  bloomPass.threshold = params.bloomThreshold;
  bloomPass.strength = params.bloomStrength;
  bloomPass.radius = params.bloomRadius;

  composer = new THREE.EffectComposer(renderer);
  composer.addPass(renderScene);
  composer.addPass(bloomPass);

  addListners(camera, renderer, composer);
  animate();
}

function animate(time) {
  analyser.getFrequencyData();
  uniforms.tAudioData.value.needsUpdate = true;
  step = (step + 1) % 1000;
  uniforms.time.value = time;
  uniforms.step.value = step;
  composer.render();
  requestAnimationFrame(animate);
}

function loadAudio(i) {
  document.getElementById("overlay").innerHTML =
  '<div class="text-loading">Please Wait...</div>';
  const files = [

  "//repo.bfw.wiki/bfwrepo/sound/5fe5680792ceb.mp3"];

  const file = files[i];

  const loader = new THREE.AudioLoader();
  loader.load(file, function (buffer) {
    audio.setBuffer(buffer);
    audio.play();
    analyser = new THREE.AudioAnalyser(audio, fftSize);
    init();
  });




}


function uploadAudio(event) {
  document.getElementById("overlay").innerHTML =
  '<div class="text-loading">Please Wait...</div>';
  const files = event.target.files;
  const reader = new FileReader();

  reader.onload = function (file) {
    var arrayBuffer = file.target.result;

    listener.context.decodeAudioData(arrayBuffer, function (audioBuffer) {
      audio.setBuffer(audioBuffer);
      audio.play();
      analyser = new THREE.AudioAnalyser(audio, fftSize);
      init();
    });
  };

  reader.readAsArrayBuffer(files[0]);
}

function addTree(scene, uniforms, totalPoints, treePosition) {
  const vertexShader = `
  attribute float mIndex;
  varying vec3 vColor;
  varying float opacity;
  uniform sampler2D tAudioData;

  float norm(float value, float min, float max ){
      return (value - min) / (max - min);
  }
  float lerp(float norm, float min, float max){
  return (max - min) * norm + min;
  }

  float map(float value, float sourceMin, float sourceMax, float destMin, float destMax){
  return lerp(norm(value, sourceMin, sourceMax), destMin, destMax);
  }


  void main() {
      vColor = color;
      vec3 p = position;
      vec4 mvPosition = modelViewMatrix * vec4( p, 1.0 );
      float amplitude = texture2D( tAudioData, vec2( mIndex, 0.1 ) ).r;
      float amplitudeClamped = clamp(amplitude-0.4,0.0, 0.6 );
      float sizeMapped = map(amplitudeClamped, 0.0, 0.6, 1.0, 20.0);
      opacity = map(mvPosition.z , -200.0, 15.0, 0.0, 1.0);
      gl_PointSize = sizeMapped * ( 100.0 / -mvPosition.z );
      gl_Position = projectionMatrix * mvPosition;
  }
`;
  const fragmentShader = `
  varying vec3 vColor;
  varying float opacity;
  uniform sampler2D pointTexture;
  void main() {
      gl_FragColor = vec4( vColor, opacity );
      gl_FragColor = gl_FragColor * texture2D( pointTexture, gl_PointCoord ); 
  }
  `;
  .........完整代码请登录后点击上方下载按钮下载查看

网友评论0