【HTML旋转粒子】(效果 + 代码)

效果展示

在这里插入图片描述

代码

旋转粒子.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
 <HEAD>
  <TITLE> New Document </TITLE>
  <META NAME="Generator" CONTENT="EditPlus">
  <META NAME="Keywords" CONTENT="">
  <META NAME="Description" CONTENT="">
  <style>
  body { 
  background-color: #000; 
  padding: 0; 
  margin: 0; 
  overflow: hidden; 
}

p { 
  position: absolute; 
  z-index: 99; 
  color: #ccc; 
  margin: 10px; 
  padding: 0; 
  font-family: Arial; 
  font-size: 11px; 
}

a { 
  color: #24cad6; 
}
  </style>
 </HEAD>

 <BODY>
 <p> <br><a id="prevSkin" href="#"></a> / <a id="nextSkin" href="#"></a>.</p>
<canvas id='world'></canvas>
  <script>
  Magnetic = new function() {
  
  var SCREEN_WIDTH = window.innerWidth;
  var SCREEN_HEIGHT = window.innerHeight;
  
  var MAGNETS_AT_START = 4;
  var PARTICLES_PER_MAGNET = 20;
  var MAGNETIC_FORCE_THRESHOLD = 300;

  var canvas;
  var context;
  var particles = [];
  var magnets = [];
  
  var mouseX = (window.innerWidth - SCREEN_WIDTH);
  var mouseY = (window.innerHeight - SCREEN_HEIGHT);
  var mouseIsDown = false;
  var mouseDownTime = 0;
  
  var skinIndex = 0;
  var skins = [
     { glowA: 'rgba(0,200,250,0.3)', glowB: 'rgba(0,200,250,0.0)', particleFill: '#ffffff', fadeFill: 'rgba(22,22,22,.6)', useFade: true },
     { glowA: 'rgba(230,0,0,0.3)', glowB: 'rgba(230,0,0,0.0)', particleFill: '#ffffff', fadeFill: 'rgba(22,22,22,.6)', useFade: true },
     { glowA: 'rgba(0,230,0,0.3)', glowB: 'rgba(0,230,0,0.0)', particleFill: 'rgba(0,230,0,0.7)', fadeFill: 'rgba(22,22,22,.6)', useFade: true },
     { glowA: 'rgba(0,0,0,0.3)', glowB: 'rgba(0,0,0,0.0)', particleFill: '#A8A8A8', fadeFill: 'rgba(255,255,255,.6)', useFade: true },
     { glowA: 'rgba(0,0,0,0.0)', glowB: 'rgba(0,0,0,0.0)', particleFill: '#333333', fadeFill: 'rgba(255,255,255,.2)', useFade: true },
     { glowA: 'rgba(230,230,230,0)', glowB: 'rgba(230,230,230,0.0)', particleFill: '#ffffff', fadeFill: '', useFade: false }
  ];
  
  this.init = function() {
    
    canvas = document.getElementById( 'world' );
    
    if (canvas && canvas.getContext) {
      context = canvas.getContext('2d');
      
      // Register event listeners
      window.addEventListener('mousemove', documentMouseMoveHandler, false);
      window.addEventListener('mousedown', documentMouseDownHandler, false);
      window.addEventListener('mouseup', documentMouseUpHandler, false);
      document.getElementById( 'prevSkin' ).addEventListener('click', previousSkinClickHandler, false);
      document.getElementById( 'nextSkin' ).addEventListener('click', nextSkinClickHandler, false);
      window.addEventListener('resize', windowResizeHandler, false);
      
      createMagnets();
      
      windowResizeHandler();
      
      setInterval( loop, 1000 / 60 );
    }
  }

  function createMagnets() {
    var w = 300;
    var h = 300;
    
    for (var i = 0; i < MAGNETS_AT_START; i++) {
      var position = {
        x: ( SCREEN_WIDTH - w ) * 0.5 + (Math.random() * w), 
        y: ( SCREEN_HEIGHT - h ) * 0.5 + (Math.random() * h)
      };
      
      createMagnet( position );
    }
  }
  
  function createMagnet( position ) {
    var m = new Magnet();
    m.position.x = position.x;
    m.position.y = position.y;
    
    magnets.push( m );
    
    createParticles( m.position );
  }

  function createParticles( position ) {
    for (var i = 0; i < PARTICLES_PER_MAGNET; i++) {
      var p = new Particle();
      p.position.x = position.x;
      p.position.y = position.y;
      p.shift.x = position.x;
      p.shift.y = position.y;
      p.color = skins[skinIndex].particleFill;
      
      particles.push( p );
    }
  }

  function documentMouseMoveHandler(event) {
    mouseX = event.clientX - (window.innerWidth - SCREEN_WIDTH) * .5;
    mouseY = event.clientY - (window.innerHeight - SCREEN_HEIGHT) * .5;
  }
  
  function documentMouseDownHandler(event) {
    event.preventDefault();
    
    mouseIsDown = true;
    
    if( new Date().getTime() - mouseDownTime < 300 ) {
      // The mouse was pressed down twice with a < 300 ms interval: add a magnet
      createMagnet( { x: mouseX, y: mouseY } );
      
      mouseDownTime = 0;
    }
    
    mouseDownTime = new Date().getTime();
    
    for( var i = 0, len = magnets.length; i < len; i++ ) {
      magnet = magnets[i];
      
      if( distanceBetween( magnet.position, { x: mouseX, y: mouseY } ) < magnet.orbit * .5 ) {
        magnet.dragging = true;
        break;
      }
    }
  }
  
  function documentMouseUpHandler(event) {
    mouseIsDown = false;
    
    for( var i = 0, len = magnets.length; i < len; i++ ) {
      magnet = magnets[i];
      magnet.dragging = false;
    }
  }
    
  function previousSkinClickHandler(event) {
    event.preventDefault();
    --skinIndex;
    updateSkin();
  }
    
  function nextSkinClickHandler(event) {
    event.preventDefault();
    ++skinIndex;
    updateSkin();
  }
  
  function updateSkin() {
    skinIndex = skinIndex < 0 ? skins.length-1 : skinIndex;
    skinIndex = skinIndex > skins.length-1 ? 0 : skinIndex;

    for (var i = 0, len = particles.length; i < len; i++) {
      particles[i].color = skins[skinIndex].particleFill;
    }
  }
  
  function windowResizeHandler() {
    SCREEN_WIDTH = window.innerWidth;
    SCREEN_HEIGHT = window.innerHeight;
    
    canvas.width = SCREEN_WIDTH;
    canvas.height = SCREEN_HEIGHT;
    
    canvas.style.position = 'absolute';
    canvas.style.left = (window.innerWidth - SCREEN_WIDTH) * .5 + 'px';
    canvas.style.top = (window.innerHeight - SCREEN_HEIGHT) * .5 + 'px';
  }

  function loop() {
    
    if( skins[skinIndex].useFade) {
      context.fillStyle = skins[skinIndex].fadeFill;
         context.fillRect(0, 0, context.canvas.width, context.canvas.height);
    }
    else {
      context.clearRect(0,0,canvas.width,canvas.height);
    }
    
    var particle, magnet;
    var i, j, ilen, jlen;
    
    // Render the magnets
    for( j = 0, jlen = magnets.length; j < jlen; j++ ) {
      magnet = magnets[j];
      
      if( magnet.dragging ) {
        magnet.position.x += ( mouseX - magnet.position.x ) * 0.2;
        magnet.position.y += ( mouseY - magnet.position.y ) * 0.2;
      }
      
      // Increase the size of the magnet center point depending on # of connections
      magnet.size += ( (magnet.connections/3) - magnet.size ) * 0.025;
      magnet.size = Math.max(magnet.size,2);
      
      var gradientFill = context.createRadialGradient(magnet.position.x,magnet.position.y,0,magnet.position.x,magnet.position.y,magnet.size*10);
      gradientFill.addColorStop(0,skins[skinIndex].glowA);
      gradientFill.addColorStop(1,skins[skinIndex].glowB);
      
      context.beginPath();
      context.fillStyle = gradientFill;
      context.arc(magnet.position.x, magnet.position.y, magnet.size*10, 0, Math.PI*2, true);
      context.fill();
      
      context.beginPath();
      context.fillStyle = '#00000000';
      context.arc(magnet.position.x, magnet.position.y, magnet.size, 0, Math.PI*2, true);
      context.fill();
      
      magnet.connections = 0;
    }
    
    // Render the particles
    for (i = 0, ilen = particles.length; i < ilen; i++) {
      particle = particles[i];
      
      var currentDistance = -1;
      var closestDistance = -1;
      var closestMagnet = null;
      
      var force = { x: 0, y: 0 };
      
      // For each particle, we check what the closes magnet is
      for( j = 0, jlen = magnets.length; j < jlen; j++ ) {
        magnet = magnets[j];
        
        currentDistance = distanceBetween( particle.position, magnet.position ) - ( magnet.orbit * 0.5 );
        
        if( particle.magnet != magnet ) {
          var fx = magnet.position.x - particle.position.x;
          if( fx > -MAGNETIC_FORCE_THRESHOLD && fx < MAGNETIC_FORCE_THRESHOLD ) {
            force.x += fx / MAGNETIC_FORCE_THRESHOLD;
          }
          
          var fy = magnet.position.y - particle.position.y;
          if( fy > -MAGNETIC_FORCE_THRESHOLD && fy < MAGNETIC_FORCE_THRESHOLD ) {
            force.y += fy / MAGNETIC_FORCE_THRESHOLD;
          }
          
        }
          
        if( closestMagnet == null || currentDistance < closestDistance ) {
          closestDistance = currentDistance;
          closestMagnet = magnet;
        }
      }
      
      if( particle.magnet == null || particle.magnet != closestMagnet ) {
        particle.magnet = closestMagnet;
      }
      
      closestMagnet.connections += 1;
      
      // Rotation
      particle.angle += particle.speed;
      
      // Translate towards the magnet position
      particle.shift.x += ( (closestMagnet.position.x+(force.x*8)) - particle.shift.x) * particle.speed;
      particle.shift.y += ( (closestMagnet.position.y+(force.y*8)) - particle.shift.y) * particle.speed;
      
      // Appy the combined position including shift, angle and orbit
      particle.position.x = particle.shift.x + Math.cos(i+particle.angle) * (particle.orbit*particle.force);
      particle.position.y = particle.shift.y + Math.sin(i+particle.angle) * (particle.orbit*particle.force);
      
      // Limit to screen bounds
      particle.position.x = Math.max( Math.min( particle.position.x, SCREEN_WIDTH-particle.size/2 ), particle.size/2 );
      particle.position.y = Math.max( Math.min( particle.position.y, SCREEN_HEIGHT-particle.size/2 ), particle.size/2 );
      
      // Slowly inherit the cloest magnets orbit
      particle.orbit += ( closestMagnet.orbit - particle.orbit ) * 0.1;
      
      context.beginPath();
      context.fillStyle = particle.color;
      context.arc(particle.position.x, particle.position.y, particle.size/2, 0, Math.PI*2, true);
      context.fill();
    }
  }
  
  function distanceBetween(p1,p2) {
    var dx = p2.x-p1.x;
    var dy = p2.y-p1.y;
    return Math.sqrt(dx*dx + dy*dy);
  }
  
};
function Particle() {
  this.size = 0.5+Math.random()*3.5;
  this.position = { x: 0, y: 0 };
  this.shift = { x: 0, y: 0 };
  this.angle = 0;
  this.speed = 0.01 + (this.size/4) * 0.015;
  this.force = 1 - (Math.random()*0.15);
  this.color = '#ffffff';
  this.orbit = 1;
  this.magnet = null;
}
function Magnet() {
  this.orbit = 100;
  this.position = { x: 0, y: 0 };
  this.dragging = false;
  this.connections = 0;
  this.size = 1;
}
Magnetic.init();
  </script>
 </BODY>
</HTML>

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>