WEB骇客
<div id="interface">
  <h1>礼花喷花器</h1>

  
数量:
<input type="range" id="1" value="100" max="1000" min="1" step="1">
重力:
<input type="range" id="2" value="0.1" max="1" min="-1" step="0.1">
抛力:
<input type="range" id="3" value="0.99" max="0.99" min="0.1" step="0.01">

</div>

<canvas id="canvas"></canvas>
body{
	padding:0px;background-color:#e4e2e4;
font-family:arial;

	margin:0px; 
	overflow:hidden;
	  -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
canvas{
border:0px solid black;
}

#interface{
left:20px;
top:20px;
width:250px;
position:absolute;
border:0px solid black;
padding:20px;  box-sizing: border-box;

}

input[type="range"] {

	width:100%;

}

input[type=range] {
    -webkit-appearance: none;
    background-color: silver;
    height:10px;
  margin-top:15px;
  margin-bottom:15px;
}

input[type="range"]::-webkit-slider-thumb {
     -webkit-appearance: none;
    background-color: #666;
    width: 10px;
    height: 26px;
}

input[type="button"] {
padding:5px;
  margin-bottom:5px;
  margin-top:5px;
    
  width:100%;
  
}
h1{padding:0px;

margin-top:0px;
}

select {
padding:5px;
  margin-bottom:5px;
  margin-top:5px;
    
  width:100%;
  
}
	var utils = {
	  norm: function(value, min, max) {
	    return (value - min) / (max - min);
	  },

	  lerp: function(norm, min, max) {
	    return (max - min) * norm + min;
	  },

	  map: function(value, sourceMin, sourceMax, destMin, destMax) {
	    return utils.lerp(utils.norm(value, sourceMin, sourceMax), destMin, destMax);
	  },

	  clamp: function(value, min, max) {
	    return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max));
	  },

	  distance: function(p0, p1) {
	    var dx = p1.x - p0.x,
	      dy = p1.y - p0.y;
	    return Math.sqrt(dx * dx + dy * dy);
	  },

	  distanceXY: function(x0, y0, x1, y1) {
	    var dx = x1 - x0,
	      dy = y1 - y0;
	    return Math.sqrt(dx * dx + dy * dy);
	  },

	  circleCollision: function(c0, c1) {
	    return utils.distance(c0, c1) <= c0.radius + c1.radius;
	  },

	  circlePointCollision: function(x, y, circle) {
	    return utils.distanceXY(x, y, circle.x, circle.y) < circle.radius;
	  },

	  pointInRect: function(x, y, rect) {
	    return utils.inRange(x, rect.x, rect.x + rect.width) &&
	      utils.inRange(y, rect.y, rect.y + rect.height);
	  },

	  inRange: function(value, min, max) {
	    return value >= Math.min(min, max) && value <= Math.max(min, max);
	  },

	  rangeIntersect: function(min0, max0, min1, max1) {
	    return Math.max(min0, max0) >= Math.min(min1, max1) &&
	      Math.min(min0, max0) <= Math.max(min1, max1);
	  },

	  rectIntersect: function(r0, r1) {
	    return utils.rangeIntersect(r0.x, r0.x + r0.width, r1.x, r1.x + r1.width) &&
	      utils.rangeIntersect(r0.y, r0.y + r0.height, r1.y, r1.y + r1.height);
	  },

	  degreesToRads: function(degrees) {
	    return degrees / 180 * Math.PI;
	  },

	  radsToDegrees: function(radians) {
	    return radians * 180 / Math.PI;
	  },

	  randomRange: function(min, max) {
	    return min + Math.random() * (max - min);
	  },

	  randomInt: function(min, max) {
	    return Math.floor(min + Math.random() * (max - min + 1));
	  }

	}

	element1 = document.getElementById("1");
	element2 = document.getElementById("2");
	element3 = document.getElementById("3");

	canvas = document.getElementById("canvas");
	var context = canvas.getContext('2d');
	W = canvas.width = window.innerWidth;
	H = canvas.height = window.innerHeight;
	generatorStock = [];

	gravity = parseFloat(element2.value);

	friction = element3.value;

	colors = [
	  '#f44336', '#e91e63', '#9c27b0', '#673ab7', '#3f51b5',
	  '#2196f3', '#03a9f4', '#00bcd4', '#009688', '#4CAF50',
	  '#8BC34A', '#CDDC39', '#FFEB3B', '#FFC107', '#FF9800',
	  '#FF5722', '#795548'
	];

	//
	// Add the Generator Here :)
	//
	generator1 = new particleGenerator(W / 2, H / 2, 0, 0, element1.value);

	function loadImage(url) {
	  var img = document.createElement("img");
	  img.src = url;
	  return img;
	}

	var mouse = {
	  x: 0,
	  y: 0
	};
	canvas.addEventListener('mousemove', function(e) {
	  mouse.x = e.pageX - this.offsetLeft;
	  mouse.y = e.pageY - this.offsetTop;
	}, false);

	function randomInt(min, max) {
	  return min + Math.random() * (max - min);
	}

	function clamp(value, min, max) {
	  return Math.min(Math.max(value, Math.min(min, max)), Math.max(min, max));
	}

	function particle(x, y) {
	  this.radius = randomInt(.1, 1);
	  this.x = x;
	  this.y = y;
	  this.vx = randomInt(-4, 4);
	  this.vy = randomInt(-10, -0);
	  this.type = utils.randomInt(0,1);

	  this.w = utils.randomRange(5, 20);
	  this.h = utils.randomRange(5, 20);

	  this.r = utils.randomRange(5, 10);

	  this.angle = utils.degreesToRads(randomInt(0, 360));
	  this.anglespin = randomInt(-0.2, 0.2);
	  this.color = colors[Math.floor(Math.random() * colors.length)];

	  this.rotateY = randomInt(0, 1);

	}

	particle.prototype.update = function() {
	  this.x += this.vx;
	  this.y += this.vy;
	  this.vy += gravity;
	  this.vx *= friction;
	  this.vy *= friction;
	  this.radius -= .02;

	  if (this.rotateY < 1) {
	    this.rotateY += 0.1;

	  } else {
	    this.rotateY = -1;

	  }
	  this.angle += this.anglespin;

	  context.save();
	  context.translate(this.x, this.y);
	  context.rotate(this.angle);

	  context.scale(1, this.rotateY);

	  context.rotate(this.angle);
	  context.beginPath();
	  context.fillStyle = this.color;
	  context.strokeStyle = this.color;
    context.lineCap="round";
      context.lineWidth = 2;

	  if (this.type === 0) {
	    context.beginPath();
	    context.arc(0, 0, this.r, 0, 2 * Math.PI);
	    context.fill();
	  }else if(this.type === 2){
    context.beginPath();
    for (i = 0; i < 22; i++) {
        angle = 0.5 * i;
        x = (.2 + 1.5 * angle) * Math.cos(angle);
        y =(.2 + 1.5 * angle) * Math.sin(angle);

        context.lineTo(x, y);
    }
    context.stroke();
      
	  }else if(this.type === 1){
      context.fillRect(-this.w / 2, -this.h / 2, this.w, this.h);
	  }

	  context.closePath();
	  context.restore();


	}

	function particleGenerator(x, y, w, h, number, text) {
	  // particle will spawn in this aera
	  this.x = x;
	  this.y = y;
	  this.w = w;
	  this.h = h;
	  this.number = number;
	  this.particles = [];
	  this.text = text;
    this.recycle = true;
	}
	particleGenerator.prototype.animate = function() {

	  context.fillStyle = "grey";

	  context.beginPath();
	  context.strokeRect(this.x, this.y, this.w, this.h);

	  context.font = "13px arial";
	  context.textAlign = "center";

	  context.closePath();
//	   for (var i = 0; i < 100; i++) {

	  if (this.particles.length < this.number) {
	    this.particles.push(new particle(clamp(randomInt(this.x, this.w + this.x), this.x, this.w + this.x),

	      clamp(randomInt(this.y, this.h + this.y), this.y, this.h + this.y), this.text));
	  }

	  if (this.particles.length > this.number) {
	    this.particles.length = this.number;
	  }

	  for (var i = 0; i < this.particles.length; i++) {
	    p = this.particles[i];
	    p.update();
	    if (p.y > H && this.recycle) {
	      //a brand new particle replacing the dead one
	      this.particles[i] = new particle(clamp(randomInt(this.x, this.w + this.x), this.x, this.w + this.x),

	        clamp(randomInt(this.y, this.h + this.y), this.y, this.h + this.y), this.text);
	    }
	  }
	}

	update();

	function update() {

	  gravity = parseFloat(element2.value);
	  generator1.number = element1.value;
	  friction = element3.value;

	  // context.globalAlpha=.5;
context.fillStyle="white";    context.fillRect(0, 0, W, H);
	  generator1.animate();
	  requestAnimationFrame(update);

	}
返回