(обн. )
Клевый эффект для текста из частиц на 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. Это тоже может быть интересно: