html5 式程序猿表白

今天是个好日子,2014年5月20日,表白的最佳时机,虽说孩子已经四岁、结婚已经五年,但是也不可以偷懒,于是有了这个效果

水平有限,浏览器兼容不好,请大家使用chrome浏览器获得最佳效果。

------------------------------------

在线研究点这里,下载收藏点这里.

------------------------------------------------------

程序猿and程序媛,大胆秀出你的爱吧。利用html5 canvas实现动态的文字粒子效果,效果如下。

实现原理

1. canvas里面实现描边文字

2. 利用getImageData获得描边文字的像素矩阵

3. 将粒子效果绑定在描边文字上

整个效果如下。

html文件非常简单。

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. <canvas id="canvas" width="1000" height="600"></canvas>  

css文件如下。

 

 

[css] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. body {  
  2.     background#000;  
  3.     text-aligncenter;  
  4.     font-family"simhei"  
  5. }  
  6. canvas {  
  7.     marginauto;  
  8.     positionabsolute;  
  9.     left: 0;  
  10.     right:0;  
  11.     top: 0;  
  12.     bottom: 0;  
  13. }  

js文件至关重要了。

 

 

[javascript] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1.            
  2. BLUR = false;  
  3.    
  4. PULSATION = true;  
  5. PULSATION_PERIOD = 1000;  
  6. PARTICLE_RADIUS = 6;  
  7.    
  8. /* disable blur before using blink */  
  9.    
  10. BLINK = false;  
  11.    
  12. GLOBAL_PULSATION = false;  
  13.    
  14. QUALITY = 2; /* 0 - 5 */  
  15.    
  16. /* set false if you prefer rectangles */  
  17. ARC = true;  
  18.      
  19. /* trembling + blur = fun */  
  20. TREMBLING = 0; /* 0 - infinity */  
  21.    
  22. FANCY_FONT = "Arial";  
  23.    
  24. BACKGROUND = "#000";  
  25.    
  26. BLENDING = true;  
  27.    
  28. /* if empty the text will be a random number */  
  29. var TEXT;  
  30. num = 0;  
  31. TEXTArray = ["海庆""深爱""春玲""直到","永远"];  
  32.   
  33. QUALITY_TO_FONT_SIZE = [10, 12, 40, 50, 200, 350];  
  34. QUALITY_TO_SCALE = [20, 6, 4, 1, 0.9, 0.5];  
  35. QUALITY_TO_TEXT_POS = [10, 20, 40, 60, 170, 280];  
  36.   
  37.   
  38. window.onload = function () {  
  39.     document.body.style.backgroundColor = BACKGROUND;  
  40.    
  41.     var canvas = document.getElementById("canvas");  
  42.     var ctx = canvas.getContext("2d");  
  43.    
  44.     var W = canvas.width;  
  45.     var H = canvas.height;  
  46.    
  47.     var tcanvas = document.createElement("canvas");  
  48.     var tctx = tcanvas.getContext("2d");  
  49.     tcanvas.width = W;  
  50.     tcanvas.height = H;  
  51.    
  52.     total_area = W * H;  
  53.     total_particles = 1000;  
  54.     single_particle_area = total_area / total_particles;  
  55.     area_length = Math.sqrt(single_particle_area);  
  56.                
  57.     var particles = [];  
  58.     for (var i = 1; i <= total_particles; i++) {  
  59.         particles.push(new particle(i));  
  60.     }  
  61.       
  62.     function particle(i) {  
  63.         this.r = Math.round(Math.random() * 255 | 0);  
  64.         this.g = Math.round(Math.random() * 255 | 0);  
  65.         this.b = Math.round(Math.random() * 255 | 0);  
  66.         this.alpha = 1;  
  67.    
  68.         this.x = (i * area_length) % W;  
  69.         this.y = (i * area_length) / W * area_length;  
  70.    
  71.         /* randomize delta to make particles sparkling */  
  72.         this.deltaOffset = Math.random() * PULSATION_PERIOD | 0;  
  73.    
  74.         this.radius = 0.1 + Math.random() * 2;  
  75.     }  
  76.       
  77.     var positions = [];  
  78.       
  79.     function new_positions() {  
  80.    
  81.         TEXT = TEXTArray[num];  
  82.    
  83.         if (num < TEXTArray.length - 1) {  
  84.             num++;  
  85.         } else {  
  86.             num = 0;  
  87.         }  
  88.         //alert(TEXT);  
  89.    
  90.         tctx.fillStyle = "white";  
  91.         tctx.fillRect(0, 0, W, H)  
  92.         tctx.fill();  
  93.    
  94.         tctx.font = "bold " + QUALITY_TO_FONT_SIZE[QUALITY] + "px " + FANCY_FONT;  
  95.           
  96.    
  97.         tctx.strokeStyle = "black";  
  98.         tctx.fillStyle="#f00";  
  99.         tctx.strokeText(TEXT,20, 60);  
  100.         //tctx.fillText(TEXT,30, 50);  
  101.    
  102.         image_data = tctx.getImageData(0, 0, W, H);  
  103.         pixels = image_data.data;  
  104.         positions = [];  
  105.         for (var i = 0; i < pixels.length; i = i + 2) {  
  106.             if (pixels[i] != 255) {  
  107.                 position = {  
  108.                     x: (i / 2 % W | 0) * QUALITY_TO_SCALE[QUALITY] | 0,  
  109.                     y: (i / 2 / W | 0) * QUALITY_TO_SCALE[QUALITY] | 0  
  110.                 }  
  111.                 positions.push(position);  
  112.             }  
  113.         }  
  114.    
  115.         get_destinations();  
  116.     }  
  117.    
  118.     function draw() {  
  119.    
  120.         var now = Date.now();  
  121.    
  122.         ctx.globalCompositeOperation = "source-over";  
  123.    
  124.         if (BLUR) ctx.globalAlpha = 0.1;  
  125.         else if (!BLUR && !BLINK) ctx.globalAlpha = 1.0;  
  126.    
  127.         ctx.fillStyle = BACKGROUND;  
  128.         ctx.fillRect(0, 0, W, H)  
  129.    
  130.         if (BLENDING) ctx.globalCompositeOperation = "lighter";  
  131.    
  132.         for (var i = 0; i < particles.length; i++) {  
  133.    
  134.             p = particles[i];  
  135.   
  136.             if (isNaN(p.x)) continue  
  137.    
  138.             ctx.beginPath();  
  139.             ctx.fillStyle = "rgb(" + p.r + ", " + p.g + ", " + p.b + ")";  
  140.             ctx.fillStyle = "rgba(" + p.r + ", " + p.g + ", " + p.b + ", " + p.alpha + ")";  
  141.    
  142.             if (BLINK) ctx.globalAlpha = Math.sin(Math.PI * mod * 1.0);  
  143.    
  144.             if (PULSATION) { /* this would be 0 -> 1 */  
  145.                 var mod = ((GLOBAL_PULSATION ? 0 : p.deltaOffset) + now) % PULSATION_PERIOD / PULSATION_PERIOD;  
  146.                 mod = Math.sin(mod * Math.PI);  
  147.             } else var mod = 1;  
  148.    
  149.             var offset = TREMBLING ? TREMBLING * (-1 + Math.random() * 2) : 0;  
  150.    
  151.             var radius = PARTICLE_RADIUS * p.radius;  
  152.    
  153.             if (!ARC) {  
  154.                 ctx.fillRect(offset + p.x - mod * radius / 2 | 0, offset + p.y - mod * radius / 2 | 0, radius * mod,  
  155.                     radius * mod);  
  156.             } else {  
  157.                 ctx.arc(offset + p.x | 0, offset + p.y | 0, radius * mod, Math.PI * 2, false);  
  158.                 ctx.fill();  
  159.             }  
  160.    
  161.             p.x += (p.dx - p.x) / 10;  
  162.             p.y += (p.dy - p.y) / 10;  
  163.         }  
  164.     }  
  165.    
  166.     function get_destinations() {  
  167.         for (var i = 0; i < particles.length; i++) {  
  168.             pa = particles[i];  
  169.             particles[i].alpha = 1;  
  170.             var distance = [];  
  171.             nearest_position = 0;  
  172.             if (positions.length) {  
  173.                 for (var n = 0; n < positions.length; n++) {  
  174.                     po = positions[n];  
  175.                     distance[n] = Math.sqrt((pa.x - po.x) * (pa.x - po.x) + (pa.y - po.y) * (pa.y - po.y));  
  176.                     if (n > 0) {  
  177.                         if (distance[n] <= distance[nearest_position]) {  
  178.                             nearest_position = n;  
  179.                         }  
  180.                     }  
  181.                 }  
  182.                 particles[i].dx = positions[nearest_position].x;  
  183.                 particles[i].dy = positions[nearest_position].y;  
  184.                 particles[i].distance = distance[nearest_position];  
  185.    
  186.                 var po1 = positions[nearest_position];  
  187.                 for (var n = 0; n < positions.length; n++) {  
  188.                     var po2 = positions[n];  
  189.                     distance = Math.sqrt((po1.x - po2.x) * (po1.x - po2.x) + (po1.y - po2.y) * (po1.y - po2.y));  
  190.                     if (distance <= 5) {  
  191.                         positions.splice(n, 1);  
  192.                     }  
  193.                 }  
  194.             } else {  
  195.                 //particles[i].alpha = 0;  
  196.             }  
  197.         }  
  198.     }  
  199.    
  200.     function init() {  
  201.         new_positions();  
  202.         setInterval(draw, 30);  
  203.         setInterval(new_positions, 2000);  
  204.     }  
  205.    
  206.     init();  
  207. };  
Reportez-vous à notre Notice d'optimisation pour plus d'informations sur les choix et l'optimisation des performances dans les produits logiciels Intel.