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 类,因为我没有意识到我的所有函数都在构造函数中初始化。现在组成类的函数在构造函数之外。我仍然没有想出如何解决间距问题。
我设法解决了这个问题。
据我了解,代码从一开始就是正确的。
我在整个旅程中错过的是,如果我想在屏幕上正确显示文本,我必须在函数 setup() 中设置字体大小。
您仍然可以通过检查我之前发布的 p5.js 编辑器的链接来查看结果。