dragging objects in processing

徘徊边缘 提交于 2019-12-11 06:34:22

问题


I am having an issue implementing Daniel Shiffman's awesome dragging example into my sketch. I have used it before and it is great, however I am attempting to use it with some "fancy" for looping to apply it to multiple objects(in this case text) but to no avail. Everything works correctly except for the objects don't drag when they should. Logically, this makes since because the offsetX and offsetY properties in the Line class continue to update thus forcing the object to remain stationary. I am sure that there is a solution but I can't figure it out. Perhaps I have been staring at it for too long. I really appreciate the help!

String[] doc; //array of Strings from each text documents line
int tSize; //text size
float easing; //easing
int boundaryOverlap; //value for words to overlap edges by
PFont font; //font
Lines lines;
boolean clicked = false;

void setup(){
  size(displayWidth/2,displayHeight); 
  background(255);
  fill(0);

  boundaryOverlap = 20; //value for words to overlap edges by
  tSize = 32; //text size

  //loads and formats text
  doc = loadStrings("text.txt"); 
  font = loadFont("Times-Roman-48.vlw");
  textFont(font, tSize);

  //lines object
  lines = new Lines(doc);

  //populate xAddition and yAddition arrays
  lines.populateArrays();
}

void draw(){
  background(255);
  fill(0);

  //loops through each line in .txt
  for(int i = 0; i <= doc.length-1; i++){
    if(clicked) lines.clicked(i);
    lines.move(i, clicked); //update doc[i] positions //deletes 
    lines.display(i); //draws text for each line of text in text.txt
   }
}

void mousePressed(){
   clicked = true;
}

void mouseReleased(){
   clicked = false; 
   lines.dragging = false;
}

Here is the line class:

class Lines{
  //class properties
  float[] x; //array holding random values to be added to x for placement
  float[] y; //array holding random values to be added to y for placement
  float offsetX;
  float offsetY;
  String[] doc;

  boolean dragging = false; //boolean for dragging

  //construct
  Lines(String[] tempDoc){
    doc = tempDoc;
  }

  //fills x and y arrays
  void populateArrays(){
    x = new float[doc.length];
    y = new float[doc.length];

    //populates x and y arrays
    for(int i = 0; i <= doc.length-1; i++){   
      x[i] = int(random(0-boundaryOverlap, width-boundaryOverlap));
      y[i] = int(random(0, height-boundaryOverlap));
      }
  }

  //draws text
  void display(int i){
       text(doc[i], x[i], y[i]); //draw text
       //if(addition[i] != null) text(addition[i], x[i], y[i]+20);
  }


  void clicked(int i){
    if(mouseX > x[i] &&
       mouseX < x[i]+textWidth(doc[i]) &&
       mouseY < y[i] &&
       mouseY > y[i]-tSize){
       dragging = true;
       offsetX = x[i] - mouseX;
       offsetY = y[i] - mouseY;  
    }
  }

  //updates text positions
  void move(int i, boolean clicked){

       //if mouseOver text hover gray
       if( mouseX > x[i] &&
       mouseX < x[i]+textWidth(doc[i]) &&
       mouseY < y[i] &&
       mouseY > y[i]-tSize){

         fill(100); //gray text fill

         if(dragging){
           x[i] = mouseX + offsetX;
           y[i] = mouseY + offsetY;
         }

       }

       else{
         fill(0); //if not text not mouseOver fill is black
         dragging = false;
       }
  }

  //delete 
  void delete(int i){
    //if "delete" is pressed 
    if (keyPressed){
      if(key == 8){
        doc[i] = ""; // doc[line String that is being hovered over] is replaced with null
        keyCode = 1;
      }
    }
  }
}

回答1:


First off, don't use vlw fonts. There is literally no reason to use a bitmap image file when everyone has Times New Roman installed. Just use createFont("Times New Roman",48). Now you can even change the textsize without it looking horrible because you just loaded the font, not a bitmap image.

That said, this code isn't really all that good... but working with it, the problem is here:

  for(int i = 0; i <= doc.length-1; i++){
    if(clicked) lines.clicked(i);
    lines.move(i, clicked); //update doc[i] positions //deletes 
    lines.display(i); //draws text for each line of text in text.txt
  }

