Клевый эффект для текста из частиц на Canvas

Прикольный эффект для текста сделан с помощью элемента HTML5 canvas. Но это сделал не я. Идея принадлежит автору оригинала. Я просто нашёл его демо-страницу.

Обновление: Автором оригинала является Ruby on Tails. Я заметил, что демо-пример немного неисправен и производительность его слабая. Так что если кто-нибудь может аккуратненько подправить пример, поделитесь решением в комментариях.

HTML:

<canvas id="canvas" width="600" height="300"></canvas>

CSS:

h1 {
	font-family: 'Comic Sans MS', Verdana;
	color: #f06;
}

JavaScript:

window.onload = function(){
			var canvas = document.getElementById("canvas");
			var ctx = canvas.getContext("2d");

			var W = canvas.width;
			var H = canvas.height;

			var tcanvas = document.createElement("canvas");
			var tctx = tcanvas.getContext("2d");
			tcanvas.width = W;
			tcanvas.height = H;

			total_area = W*H;
			total_particles = 1000;
			single_particle_area = total_area/total_particles;
			area_length = Math.sqrt(single_particle_area);
			console.log(area_length);

			var particles = [];
			for(var i = 1; i <= total_particles; i++)
			{
				particles.push(new particle(i));
			}

			function particle(i)
			{
				this.r = Math.round(Math.random()*255);
				this.g = Math.round(Math.random()*255);
				this.b = Math.round(Math.random()*255);
				this.alpha = 1;
				//this.color = "rgb("+r+", "+g+", "+b+")";

				this.x = (i*area_length)%W;
				this.y = (i*area_length)/W*area_length;
				//console.log(W+"%("+i+"*"+area_length+"/2) = "+this.x+", "+this.y);

				this.radius = 2+Math.random()*8;
			}

			var positions = [];
			function new_positions()
			{
				tctx.fillStyle = "white";
				tctx.fillRect(0, 0, W, H)
				tctx.fill();

				tctx.font = "bold 350px arial";
				text = Math.round(100 + Math.random()*899);
				tctx.strokeStyle = "black";
				tctx.strokeText(text, 5, 275);

				image_data = tctx.getImageData(0, 0, W, H);
				pixels = image_data.data;
				positions = [];
				for(var i = 0; i < pixels.length; i = i+4)
				{
					if(pixels[i] != 255 && pixels[i+1] != 255 && pixels[i+2] != 255)
					{
						position = {x: i/4%W, y: i/4/W}
						positions.push(position);
					}
				}

				get_destinations();
			}

			function draw()
			{
				ctx.fillStyle = "white";
				ctx.fillRect(0, 0, W, H)
				ctx.fill();

				for(var i = 0; i < particles.length; i++)
				{
					p = particles[i];

					ctx.beginPath();
					ctx.fillStyle = "rgb("+p.r+", "+p.g+", "+p.b+")";
					ctx.fillStyle = "rgba("+p.r+", "+p.g+", "+p.b+", "+p.alpha+")";
					//ctx.fillRect(p.x, p.y, p.radius, p.radius);
					ctx.arc(p.x, p.y, p.radius, Math.PI*2, false);
					ctx.fill();

					p.x += (p.dx-p.x)/10;
					p.y += (p.dy-p.y)/10;
				}
			}

			function get_destinations()
			{
				for(var i = 0; i < particles.length; i++)
				{
					pa = particles[i];
					particles[i].alpha = 1;
					var distance = [];
					nearest_position = 0;
					if(positions.length)
					{
						for(var n = 0; n < positions.length; n++)
						{
							po = positions[n];
							distance[n] = Math.sqrt((pa.x-po.x)*(pa.x-po.x) + (pa.y-po.y)*(pa.y-po.y));
							if(n > 0)
							{
								if(distance[n] <= distance[nearest_position])
								{
									nearest_position = n;
								}
							}
						}
						particles[i].dx = positions[nearest_position].x;
						particles[i].dy = positions[nearest_position].y;
						particles[i].distance = distance[nearest_position];

						var po1 = positions[nearest_position];
						for(var n = 0; n < positions.length; n++)
						{
							var po2 = positions[n];
							distance = Math.sqrt((po1.x-po2.x)*(po1.x-po2.x) + (po1.y-po2.y)*(po1.y-po2.y));
							if(distance <= 5)
							{
								positions.splice(n, 1);
							}
						}
					}
					else
					{
						//particles[i].alpha = 0;
					}
				}
			}
			function init()
			{
				new_positions();
				setInterval(draw, 16.67);
				setInterval(new_positions, 2000);
			}

			init();
		}
  • Internet Explorer 9 и ниже.

А вот и пример

Перевод статьи Cool Canvas Particles Text Effect с сайта cssdeck.com, автор Rishabh.

P.S. Это тоже может быть интересно:

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Получать новые комментарии по электронной почте. Вы можете подписаться без комментирования.