canvas实现可调参数的下雪积雪粒子动画效果代码

代码语言:html

所属分类:粒子

代码描述:canvas实现可调参数的下雪积雪粒子动画效果代码

代码标签: canvas 参数 下雪 积雪 粒子 动画

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

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

<head>
  <meta charset="UTF-8">
  

  
  
<style>
/*
global
*/
*, *::before, *::after {
    margin: 0;
    padding: 0;
    border: 0;
    box-sizing: border-box;
}

*:focus {
    outline: none;
}

body {
    height: 100vh;
    background-color: #111;
    overflow: hidden;
}

canvas {
    touch-action: none;
}
</style>


  
  
</head>

<body translate="no">
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/Stats-16.js"></script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/dat.gui-min.js"></script>
      <script  >
//---

'use strict';

//---

console.clear();

//---

let stats = null;
let gui = null;

//---

let w = 0;
let h = 0;

let animationFrame = null;
let isTouchDevice = false;

const canvas = document.createElement('canvas');
const context = canvas.getContext('2d', { willReadFrequently: false, alpha: false });

let imageData = null;
let imageDataWidth = 0;
let data = null;

let buffer = null;
let bufferBorder = 0;

const center = { x: w / 2, y: h / 2 };
const border = { left: 0, top: 1, right: w, bottom: h };

let pointer = { x: 0, y: 0 };
let pointerPos = { x: center.x, y: center.y };
let pointerDownButton = -1;
let pointerActive = false;

const pointerMoveTimeoutTime = 2500;

//---

const particlePropertiesAmount = 7;

let particleAmount = 75000;
let particleHolderLength = 0;
let particleHolder = null;
let particleSpeedFactor = 10;
let particlesRGBMax = 255;
let particlesRGBMin = 25;
let particleSpeedFactorSquare = particleSpeedFactor * particleSpeedFactor;

let deltaTime = 0.175; //0.075;

let waveFrequency = 0.005;
let waveAmplitude = 2;
let windStrength = 0.055;

//---

let clearPixelData = null;
let clearRowSize = 0;
let clearRow = null;

let bgColorR = 17;
let bgColorG = 17;
let bgColorB = 17;

//---

let sinTableLength = 0;
let sinTable = null;

//---

function init() {

  isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0;

  //---

  if (isTouchDevice === true) {

    canvas.addEventListener('touchmove', cursorMoveHandler, false);
    canvas.addEventListener('touchend', cursorLeaveHandler, false);
    canvas.addEventListener('touchcancel ', cursorLeaveHandler, false);

  } else {

    canvas.addEventListener('pointermove', cursorMoveHandler, false);
    canvas.addEventListener('pointerdown', cursorDownHandler, false);
    canvas.addEventListener('pointerup', cursorUpHandler, false);
    canvas.addEventListener('pointerleave', cursorLeaveHandler, false);

  }

  //---

  setSinusTable();

  //---

  stats = new Stats();
  stats.domElement.style.position = 'absolute';
  stats.domElement.style.setProperty('display', 'none');

  document.body.appendChild(stats.domElement);

  //---

  document.body.appendChild(canvas);

  window.addEventListener('resize', onResize, false);

  restart();

}

function onResize(event) {

  restart();

}

function restart() {

  const innerWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
  const innerHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;

  //---

  w = innerWidth;
  h = innerHeight;

  //---

  canvas.width = w;
  canvas.height = h;

  imageData = context.getImageData(0, 0, w, h);
  imageDataWidth = imageData.width;
  data = imageData.data;

  buffer = new Uint8Array(w * h);
  buffer.fill(0);

  bufferBorder = h;

  //---

  center.x = w * 0.5;
  center.y = h * 0.5;

  pointerPos.x = center.x;
  pointerPos.y = center.y;
  pointer.x = center.x;
  pointer.y = center.y;

  border.right = w;
  border.bottom = h;

  //---

  setClearImageData();
  setParticles();

  //---

  if (animationFrame != null) {

    cancelAnimFrame(animationFrame);

  }

  render();

}

//---

function initGUI() {

  const updateParticleAmount = () => {

    particleAmount = guiSetting['particle amount'];

    setParticles();

  };

  const updateParticleSpeedFactor = () => {

    particleSpeedFactor = guiSetting['particle speed factor'];

    setParticles();

  };

  const updateParticleDelateTime = () => {

    deltaTime = guiSetting['particle delta time'];

    setParticles();

  };

  const updateParticleWaveFrequency = () => {

    waveFrequency = guiSetting['particle wave frequency'];

    setSinusTable();

  };

  const updateParticleWaveAmplitude = () => {

    waveAmplitude = guiSetting['particle wave amplitude'];

    setSinusTable();

  };

  const updateParticleWindStrength = () => {

    windStrength = guiSetting['particle wind strength'];

    setParticles();

  };

  const removeParticles = () => {

    buffer.fill(0);

  };

  const updateBackgroundColor = () => {

    bgColorR = Math.floor(guiSetting['particle bg'][0]);
    bgColorG = Math.floor(guiSetting['particle bg'][1]);
    bgColorB = Math.floor(guiSetting['particle bg'][2]);

    setClearImageData();

  };

  const updateBrightestParticleColor = () => {

    particlesRGBMax = guiSetting['particle brightest'];

    setParticles();

  };

  const updateDarkestParticleColor = () => {

    particlesRGBMin = guiSetting['particle darkest'];
    console.log(particlesRGBMin);

    setParticles();

  };

  const toggleStats = () => {

    const styleDisplay = getComputedStyle(stats.domElement).getPropertyValue('display').trim();

    if (styleDisplay === 'block') {

      stats.domElement.style.setProperty('display', 'none');

    } else {

      stats.domElement.style.setProperty('display', 'block');

    }

  };

  const linkTo = () => {

    window.open('https://x.com/niklaswebdev', '_parent');

  };

  //---

  const guiSetting = {

    'particle amount': particleAmount,
    'particle speed factor': particleSpeedFactor,
    'particle delta time': deltaTime,
    'particle wave frequency': waveFrequency,
    'particle wave amplitude': waveAmplitude,
    'particle wind strength': windStrength,
    'particle clear': removeParticles,
    'particle bg': [bgColorR, bgColorG, bgColorB],
    'particle brightest': particlesRGBMax,
    'particle darkest': particlesRGBMin,
    'toggle stats': toggleStats,
    '@niklaswebdev': linkTo };



  //---

  gui = new dat.GUI({ width: 320 });
  gui.add(guiSetting, 'particle amount').min(1000).max(500000).step(1).onChange(updateParticleAmount);
  gui.add(guiSetting, 'particle speed factor').min(1).max(100).step(1).onChange(updateParticleSpeedFactor);
  gui.add(guiSetting, 'particle delta time')..........完整代码请登录后点击上方下载按钮下载查看

网友评论0