Position algorithm problem in for loop

ezgif.com-gif-maker (22)

The current state is as shown in the figure, with “a” as the axis of movement, how to move with “d” as the axis in the current cycle?

Here’s the current code, thanks for your help!

function setup() {
  createCanvas(400, 400);
}

function draw() {
  background(220);
  
  let tSize = 40;
  let distance = map(sin(frameCount * 0.04), -1, 1, 0, 80);
  leftAlign("abcd", 100, height/2, distance, tSize);
  
}

function leftAlign(strings, posX, posY, distance, tSize) {
  noStroke();
  textSize(tSize);
  push();
  translate(posX, posY);
  for (let i = 0; i < strings.length; i++) {
    let x = i * distance;
    text(strings[i], x, 0);
  }
  pop();
}

I tried to write a new function to achieve the desired effect, by rearranging the content array.

ezgif.com-gif-maker (23)

function rightAlign(strings, posX, posY, distance, tSize) {
  let stringsArray = strings.split("").reverse();
  noStroke();
  textSize(tSize);
  push();
  translate(posX, posY);
  for (let i = 0; i < strings.length; i++) {
    let x = -i * distance;
    text(stringsArray[i], x, 0);
  }
  pop();
}

But how can we achieve this effect through the positional algorithm without changing the order of the array.

This line must be different for each letter

Therefore move it to the function

1 Like

The axis element is determined when parameter distance is multiplied by 0:
const x = i * distance;

Variable i is both the loop iterator’s current value & string’s current index.

So when i is 0 we have element “a”, which makes the multiplication w/ parameter distance equal to 0.

In order to change the axis element to “d”, which is the last index, we need to decouple current string index from current iterator value:
const idx = abs(strings.length - 1 - i), x = i * distance;

Now we have a separate idx variable which is the inverse of i.

When current i is 0, idx is 3. And when current i is 3, idx is 0.

Thus idx = 3 is our new axis, b/c that’s when i = 0!

Check it out the changes I’ve made to your original sketch:

// Discourse.Processing.org/t/position-algorithm-problem-in-for-loop/40604/3
// (2023/Jan/16)

"use strict";

const TXT = 'abcd', STEP = .04, RANGE = 80, REVERSED = true;
var bg;

function setup() {
  createCanvas(400, 400);
  textSize(40).textAlign(CENTER, CENTER).noStroke();
  bg = color(220);
}

function draw() {
  background(bg);
  const dx = RANGE * norm(sin(frameCount * STEP), -1, 1);
  spreadText(TXT, 100, height >> 1, dx, REVERSED);
}

function spreadText(txt, x, y, dx, reversed = false) {
  const len = txt.length, axis = reversed? len - 1 : 0;

  if (reversed) {
    x = width - x;
    dx *= -1;
  }

  for (var i = 0; i < len; ++i) {
    const idx = abs(axis - i), px = i * dx + x;
    text(txt[idx], px, y);
  }
}
2 Likes

Thank you all for your help. I also thought of a solution and made an open source tool StringsAlign.js for p5js.

ezgif.com-gif-maker (24)

My English is very poor, and I haven’t had time to do the English version of the document. You can see the internals from the examples folder. :laughing:

3 Likes

Congratz for your new library! :confetti_ball: :books: :tada:

And I’ve got some small advices for it:

Your library’s CDN link is unnecessarily too big:

The @main part is totally optional:

<script src="https://cdn.JsDelivr.net/gh/hendasheng/StringsAlign-P5js/scripts/stringsAlign.js"></script>

Actually it’d be even better if you got rid of subfolder “/scripts” and moved file “/stringsAlign.js” to the repo’s root folder:

<script
  src="//cdn.JsDelivr.net/gh/hendasheng/StringsAlign-P5js/stringsAlign.js">
</script>

Another small detail is to rename subfolder “/example” to “/examples”. :wink:

That’s all for now. Cya! :smile_cat:

P.S.: BtW, you should post your library in the category “Gallery” as well.

2 Likes

Thanks for your advice! This helped me a lot, this is my first library and I don’t know much about libraries. I will continue to update in the future. :laughing:

1 Like