简体   繁体   中英

Filling shape with particles canvas

Just wondering if anyone could point me in a good direction to a way I could fill an irregular shape with particles, in rows, which would then be animatable.

This is the closest example i can find - http://www.wkams.com/#!/work/detail/coca-cola-music-vis

The two ways I can think would work is work out the density I want, map out how many particles would be needed for each row, and position accordingly. This way seems quite timely and not very robust.

The second way, which I can't seem to figure out how I would do it, is draw the shape in the canvas, then generatively fill the shape with particles, keeping them in the constraints of the shape.

Any general concept of how this could be done would be greatly appreciated.

Let me know if it doesn't make sense.

Cheers

You can use compositing to restrict your particles inside an irregular shape

在此处输入图片说明在此处输入图片说明

For each loop of your animation:

  • Clear the canvas.

  • Draw your irregular shape on the canvas.

  • Set compositing to 'source-atop'. This will cause any new drawings to appear only if any newly drawn pixel is over an existing opaque pixel . This is the secret to restricting your particles to be drawn only inside your irregular shape.

  • Draw your rows of particles. All particles will appear only inside the shape.

Here's example code and a Demo. My example just animates the size of each particle row. You can apply your design requirements to change the size & position of each row.

 var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); var cw=canvas.width; var ch=canvas.height; // ctx.fillStyle='skyblue'; var PI2=Math.PI*2; // var w=132; var h=479; // var x1=29; var x2=177; var x3=327; // var nextTime=0; var delay=16*2; var isFading=true; var isComplete=false; var opacity=100; var imgCount=2; var img=new Image();img.onload=start;img.src="https://dl.dropboxusercontent.com/u/139992952/multple/coke.png"; var label=new Image();label.onload=start;label.src="https://dl.dropboxusercontent.com/u/139992952/multple/label.png"; function start(){ console.log(imgCount); if(--imgCount>0){return;} requestAnimationFrame(animate); $('#again').click(function(){ nextTime=0; delay=16*2; opacity=100; isFading=true; }); } function overlay(clipX,x,alpha){ ctx.globalAlpha=alpha; ctx.drawImage(img,clipX,0,w,h,x,0,w,h); } function fillParticles(radius,margin){ var rr=radius*2+margin; ctx.save(); ctx.clearRect(0,0,cw,ch); overlay(x3,50,1.00); ctx.globalCompositeOperation='source-atop'; ctx.beginPath(); var rows=parseInt(ch/(rr))-2; var cols=parseInt(cw/rr); for(var r=0;r<rows;r++){ for(var c=0;c<cols;c++){ ctx.arc(c*rr,h-(r*rr),radius,0,PI2); ctx.closePath(); }} ctx.fill(); ctx.restore(); overlay(x2,50,1.00); } function animate(time){ if(!isComplete){ requestAnimationFrame(animate); } if(time<nextTime){return;} if(isFading){ if(--opacity>0){ ctx.clearRect(0,0,cw,ch); overlay(x1,50,opacity/100); overlay(x2,50,1.00); }else{ isFading=false; overlay(x2,50,1.00); ctx.drawImage(label,70,210); nextTime=time+1000; } }else{ delay=1000; fillParticles(parseInt(Math.random()*8)+2,3); ctx.drawImage(label,70,210); nextTime=time+delay; } } 
 body{ background-color:white; padding:10px; } #canvas{border:1px solid red;} 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <button id=again>Again</button> <br> <canvas id="canvas" width=250 height=500></canvas> 

If I were to approach this problem, I would go about it in this way:

  1. Create an object that can be used to "create" particles.
  2. Create as many new instances of that object as is needed for the required density.

So, basically, all the work is done by one function constructor/object.

You want this object to provide methods to draw itself to the canvas, store its x and y coordinates, its velocity and direction.

Then you can create instances of this object with the new keyword and set their x and y coordinates to spread them across a grid.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM