#javascript #processing #p5.js
#javascript #обработка #p5.js
Вопрос:
Я много раз видел действительно классные примеры кинетической типографики. В этих примерах каждая буква является частицей. Текст представляет собой систему частиц, и на него могут воздействовать различные силы, такие как гравитация или даже центробежная сила. Эти системы изготавливаются в процессе обработки и в p5.js .
Я создаю интерактивный экран для Интернета, заполненный текстом, используя p5.js , вдохновленный этим примером кинетической типографики. Когда пользователь наводит курсор на текст, он начинает подпрыгивать по всему экрану.
Я перевел эскиз с обработки на 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 Я об этом не знаю. Любая помощь будет очень признательна.
// Редактировать, как предложено в комментарии, здесь вы можете найти класс Spring, написанный на p5.js:
// 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) amp;amp; !(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 редактор с кодом:
Весенний текстовый код p5js
примечание: мне пришлось исправить класс Spring, потому что я не понимал, что все мои функции инициализируются в конструкторе. Теперь функции, составляющие класс, находятся вне конструктора. Я все еще не понял, как решить проблему с интервалом.
Комментарии:
1. Где
Spring
определен класс?2. @Samathingamajig Класс определяется вне функций setup() и draw(). Это длинный фрагмент кода, если он может быть полезен для решения проблемы, я отредактирую этот пост.
3. Да, это очень важно. Кроме того, пожалуйста, добавьте для нас ссылку на веб-редактор p5 (но не удаляйте код из этого сообщения, просто добавьте эту ссылку в конце)
4. @Samathingamajig Я добавил класс Spring и ссылку на веб-редактор p5 с кодом.
Ответ №1:
Мне удалось решить проблему.
Насколько я понял, код был правильным с самого начала.
Что я пропустил во время путешествия, так это то, что мне нужно установить размер шрифта в функции setup(), если я хочу правильно отображать текст на экране.
Вы все равно можете увидеть результат, проверив ссылку на p5.js редактор, которого я опубликовал ранее.