效果展示

代码

旋转粒子.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>