【问题标题】:Is there a way to space correctly a string of text in p5.js?有没有办法在 p5.js 中正确分隔一串文本?
【发布时间】:2021-06-30 00:41:09
【问题描述】:

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

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

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

我想重点介绍一下处理代码的这一部分:

 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;
   }
  }
}

你可以看到结果

你可以看到参数

   springs[i] = new Spring(locx, locy, 40, springs, i, message.charAt(i));    
   locx += textWidth(message.charAt(i));

做它的工作,间隔字母。

但是,当我在 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;
    }
   }  
  }

结果显示

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

springs[i] = new Spring(locx, locy, 40, springs, i, message.charAt(i));
locx += textWidth(message.charAt(i));

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

springs[i] = new Spring(locx*5, locy, 40, springs, i, message.charAt(i));

然后我得到了

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

此时我不知道如何修复它,它一定是我不知道的 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;
    }
} 

您可以在这里找到 P5.js 编辑器的链接,其中包含以下代码: Spring text p5js code

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

【问题讨论】:

  • Spring 类在哪里定义?
  • @Samathingamajig 该类在 setup() 和 draw() 函数之外定义。是一段很长的代码,如果对解决问题有用,我会编辑这篇文章。
  • 是的,这很重要。另外,请为我们添加p5 web editor link链接(但不要从这篇文章中删除代码,只需在末尾添加此链接)
  • @Samathingamajig 我已经用代码添加了 Spring 类和 p5 网络编辑器链接。

标签: javascript processing p5.js


【解决方案1】:

我设法解决了这个问题。

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

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

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

【讨论】:

    猜你喜欢
    • 2019-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-02
    • 2011-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多