Mousedrag objects

I recently started looking into classes with a little help from the coding train, so I’m trying to rewrite a project with classes in hopes of making it simpler. Now I’m stuck with this problem: I want the user to drag around single letters along the x axis. But the letters can’t go to any random place, but can only move within 32 columns distributed equally along the canvas. In the drag() function, the x value of the constructor function changes based on the mouse position, but that doesn’t change the actual position of the chosen letter. Am I even on the right path?

https://editor.p5js.org/RBvonRB/sketches/KAKkX1KKy

Thanks for any help!

1 Like

now the first click anywhere on the canvas gives a ERROR

a click on a character prints its index, but it should show more,
like change the color of the selected character,
or draw its detection rectangle.

the drag does not work

i see a conflict that the click is outside the class
( and the character does not know about it )
and the drag inside.

1 Like

you never pass anything to the drag function of the letter class and so it is calculating on an undefined variable. beyond that you never update the position of the letter according to the newly calculated indexPos. here’s a working version but i think you will want to go back and rewrite alot of this code there is a lot of unnecessary and/or unwieldy stuff happening

var letter = [];

var universRom;
var textSz = 36;
var txt = 'firstnamelast';
var columns = 32;
var clickedLetter;

let allPos = [];
let randomIndex = [];

function preload() {
  universRom = loadFont('assets/universRom.otf');
}

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

  
  //array with random positions between 0 and 32
  for (let i = 0; i < columns; i++) {
    allPos[i] = i;
  }
  for (let i = 0; i < txt.length; i++) {
    let rand = floor(random(allPos.length));
    let remove = allPos.splice(rand, 1);
    randomIndex.push(remove);
  }
  randomIndex.sort(compareNumbers);
  randomIndex[0] = 0;
  randomIndex[txt.length - 1] = columns- 1;
  for (let i = 0; i < txt.length; i++) {
    letter[i] = new Letter(randomIndex[i], i);
  }
  
}

function draw() {
  background(255, 100, 100);

  for (let i = 0; i < txt.length; i++) {
    letter[i].display();
    letter[i].borders();
    letter[i].mouseOver(mouseX, mouseY);
  }
}

function mousePressed() {
  for (let i = txt.length - 1; i >= 0; i--) {
    if (letter[i].mouseOver(mouseX, mouseY)) {
      clickedLetter = i;
      console.log('clickedLetter: ' + clickedLetter);
    }
  }
}

function mouseDragged() {
  letter[clickedLetter].drag(mouseX);
}

class Letter {
  constructor(tempIndexPos, tempIndexChar) {
    this.textSz = 18;
    this.dist = width / columns;
    this.indexPos = tempIndexPos;
    this.x = this.indexPos * this.dist;
    this.y = 60;
    this.indexChar = tempIndexChar;
    this.letterW = this.textSz * 0.7;
    this.letterH = this.textSz * 0.8;
    this.clickMargin = 2;
  }

//area of each letter where interaction is possible
  borders() {
    this.top = this.y - this.letterH;
    this.bot = this.y + this.clickMargin;
    this.left = this.x - this.clickMargin;
    this.right = this.x + this.letterW;
  }

//mouse is over letter
  mouseOver(clickX, clickY) {
    if (clickX > this.left && clickX < this.right && clickY > this.top && clickY < this.bot) {
      return true;
    } else {
      return false;
    }
  }

  //drag letter
  drag(xIndicator) {
    /* this.mouseIndex = floor(map(constrain(xIndicator, 0, width), 0, width, 0, columns));*/
     
    this.indexPos = floor(xIndicator / columns);
    this.x = this.indexPos * this.dist;
  }

  //display letter
  display() {
    textFont(universRom);
    textSize(this.textSz);
    fill(0);
    text(txt.charAt(this.indexChar), this.x, this.y)
  }
}

function compareNumbers(a, b) {
  return a - b;
}

1 Like

Thanks! fixed the error message with an if statement

Thanks, this works! But I did pass the mouseX from the mouseDragged function to the drag function. But I guess that didn’t work because the position was never updated.

Anything in particular that I could leave out? As I said, first time working with classes, so making the whole thing a class might even be unnecessary…