有没有办法在 p5.js 中正确分隔文本字符串?

Luc*_*sio 5 javascript processing p5.js

我多次看到非常酷的动态排版示例。在这些例子中,每个字母都是一个粒子。文本是一个粒子系统,它可能会受到各种力,例如重力甚至离心力。这些系统是在 Processing 和 p5.js 中制作的。

受这些动态排版示例的启发,我正在使用 p5.js 为网络构建一个充满文本的交互式屏幕。当用户在文本上移动光标时,这个开始在屏幕上反弹。

我将草图从 Processing 翻译成 p5.js,我注意到这个问题与 setup() 函数中的文本间距有关。在 Processing 中,代码看起来像这样,并且运行正常。

我想专注于处理代码的这一部分:

 void setup() {
 size(640, 360);
 //load the font
 f = createFont("Arial", fontS, true);
 textFont(f);
 // Create the array the same size as the String
 springs = new Spring[message.length()]; 
 // Initialize Letters (Springs) at the correct x location
 int locx = 40;
 //initialize Letters (Springs) at the correct y location
 int locy = 100;
  for (int i = 0; i < message.length(); i++) {
  springs[i] = new Spring(locx, locy, 40, springs, i, message.charAt(i)); 
  locx += textWidth(message.charAt(i));
   //boudaries of text just to make it a nice "go to head"
   if (locx >= 360) {
   locy+=60;
   locx = 40;
   }
  }
}
Run Code Online (Sandbox Code Playgroud)

你可以看到结果 在这张图片中

正如你所看到的参数

   springs[i] = new Spring(locx, locy, 40, springs, i, message.charAt(i));    
   locx += textWidth(message.charAt(i));
Run Code Online (Sandbox Code Playgroud)

完成它的工作,将字母间隔开。

然而,当我在 P5.js 中翻译这个草图时,我没有得到同样好的间距。这是相同的部分,但是 p5.js 代码:

  function setup() {
  createCanvas(640, 360);
  noStroke();
  textAlign(LEFT);
  // Create the array the same size as the String
  springs = new Array(message.length);
  // Initialize Letters (Springs) at the correct x location
  var locx = 10;
  //initialize Letters (Springs) at the correct y location
  var locy = 120;
   for (var i = 0; i < message.length; i++) {
   springs[i] = new Spring(locx, locy, 40, springs, i, message.charAt(i));
   locx += textWidth(message.charAt(i));
   //boudaries of text just to make it a nice "go to head"
    if(locx>= 390){
    locy+= 60;
    locx= 40;
    }
   }  
  }
Run Code Online (Sandbox Code Playgroud)

结果显示

在这张图片中

我确信,在 p5js 代码中,这部分存在问题:

springs[i] = new Spring(locx, locy, 40, springs, i, message.charAt(i));
locx += textWidth(message.charAt(i));
Run Code Online (Sandbox Code Playgroud)

因为我试图通过乘以 locx 的值来修复它,如下所示:

springs[i] = new Spring(locx*5, locy, 40, springs, i, message.charAt(i));
Run Code Online (Sandbox Code Playgroud)

然后我得到了

这个结果

这似乎是正确的,但我确定它不是。

在这一点上我不知道如何修复它,它一定是我不知道的 p5.js 的东西。非常感谢任何帮助。

//编辑这里的评论中建议您可以找到用p5.js编写的Spring类:

    // Spring class
