index.html 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. <!DOCTYPE html>
  2. <html dir="ltr" lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width" />
  6. <title>点击夜空欣赏烟花</title>
  7. <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
  8. <style>
  9. /* basic styles for black background and crosshair cursor */
  10. body {
  11. background: #000;
  12. margin: 0;
  13. }
  14. canvas {
  15. cursor: crosshair;
  16. display: block;
  17. }
  18. .STYLE1 {color: #333333}
  19. </style>
  20. </head>
  21. <body>
  22. <div >
  23. <canvas id="canvas"><span class="STYLE1">Open IE effect more perfect </span></canvas>
  24. <audio autoplay="autoplay">
  25. <source src="http://www.sypeiyin.cn/Uploads/zh/News/2012071516257FJR.mp3" type="audio/mpeg"/>
  26. </audio>
  27. <img src="yanhua.jpg" style="position: absolute;left:0px;bottom: 0px;height: auto;width:100%;padding:0px;margin:0px;"/>
  28. </div>
  29. <script>
  30. // when animating on canvas, it is best to use requestAnimationFrame instead of setTimeout or setInterval
  31. // not supported in all browsers though and sometimes needs a prefix, so we need a shim
  32. window.requestAnimFrame = ( function() {
  33. return window.requestAnimationFrame ||
  34. window.webkitRequestAnimationFrame ||
  35. window.mozRequestAnimationFrame ||
  36. function( callback ) {
  37. window.setTimeout( callback, 1000 / 60 );
  38. };
  39. })();
  40. // now we will setup our basic variables for the demo
  41. var canvas = document.getElementById( 'canvas' ),
  42. ctx = canvas.getContext( '2d' ),
  43. // full screen dimensions
  44. cw = window.innerWidth,
  45. ch = window.innerHeight,
  46. // firework collection
  47. fireworks = [],
  48. // particle collection
  49. particles = [],
  50. // starting hue
  51. hue = 120,
  52. // when launching fireworks with a click, too many get launched at once without a limiter, one launch per 5 loop ticks
  53. limiterTotal = 5,
  54. limiterTick = 0,
  55. // this will time the auto launches of fireworks, one launch per 80 loop ticks
  56. timerTotal = 80,
  57. timerTick = 0,
  58. mousedown = false,
  59. // mouse x coordinate,
  60. mx,
  61. // mouse y coordinate
  62. my;
  63. // set canvas dimensions
  64. canvas.width = cw;
  65. canvas.height = ch;
  66. // now we are going to setup our function placeholders for the entire demo
  67. // get a random number within a range
  68. function random( min, max ) {
  69. return Math.random() * ( max - min ) + min;
  70. }
  71. // calculate the distance between two points
  72. function calculateDistance( p1x, p1y, p2x, p2y ) {
  73. var xDistance = p1x - p2x,
  74. yDistance = p1y - p2y;
  75. return Math.sqrt( Math.pow( xDistance, 2 ) + Math.pow( yDistance, 2 ) );
  76. }
  77. // create firework
  78. function Firework( sx, sy, tx, ty ) {
  79. // actual coordinates
  80. this.x = sx;
  81. this.y = sy;
  82. // starting coordinates
  83. this.sx = sx;
  84. this.sy = sy;
  85. // target coordinates
  86. this.tx = tx;
  87. this.ty = ty;
  88. // distance from starting point to target
  89. this.distanceToTarget = calculateDistance( sx, sy, tx, ty );
  90. this.distanceTraveled = 0;
  91. // track the past coordinates of each firework to create a trail effect, increase the coordinate count to create more prominent trails
  92. this.coordinates = [];
  93. this.coordinateCount = 3;
  94. // populate initial coordinate collection with the current coordinates
  95. while( this.coordinateCount-- ) {
  96. this.coordinates.push( [ this.x, this.y ] );
  97. }
  98. this.angle = Math.atan2( ty - sy, tx - sx );
  99. this.speed = 2;
  100. this.acceleration = 1.05;
  101. this.brightness = random( 50, 70 );
  102. // circle target indicator radius
  103. this.targetRadius = 1;
  104. }
  105. // update firework
  106. Firework.prototype.update = function( index ) {
  107. // remove last item in coordinates array
  108. this.coordinates.pop();
  109. // add current coordinates to the start of the array
  110. this.coordinates.unshift( [ this.x, this.y ] );
  111. // cycle the circle target indicator radius
  112. if( this.targetRadius < 8 ) {
  113. this.targetRadius += 0.3;
  114. } else {
  115. this.targetRadius = 1;
  116. }
  117. // speed up the firework
  118. this.speed *= this.acceleration;
  119. // get the current velocities based on angle and speed
  120. var vx = Math.cos( this.angle ) * this.speed,
  121. vy = Math.sin( this.angle ) * this.speed;
  122. // how far will the firework have traveled with velocities applied?
  123. this.distanceTraveled = calculateDistance( this.sx, this.sy, this.x + vx, this.y + vy );
  124. // if the distance traveled, including velocities, is greater than the initial distance to the target, then the target has been reached
  125. if( this.distanceTraveled >= this.distanceToTarget ) {
  126. createParticles( this.tx, this.ty );
  127. // remove the firework, use the index passed into the update function to determine which to remove
  128. fireworks.splice( index, 1 );
  129. } else {
  130. // target not reached, keep traveling
  131. this.x += vx;
  132. this.y += vy;
  133. }
  134. }
  135. // draw firework
  136. Firework.prototype.draw = function() {
  137. ctx.beginPath();
  138. // move to the last tracked coordinate in the set, then draw a line to the current x and y
  139. ctx.moveTo( this.coordinates[ this.coordinates.length - 1][ 0 ], this.coordinates[ this.coordinates.length - 1][ 1 ] );
  140. ctx.lineTo( this.x, this.y );
  141. ctx.strokeStyle = 'hsl(' + hue + ', 100%, ' + this.brightness + '%)';
  142. ctx.stroke();
  143. ctx.beginPath();
  144. // draw the target for this firework with a pulsing circle
  145. ctx.arc( this.tx, this.ty, this.targetRadius, 0, Math.PI * 2 );
  146. ctx.stroke();
  147. }
  148. // create particle
  149. function Particle( x, y ) {
  150. this.x = x;
  151. this.y = y;
  152. // track the past coordinates of each particle to create a trail effect, increase the coordinate count to create more prominent trails
  153. this.coordinates = [];
  154. this.coordinateCount = 5;
  155. while( this.coordinateCount-- ) {
  156. this.coordinates.push( [ this.x, this.y ] );
  157. }
  158. // set a random angle in all possible directions, in radians
  159. this.angle = random( 0, Math.PI * 2 );
  160. this.speed = random( 1, 10 );
  161. // friction will slow the particle down
  162. this.friction = 0.95;
  163. // gravity will be applied and pull the particle down
  164. this.gravity = 1;
  165. // set the hue to a random number +-20 of the overall hue variable
  166. this.hue = random( hue - 20, hue + 20 );
  167. this.brightness = random( 50, 80 );
  168. this.alpha = 1;
  169. // set how fast the particle fades out
  170. this.decay = random( 0.015, 0.03 );
  171. }
  172. // update particle
  173. Particle.prototype.update = function( index ) {
  174. // remove last item in coordinates array
  175. this.coordinates.pop();
  176. // add current coordinates to the start of the array
  177. this.coordinates.unshift( [ this.x, this.y ] );
  178. // slow down the particle
  179. this.speed *= this.friction;
  180. // apply velocity
  181. this.x += Math.cos( this.angle ) * this.speed;
  182. this.y += Math.sin( this.angle ) * this.speed + this.gravity;
  183. // fade out the particle
  184. this.alpha -= this.decay;
  185. // remove the particle once the alpha is low enough, based on the passed in index
  186. if( this.alpha <= this.decay ) {
  187. particles.splice( index, 1 );
  188. }
  189. }
  190. // draw particle
  191. Particle.prototype.draw = function() {
  192. ctx. beginPath();
  193. // move to the last tracked coordinates in the set, then draw a line to the current x and y
  194. ctx.moveTo( this.coordinates[ this.coordinates.length - 1 ][ 0 ], this.coordinates[ this.coordinates.length - 1 ][ 1 ] );
  195. ctx.lineTo( this.x, this.y );
  196. ctx.strokeStyle = 'hsla(' + this.hue + ', 100%, ' + this.brightness + '%, ' + this.alpha + ')';
  197. ctx.stroke();
  198. }
  199. // create particle group/explosion
  200. function createParticles( x, y ) {
  201. // increase the particle count for a bigger explosion, beware of the canvas performance hit with the increased particles though
  202. var particleCount = 30;
  203. while( particleCount-- ) {
  204. particles.push( new Particle( x, y ) );
  205. }
  206. }
  207. // main demo loop
  208. function loop() {
  209. // this function will run endlessly with requestAnimationFrame
  210. requestAnimFrame( loop );
  211. // increase the hue to get different colored fireworks over time
  212. hue += 0.5;
  213. // normally, clearRect() would be used to clear the canvas
  214. // we want to create a trailing effect though
  215. // setting the composite operation to destination-out will allow us to clear the canvas at a specific opacity, rather than wiping it entirely
  216. ctx.globalCompositeOperation = 'destination-out';
  217. // decrease the alpha property to create more prominent trails
  218. ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
  219. ctx.fillRect( 0, 0, cw, ch );
  220. // change the composite operation back to our main mode
  221. // lighter creates bright highlight points as the fireworks and particles overlap each other
  222. ctx.globalCompositeOperation = 'lighter';
  223. // loop over each firework, draw it, update it
  224. var i = fireworks.length;
  225. while( i-- ) {
  226. fireworks[ i ].draw();
  227. fireworks[ i ].update( i );
  228. }
  229. // loop over each particle, draw it, update it
  230. var i = particles.length;
  231. while( i-- ) {
  232. particles[ i ].draw();
  233. particles[ i ].update( i );
  234. }
  235. // launch fireworks automatically to random coordinates, when the mouse isn't down
  236. if( timerTick >= timerTotal ) {
  237. if( !mousedown ) {
  238. // start the firework at the bottom middle of the screen, then set the random target coordinates, the random y coordinates will be set within the range of the top half of the screen
  239. fireworks.push( new Firework( cw / 2, ch, random( 0, cw ), random( 0, ch / 2 ) ) );
  240. timerTick = 0;
  241. }
  242. } else {
  243. timerTick++;
  244. }
  245. // limit the rate at which fireworks get launched when mouse is down
  246. if( limiterTick >= limiterTotal ) {
  247. if( mousedown ) {
  248. // start the firework at the bottom middle of the screen, then set the current mouse coordinates as the target
  249. fireworks.push( new Firework( cw / 2, ch, mx, my ) );
  250. limiterTick = 0;
  251. }
  252. } else {
  253. limiterTick++;
  254. }
  255. }
  256. // mouse event bindings
  257. // update the mouse coordinates on mousemove
  258. canvas.addEventListener( 'mousemove', function( e ) {
  259. mx = e.pageX - canvas.offsetLeft;
  260. my = e.pageY - canvas.offsetTop;
  261. });
  262. // toggle mousedown state and prevent canvas from being selected
  263. canvas.addEventListener( 'mousedown', function( e ) {
  264. e.preventDefault();
  265. mousedown = true;
  266. });
  267. canvas.addEventListener( 'mouseup', function( e ) {
  268. e.preventDefault();
  269. mousedown = false;
  270. });
  271. $('#canvas').bind('touchstart',function(e){
  272. // console.log(e.originalEvent.x);
  273. // console.log(e.originalEvent.y);
  274. var touch=e.originalEvent.targetTouches[0];
  275. mx=touch.pageX-canvas.offsetLeft;;
  276. my = touch.pageY - canvas.offsetTop;
  277. e.preventDefault();
  278. mousedown = true;
  279. });
  280. $('#canvas').bind('touchend',function(e){
  281. e.preventDefault();
  282. mousedown = false;
  283. })
  284. $('#canvas').bind('touchmove',function(e){
  285. var touch=e.originalEvent.targetTouches[0];
  286. mx=touch.pageX-canvas.offsetLeft;;
  287. my = touch.pageY - canvas.offsetTop;
  288. e.preventDefault();
  289. // mousedown = false;
  290. })
  291. // once the window loads, we are ready for some fireworks!
  292. window.onload = loop;
  293. </script>
  294. </body>
  295. </html>