You check for clicked, and if so, mark the line as clicked. Then you completely disregard that and move all the lines, without looking at the "clicked" state (it is not used in the move function at all).

That said, what you're trying to do can be done much better, and much cleaner:

LineCollection lines;
float textSize;

void setup(){
  size(400,400);
  // fix the text size, reference a real font
  textSize = 32; 
  textFont(createFont("Times New Roman", textSize));
  // parse strings, construct Lines container
  String[] textValues = new String[]{"lol","cat"};
  lines = new LineCollection(textValues);
  // Do not loop! only update when events warrant,
  // based on redraw() calls  
  noLoop();
}
// fall through drawing
void draw() { background(255); lines.draw(); }
// fall through event handling
void mouseMoved() { lines.mouseMoved(mouseX,mouseY); redraw(); }
void mousePressed() { lines.mousePressed(mouseX,mouseY); redraw(); }
void mouseDragged() { lines.mouseDragged(mouseX,mouseY); redraw(); }
void mouseReleased() { lines.mouseReleased(mouseX,mouseY); redraw(); }


/**
 * A collection of lines. This is *only* a collecton,
 * it is simply responsible for passing along events.
 */
class LineCollection {
  Line[] lines;
  int boundaryOverlap = 20;

  // construct
  LineCollection(String[] strings){
    lines = new Line[strings.length];
    int x, y;
    for(int i=0, last=strings.length; i<last; i++) {
      x = (int) random(0, width);
      y = (int) random(0, height);
      lines[i] = new Line(strings[i], x, y);   
    }
  }

  // fall through drawing   
  void draw() {

    // since we don't care about counting elements
    // in our "lines" container, we use the "foreach"
    // version of the for loop. This is identical to
    // "for(int i=0; i<lines.size(); i++) {
    //    Line l = lines[i];
    //    [... use l here ...]
    //  }"
    // except we don't have to unpack our list manually.

    for(Line l: lines) { l.draw(); }
  }

  // fall through event handling
  void mouseMoved(int mx, int my) { for(Line l: lines) { l.mouseMoved(mx,my); }} 
  void mousePressed(int mx, int my) { for(Line l: lines) { l.mousePressed(mx,my); }} 
  void mouseDragged(int mx, int my) { for(Line l: lines) { l.mouseDragged(mx,my); }}
  void mouseReleased(int mx, int my) { for(Line l: lines) { l.mouseReleased(mx,my); }}
}

/**
 * Individual lines
 */
class Line {
  String s;
  float x, y, w, h;
  boolean active;
  color fillColor = 0;
  int cx, cy, ox=0, oy=0;

  public Line(String _s, int _x, int _y) {
    s = _s;
    x = _x;
    y = _y;
    w = textWidth(s);
    h = textSize;
  }

  void draw() {
    fill(fillColor);
    text(s,ox+x,oy+y+h);
  }

  boolean over(int mx, int my) {
    return (x <= mx && mx <= x+w && y <= my && my <= y+h);
  }

  // Mouse moved: is the cursor over this line?
  // if so, change the fill color
  void mouseMoved(int mx, int my) {
    active = over(mx,my);
    fillColor = (active ? color(155,155,0) : 0);
  }

  // Mouse pressed: are we active? then
  // mark where we started clicking, so 
  // we can do offset computation on
  // mouse dragging.
  void mousePressed(int mx, int my) {
    if(active) {
      cx = mx;
      cy = my;
      ox = 0;
      oy = 0; 
    }
  }

  // Mouse click-dragged: if we're active,
  // change the draw offset, based on the
  // distance between where we initially
  // clicked, and where the mouse is now.
  void mouseDragged(int mx, int my) {
    if(active) {
      ox = mx-cx;
      oy = my-cy;
    }
  }

  // Mouse released: if we're active,
  // commit the offset to this line's
  // position. Also, regardless of
  // whether we're active, now we're not.  
  void mouseReleased(int mx, int my) {
    if(active) {
      x += mx-cx;
      y += my-cy;
      ox = 0;
      oy = 0;
    }
    active = false;
  }
}

update

Explained the foreach version of "for" used in this code.



来源:https://stackoverflow.com/questions/15305722/dragging-objects-in-processing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!