class Spring {
  constructor (_x, _y, _s, _others, _id, letter_) {
    // Screen values
    this.x_pos = this.tempxpos = _x;
    this.y_pos = this.tempypos = _y;
    this.size = _s;
    this.over = false;
    this.move = false;

    // Spring simulation constants
    this.mass =  8.0;       // Mass
    this.k = 0.2;    // Spring constant
    this.damp =0.98;       // Damping
    this.rest_posx = _x;  // Rest position X
    this.rest_posy = _y;  // Rest position Y

    // Spring simulation variables
    //float pos = 20.0; // Position
    this.velx = 0.0;   // X Velocity
    this.vely = 0.0;   // Y Velocity
    this.accel = 0;    // Acceleration
    this.force = 0;    // Force

    this.friends = _others;
    this.id = _id;

    this.letter = letter_;
    

  }
    update() {

      if (this.move) {
        this.rest_posy = mouseY;
        this.rest_posx = mouseX;
      }

      this.force = -this.k * (this.tempypos - this.rest_posy);  // f=-ky
      this.accel = this.force / this.mass;  // Set the acceleration, f=ma == a=f/m
      this.vely = this.damp * (this.vely + this.accel);         // Set the velocity
      this.tempypos = this.tempypos + this.vely;           // Updated position


      this.force = -this.k * (this.tempxpos - this.rest_posx);  // f=-ky
      this.accel = this.force / this.mass; // Set the acceleration, f=ma == a=f/m
      this.velx = this.damp * (this.velx + this.accel);  // Set the velocity
      this.tempxpos = this.tempxpos + this.velx; // Updated position


      if ((this.overEvent() || this.move) && !(this.otherOver()) ) {
        this.over = true;
      } else {
        this.over = false;
      }
    }

    // Test to see if mouse is over this spring
    overEvent() {
      let disX = this.x_pos - mouseX;
      let disY = this.y_pos - mouseY;
      let dis = createVector(disX, disY);
      if (dis.mag() < this.size / 2 ) {
        return true;
      } else {
        return false;
      }
    }

    // Make sure no other springs are active
    otherOver() {
      for (let i = 0; i < message.length; i++) {
        if (i != this.id) {
          if (this.friends[i].over == true) {
            this.velx = -this.velx;
            return true;
          }
        }
      }
      return false;
    }
    //the springs collides with the edges of the screen 
    box_collision() {
  if(this.tempxpos+this.size/2>width){
  this.tempxpos = width-this.size/2;
  this.velx =  -this.velx;
  } else if (this.tempxpos - this.size/2 < 0){
  this.tempxpos = this.size/2;
  this.velx = -this.velx;
  }
  if (this.tempypos+this.size/2>height) {
  this.tempypos = height-this.size/2;
  this.vely = -this.vely;
  } else if (this.tempypos- this.size/2 < 0) {
  this.tempypos = this.size/2;
  this.vely = -this.vely;
  }
}
    //the springs collides with each other
    collide() {
      for (var i = this.id + 1; i < message.length; i++) {

        var dx = this.friends[i].tempxpos - this.tempxpos;
        var dy = this.friends[i].tempypos - this.tempypos;
        var distance = sqrt(dx*dx + dy*dy);
        var minDist = this.friends[i].size/2 + this.size/2;

        if (distance < minDist) { 
          var angle = atan2(dy, dx);
          var targetX = this.tempxpos + cos(angle) * minDist;
          var targetY = this.tempypos + sin(angle) * minDist;
          var ax = (targetX - this.friends[i].tempxpos) * 0.01;
          var ay = (targetY - this.friends[i].tempypos) * 0.01;
          this.velx -= ax;
          this.vely -= ay;
          this.friends[i].velx += ax;
          this.friends[i].vely += ay;
        }
      }
    }
  //display the letter Particle
    display() {
      if (this.over) {
        fill(255, 0, 0);
      } else {
        fill(255);
      }
      noStroke();
      textSize(fontS);
      //for debugging
      // ellipse(this.tempxpos, this.tempypos, this.size, this.size);
      text(this.letter, this.tempxpos, this.tempypos);
    }

    pressed() {
      if (this.over) {
        this.move = true;
      } else {
        this.move = false;
      }
    }

    released() {
      this.move = false;
      this.rest_posx = this.x_pos;
      this.rest_posy = this.y_pos;
    }
} 
Run Code Online (Sandbox Code Playgroud)

在这里你可以找到指向 P5.js 编辑器的链接,代码如下: Spring text p5js code

注意:我必须修复 Spring 类,因为我没有意识到我的所有函数都在构造函数中初始化。现在组成类的函数在构造函数之外。我仍然没有想出如何解决间距问题。

Luc*_*sio 2

我设法解决了这个问题。

据我了解,代码从一开始就是正确的。

我在整个旅程中错过的是,如果我想在屏幕上正确显示文本,我必须在函数 setup() 中设置字体大小。

在此输入图像描述

您仍然可以通过检查我之前发布的 p5.js 编辑器的链接来查看结果。