【HTML泡泡特效】——效果+代码

效果


代码

DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title>泡泡特效title>
head>
<body>
  <script  src="js/script.js">script>
body>
html>
"use strict";
window.addEventListener("load",function() {

  let idAnim;

  const initSpeed = 1;
  const rMin = 15;
  const rMax = 55;
  let canv, ctx;   
  let maxx, maxy;  
  let particles;
  let click;
  let initDir;
  let noiseInitDir;
  let initHue;
  let noiseInitHue;
  let mouseX = -100, mouseY = -100; 

function Mash() {
	var n = 0xefc8249d;
	var mash = function(data) {
		if ( data ) {
			data = data.toString();
			for (var i = 0; i < data.length; i++) {
				n += data.charCodeAt(i);
				var h = 0.02519603282416938 * n;
				n = h >>> 0;
				h -= n;
				h *= n;
				n = h >>> 0;
				h -= n;
				n += h * 0x100000000; 
			}
			
		}
	};
  
}
  const mrandom = Math.random;
  const mfloor = Math.floor;
  const mround = Math.round;
  const mceil = Math.ceil;
  const mabs = Math.abs;
  const mmin = Math.min;
  const mmax = Math.max;

  const mPI = Math.PI;
  const mPIS2 = Math.PI / 2;
  const m2PI = Math.PI * 2;
  const msin = Math.sin;
  const mcos = Math.cos;
  const matan2 = Math.atan2;

  const mhypot = Math.hypot;
  const msqrt = Math.sqrt;

  const rac3   = msqrt(3);
  const rac3s2 = rac3 / 2;
  const mPIS3 = Math.PI / 3;

  function alea (min, max) {
    if (typeof max == 'undefined') return min * mrandom();
    return min + (max - min) * mrandom();
  }

  function intAlea (min, max) {

    if (typeof max == 'undefined') {
      max = min; min = 0;
    }
    return mfloor(min + (max - min) * mrandom());
  } 
  function NoiseGen(rndFunc, period, nbHarmonics, attenHarmonics, lowValue = 0, highValue = 1) {

  let arP0 = []; 
  let arP1 = [];  
  let amplitudes = []; 
  let increments = []; 
  let phases = [];
  let globAmplitude = 0;
  if (!rndFunc) rndFunc = Math.random; rndFunc
  if (nbHarmonics < 1) nbHarmonics = 1;

  for (let kh = 1; kh <= nbHarmonics; ++ kh) {
    arP0[kh] = rndFunc();
    arP1[kh] = rndFunc();
    amplitudes[kh] = (kh == 1) ? 1 : (amplitudes[kh - 1] * attenHarmonics);
    globAmplitude += amplitudes[kh];
    increments[kh] = kh / period;
    phases[kh] = rndFunc();
  } 

  amplitudes.forEach ((value, kh) => amplitudes[kh] = value / globAmplitude * (highValue - lowValue))

  return function () {
    let pf, pfl;
    let signal = 0;
    for (let kh = nbHarmonics; kh >= 1; --kh) {
      pf = phases[kh] += increments[kh];
      if (phases[kh] >= 1) {
        pf = phases[kh] -= 1;
        arP0[kh] = arP1[kh];
        arP1[kh] = rndFunc();
      } 
      pfl = pf * pf * (3 - 2 * pf); // always 0..1, but smoother
      signal += (arP0[kh] * (1 - pfl) + arP1[kh] * pfl) * amplitudes[kh];
    }
    return signal + lowValue;
  } 
  } 
  function intermediate (p0, p1, alpha) {

    return [(1 - alpha) * p0[0] + alpha * p1[0],
            (1 - alpha) * p0[1] + alpha * p1[1]];
  } 
  function distance (p0, p1) {


    return mhypot (p0[0] - p1[0], p0[1] - p1[1]);

  } 
  function randomElement(array) {
    return array[intAlea(array.length)];
  } 
  function removeElement(array, element) {
    let idx = array.indexOf(element);
    if (idx == -1) throw ('Bug ! indexOf -1 in removeElement');
    array.splice(idx, 1);
  } 
function clonePoint(p) {
  return [p[0],p[1]];
}
function Particle () {

  let hue = (initHue + alea(-40,40)) % 360;

  this.x = maxx / 2;
  this.y = maxy / 2;
  this.dir = initDir + alea(-mPI / 10, mPI / 10);

  this.speed = initSpeed * alea(0.8, 1.4);

  this.genddir = NoiseGen(null, 100, 2, 0.8, -0.03, 0.03);

  this.genR = NoiseGen(null, 100, 1, 0, rMin, rMax);
  this.r0 = this.genR();
  this.r = 0.1;

  this.color1 = `hsl(${hue},100%,50%)`;
  this.color2 = `hsl(${hue},100%,80%)`;
  this.state = 0; // growth

}
Particle.prototype.move = function () {

  this.dir = (this.dir + this.genddir()) % m2PI;
  this.speed += 0.01;

  this.x += this.speed * mcos(this.dir);
  this.y += this.speed * msin(this.dir);

  if (this.y < -this.r || this.y > maxy + this.r || this.x < -this.r || this.x > maxx + this.r) return false;

  if (this.state != 2) { 
    let dx = mouseX - this.x;
    let dy = mouseY - this.y;
    if (mhypot (dx, dy) <= this.r) {
      this.state = 2;
      this.r1 = 0;
    }
  }
  switch (this.state) {
    case 0 : this.r += 0.2;
             if (this.r > this.r0 ) this.state = 1;
             break;
    case 1 : this.r = this.genR();
             break;
    case 2 : this.r += 1;
             this.r1 += 4; 
             if (this.r1 > this.r) return false;
    }
  return true;
}
Particle.prototype.draw = function () {

if (this.state != 2) {
  ctx.beginPath();
  ctx.arc(this.x, this.y,this.r,0,m2PI);
  ctx.fillStyle = this.color1;
  ctx.fill();
  ctx.beginPath();
  ctx.arc(this.x + this.r / 3.5, this.y - this.r / 3.5 ,this.r / 2,0,m2PI);
  ctx.fillStyle = this.color2;
  ctx.fill();

} else {
  ctx.strokeStyle = this.color1;
  ctx.beginPath();
  ctx.arc(this.x, this.y,this.r,0,m2PI);
  ctx.lineWidth = 2;
  ctx.stroke();

  ctx.strokeStyle = this.color1;
  ctx.beginPath();
  ctx.arc(this.x, this.y,this.r1,0,m2PI);
  ctx.lineWidth = 2;
  ctx.stroke();
}
}
function startOver() {
  maxx = window.innerWidth;
  maxy = window.innerHeight;
  if (maxx < 10) return false;

  canv.style.left = ((window.innerWidth ) - maxx) / 2 + 'px';
  canv.style.top = ((window.innerHeight ) - maxy) / 2 + 'px';
  ctx.canvas.width = maxx;
  ctx.canvas.height = maxy;
  ctx.lineJoin = 'round'; 
  noiseInitDir = NoiseGen(null, 200,0,0,-0.03,0.03);
  noiseInitHue = NoiseGen(null, 500,1,0.8,-2,2);
  particles = [];
  initDir = alea(m2PI);
  initHue = alea(360);
  return true; 
} 
function mouseMove(event) {

  mouseX = event.clientX;
  mouseY = event.clientY;
}
function animate(tStamp) {
  if (idAnim) window.cancelAnimationFrame(idAnim);
  idAnim = undefined;

  if (click && startOver()) click = false;
  if (particles) {
    initDir += noiseInitDir();
    initDir %= m2PI;
    initHue += noiseInitHue();
    initHue %= 360;
    ctx.fillStyle = '#000';
    ctx.fillRect(0, 0, maxx, maxy);
    if (particles.length < 50) {
      particles.push(new Particle());
    }
    particles.forEach((part,k) => {
      if (part.move() == false ) {
        removeElement(particles, part);
      } else part.draw();
    });
  }
  idAnim = window.requestAnimationFrame(animate);
}
  {
    canv = document.createElement('canvas');
    canv.style.position="absolute";
    document.body.appendChild(canv);
    ctx = canv.getContext('2d');
  } 
  window.addEventListener('mousemove',mouseMove);
  animate();
  click = true; 
}); 

以上即为全部源代码。有1000多行的注释由于不便于阅读我删掉了。整个源文件(包括注释)我也上传到了“资源”中,欢迎喜欢的朋友下载。

你可能感兴趣的:(html,javascript,前端,泡泡特效,前端特效)