-->

How to fill text with particles using p5js

2019-09-14 16:47发布

问题:

I want to fill a text with particles like this

I tried to do this using p5.js but I am stuck where the particles are only appearing on the edges. Any idea to accomplish this rather than having it on the edges?

Here is my attempt. Thanks a ton in advance :)

SteeringDemo.html

<body>
<script>
var font;
var vehicles=[];
var x=1360;
var y=400;
function preload() {
    font=loadFont('Poppins-Medium.ttf')
}
function setup() {
    var canvasDiv = document.getElementById('canvas');
    var width = canvasDiv.offsetWidth;
    var sketchCanvas = createCanvas(width,450);
    console.log(sketchCanvas);
    sketchCanvas.parent("canvas");
    background('#fff');

    var points=font.textToPoints('B',x/3,y/2,240);
    console.log(points);
    for(i=0;i<points.length;i++){
        var pt=points[i];
        var vehicle = new Vehicle(pt.x, pt.y);
        vehicles.push(vehicle);
    }
}
function draw() {
    background('#fff');
    for(var i=0; i< vehicles.length;i++){
        var v=vehicles[i];
        v.behaviors();
        v.update();
        v.show();
    }
}
</script>
<div class="container">
<div class="row">
    <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
        <div id="canvas"></div>
    </div>
</div>
</div>
</body>

Vehicle.js

function Vehicle(x,y) {
  this.pos= createVector(random(width),random(height));
  this.target=createVector(x,y);
  this.vel= p5.Vector.random2D();
  this.acc= createVector();
  this.radius=8;
  this.maxspeed=10;
  this.maxForce=1;
}
Vehicle.prototype.behaviors=function () {
  var arrive=this.arrive(this.target);
  var mouse= createVector(mouseX,mouseY);
  var flee=this.flee(mouse);
  arrive.mult(1);
  flee.mult(5);
  this.applyForce(arrive);
  this.applyForce(flee);
}
Vehicle.prototype.applyForce =function (f) {
  this.acc.add(f);
}
Vehicle.prototype.update=function () {
  this.pos.add(this.vel);
  this.vel.add(this.acc);
  this.acc.mult(0);
}
Vehicle.prototype.show=function () {
  stroke('#0097a7');
  strokeWeight(4);
  point(this.pos.x,this.pos.y);
}
Vehicle.prototype.arrive= function (target) {
  var desired=p5.Vector.sub(target,this.pos);
  var d=desired.mag();
  var speed=this.maxspeed;
  if(d < 100) {
    speed=map(d,0,100,0,this.maxspeed)
  }
  desired.setMag(speed);
  var steer=p5.Vector.sub(desired,this.vel);
  steer.limit(this.maxForce);
  return steer;
}

Vehicle.prototype.flee= function (target) {
  var desired=p5.Vector.sub(target,this.pos);
  var d= desired.mag();
  if(d <50) {
    desired.setMag(this.maxspeed);
    desired.mult(-1);
    var steer=p5.Vector.sub(desired,this.vel);
    steer.limit(this.maxForce);
    return steer;
  } else {
    return createVector(0,0);
  }
 }

回答1:

Though you could but, you don't have to use p5*js to achieve that animation. Fortunately, I've came across a javascript library called Particle Slider and as it turns out, yalantis also using the same library for their animation.

Here is how you could accomplish such animation using that library.

let init = () => {
    PS.renderText({
        text: 'B',
        fontFamily: 'Arial',
        fontSize: 200,
        fontColor: '#00E2FA',
        fontWeight: 'bold'
    });
    var myPS = new ParticleSlider({
        ptlGap: 3,
        ptlSize: 1,
        mouseForce: 70
    });
    window.onresize = () => {
        myPS.width = window.innerWidth;
        myPS.height = window.innerHeight;
    }
}
window.onload = init;
html, body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-color: black;
}
<script src="https://istack.000webhostapp.com/PS.js"></script>
<!-- DO NOT CHANGE ANYTHING AFTER THIS LINE -->
<div class="slides">
    <div class="slide"> </div>
</div>
<canvas class="draw"></canvas>
<!-- DO NOT CHANGE ANYTHING BEFORE THIS LINE -->

Yes! It's really that easy :)

also, checkout a demo on jsFiddle

for future reference always refer to the official documentation