用处理创建自定义图纸工具

发布于 2025-01-19 23:22:25 字数 980 浏览 2 评论 0 原文

我目前正在处理中编写一种绘图工具。我希望能够用鼠标绘制一条黑线,但让它再次消失。为此,我首先想到使用从黑色渐变为白色的黑色椭圆。然后,该椭圆通过 mouseX 和 mouseY 链接到鼠标指针。因为我希望每个绘制的椭圆单独从黑色淡入白色(以创建线条再次淡出的效果),所以我想到了使用对象。到目前为止这是有效的,但是褪色还没有起作用。 我希望鼠标指针处的椭圆始终为黑色,然后只有在鼠标指针进一步移动或进一步绘制时才变为白色...就像淡入淡出一样...

我应该为此使用 ArrayList 吗?并说应该在每帧的 MouseX 和 MouseY 位置绘制一个新对象?我需要 PVector 吗?

到目前为止,这就是我的想法:

float counter;
PGraphics pg;

Brush myBrush;

void setup() {
  size(600, 600);
  pg = createGraphics(width, height);
}


void draw() {
  //background(255);
  color from = color(0);
  color to = color(255);
  color faded = lerpColor(from, to, counter);
  myBrush = new Brush(faded, mouseX, mouseY); 
  myBrush.display();
}

class Brush {
  color tempC;
  float xpos;
  float ypos;
  color c;

  Brush(color tempC, float tempXpos, float tempYpos) {
    c = tempC;
    xpos = tempXpos;
    ypos = tempYpos;
  }
  void display() {
    noStroke();
    fill(c);
    ellipse(xpos, ypos, 50, 50);
    counter = counter + 0.01;
  }
}

I am currently in the process of coding a kind of drawing tool in Processing. I want to be able to draw a black line with the mouse, but have it fade away again. For this I first thought of working with a black ellipse that fades from black to white. This ellipse is then linked to the mouse pointer via mouseX and mouseY. Because I want each drawn ellipse to fade from black to white individually (to create the effect that the line fades again), I thought of working with objects. This works so far, but the fading does not work yet.
I want the ellipse at the mouse pointer to always be black and then only change to white once the mouse pointer has been moved further or drawn further... just like a fade...

Should I use an ArrayList for this? And say that a new object should be drawn at the MouseX and MouseY position per frame? Do I need PVector for this?

This is what I came up for this so far:

float counter;
PGraphics pg;

Brush myBrush;

void setup() {
  size(600, 600);
  pg = createGraphics(width, height);
}


void draw() {
  //background(255);
  color from = color(0);
  color to = color(255);
  color faded = lerpColor(from, to, counter);
  myBrush = new Brush(faded, mouseX, mouseY); 
  myBrush.display();
}

class Brush {
  color tempC;
  float xpos;
  float ypos;
  color c;

  Brush(color tempC, float tempXpos, float tempYpos) {
    c = tempC;
    xpos = tempXpos;
    ypos = tempYpos;
  }
  void display() {
    noStroke();
    fill(c);
    ellipse(xpos, ypos, 50, 50);
    counter = counter + 0.01;
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

芯好空 2025-01-26 23:22:25

您在这里遇到的问题是,您只能知道如何在绘制线条后淡出线条,但您是在用户移动鼠标时绘制它的。

为了解决这个问题,我建议将绘制线条所需的所有信息存储在对象中,并在用户绘制时更新它。正如您所猜测的,您完全可以使用 ArrayList 来实现此目的。

Faaaading

不止一行

我对你的代码进行了大量修改以简化我自己的生活,我对结果进行了评论,这样就可以了您可以更轻松地按照自己的方式将其重新构建到您自己的项目中。

我用物品来保持一切整洁。这里的逻辑如下:Canvas 对象包含绘图。它由 Line 对象组成,而线对象本身又由 Dots 组成。

这是注释的代码:

Canvas canvas;

void setup() {
  size(600, 600);
  canvas = new Canvas();
}

void draw() {
  // instead of drawing only once, we're going to save every line the user draw in teh canvas object
  background(255);

  // the canvas object has to calculate stuff, then display itself
  canvas.Update();
  canvas.Display();
}

// setting up the mousePressed and mouseReleased events so the canvas object "knows"
void mousePressed() {
  canvas.mouseDown = true;
}
void mouseReleased() {
  canvas.mouseReleased = true;
  canvas.mouseDown = false;
}

class Canvas {
  boolean mouseDown;
  boolean mouseReleased = true;
  ArrayList<Line> lines = new ArrayList<Line>(); // every line will be stored in this list
  Brush brush; // the brush object can be modified with different sizes or colors

  Canvas() {
    // here i use a default brush, but you can experiment different colors or sizes
    brush = new Brush(color(0, 200, 0), color(0), color(255), 50);
  }

  void Update() {
    brush.highlight = mouseDown; // so the user has visual feedback while drawing

    if (mouseDown) {      
      if (mouseReleased) { // if this is a "new" line, add a line object to store it
        lines.add(new Line(brush.colorFrom, brush.colorTo));
        mouseReleased = false;
      }
      // add a dot at the mouse's current position, then update the fading
      lines.get(lines.size()-1).Add(new Dot(mouseX, mouseY, brush.diameter, brush.colorFrom));
      lines.get(lines.size()-1).ApplyFade();
    }
  }

  void Display() {
    // for every Line, draw every Dot... then don't forget to display the brush!
    for (Line l : lines) {
      for (Dot d : l.dots) {
        d.Display();
      }
    }
    brush.Display();
  }
}

// A line is a bunch of dots and two colord (for the fade effect)
class Line {
  ArrayList<Dot> dots = new ArrayList<Dot>();
  color colorFrom, colorTo;

  Line(color colorFrom, color colorTo) {
    this.colorFrom = colorFrom;
    this.colorTo = colorTo;
  }

  void Add(Dot d) {
    dots.add(d);
  }

  // This method calculate how many dots there are in the line to better distribute the shades of the fade
  void ApplyFade() {
    for (int i=0; i<dots.size(); i++) {
      Dot d = dots.get(i);
      d.c = lerpColor(colorFrom, colorTo, (float) i/dots.size());
    }
  }
}

// a Dot has a size, a position and a color
class Dot {
  float xpos;
  float ypos;
  float diameter;
  color c;

  Dot(float xpos, float ypos, float diameter, color c) {
    this.xpos = xpos;
    this.ypos = ypos;
    this.diameter = diameter;
    this.c = c;
  }

  void Display() {
    noStroke();
    fill(c);
    ellipse(xpos, ypos, diameter, diameter);
  }
}

// this class is overdesigned so in the future you can change the brush's characteristics like the fade'S colors or simply it's size
class Brush {
  boolean highlight;
  float diameter, xpos, ypos;
  color circleColor, colorFrom, colorTo;

  Brush(color circleColor, color colorFrom, color colorTo, float diameter) {
    this.circleColor = circleColor;
    this.colorFrom = colorFrom;
    this.colorTo = colorTo;
    this.diameter = diameter;
  }

  void Display() {
    stroke(circleColor);
    strokeWeight(5);
    noFill();
    ellipse(mouseX, mouseY, diameter, diameter);
    if (highlight) { // if the mouse's button is down, give visual feedback about the brush
      stroke(0);
      strokeWeight(4);
      ellipse(mouseX, mouseY, diameter, diameter);
      stroke(255);
      strokeWeight(3);
      ellipse(mouseX, mouseY, diameter, diameter);
    }
  }
}

希望这有帮助。如果您对代码有疑问,我会在场。玩得开心!

The issue you're struggling with here is that you can only know how to fade the line once the line has been drawn, but you draw it while the user move the mouse.

To deal with this issue, I would suggest to store every information needed to draw the line in an object, and update it as the user is drawing. As you guessed, you could totally use an ArrayList to achieve this.

Faaaading

More than one line

I modified your code quite heavily to simplify my own life, and I commented the result so it would be easier for you to re-cast it into your own project on your own terms.

I used objects to keep everything tidy. The logic here goes as follow: The Canvas object contains the drawing. It's made of Line objects, which are themselves made of Dots.

Here's the commented code:

Canvas canvas;

void setup() {
  size(600, 600);
  canvas = new Canvas();
}

void draw() {
  // instead of drawing only once, we're going to save every line the user draw in teh canvas object
  background(255);

  // the canvas object has to calculate stuff, then display itself
  canvas.Update();
  canvas.Display();
}

// setting up the mousePressed and mouseReleased events so the canvas object "knows"
void mousePressed() {
  canvas.mouseDown = true;
}
void mouseReleased() {
  canvas.mouseReleased = true;
  canvas.mouseDown = false;
}

class Canvas {
  boolean mouseDown;
  boolean mouseReleased = true;
  ArrayList<Line> lines = new ArrayList<Line>(); // every line will be stored in this list
  Brush brush; // the brush object can be modified with different sizes or colors

  Canvas() {
    // here i use a default brush, but you can experiment different colors or sizes
    brush = new Brush(color(0, 200, 0), color(0), color(255), 50);
  }

  void Update() {
    brush.highlight = mouseDown; // so the user has visual feedback while drawing

    if (mouseDown) {      
      if (mouseReleased) { // if this is a "new" line, add a line object to store it
        lines.add(new Line(brush.colorFrom, brush.colorTo));
        mouseReleased = false;
      }
      // add a dot at the mouse's current position, then update the fading
      lines.get(lines.size()-1).Add(new Dot(mouseX, mouseY, brush.diameter, brush.colorFrom));
      lines.get(lines.size()-1).ApplyFade();
    }
  }

  void Display() {
    // for every Line, draw every Dot... then don't forget to display the brush!
    for (Line l : lines) {
      for (Dot d : l.dots) {
        d.Display();
      }
    }
    brush.Display();
  }
}

// A line is a bunch of dots and two colord (for the fade effect)
class Line {
  ArrayList<Dot> dots = new ArrayList<Dot>();
  color colorFrom, colorTo;

  Line(color colorFrom, color colorTo) {
    this.colorFrom = colorFrom;
    this.colorTo = colorTo;
  }

  void Add(Dot d) {
    dots.add(d);
  }

  // This method calculate how many dots there are in the line to better distribute the shades of the fade
  void ApplyFade() {
    for (int i=0; i<dots.size(); i++) {
      Dot d = dots.get(i);
      d.c = lerpColor(colorFrom, colorTo, (float) i/dots.size());
    }
  }
}

// a Dot has a size, a position and a color
class Dot {
  float xpos;
  float ypos;
  float diameter;
  color c;

  Dot(float xpos, float ypos, float diameter, color c) {
    this.xpos = xpos;
    this.ypos = ypos;
    this.diameter = diameter;
    this.c = c;
  }

  void Display() {
    noStroke();
    fill(c);
    ellipse(xpos, ypos, diameter, diameter);
  }
}

// this class is overdesigned so in the future you can change the brush's characteristics like the fade'S colors or simply it's size
class Brush {
  boolean highlight;
  float diameter, xpos, ypos;
  color circleColor, colorFrom, colorTo;

  Brush(color circleColor, color colorFrom, color colorTo, float diameter) {
    this.circleColor = circleColor;
    this.colorFrom = colorFrom;
    this.colorTo = colorTo;
    this.diameter = diameter;
  }

  void Display() {
    stroke(circleColor);
    strokeWeight(5);
    noFill();
    ellipse(mouseX, mouseY, diameter, diameter);
    if (highlight) { // if the mouse's button is down, give visual feedback about the brush
      stroke(0);
      strokeWeight(4);
      ellipse(mouseX, mouseY, diameter, diameter);
      stroke(255);
      strokeWeight(3);
      ellipse(mouseX, mouseY, diameter, diameter);
    }
  }
}

Hope this helps. I'll be around if you have questions about the code. Have fun!

忘羡 2025-01-26 23:22:25

这是一个带有阵列列表和对象的版本...这里的问题是所有椭圆对象同时逐渐消失...我想实现每个椭圆都首先绘制的黑色,然后在时间x变为白色之后。例如。多变的...

float counter;
PGraphics pg;
ArrayList<PVector> positionsList;

Brush myBrush;

void setup() {
  size(600, 600);
  positionsList = new ArrayList<PVector>();
  pg = createGraphics(width, height);
}


void draw() {
  background(255);
  color from = color(0);
  color to = color(255);
  color faded = lerpColor(from, to, counter);

  for (PVector p : positionsList) {
    myBrush = new Brush(faded, p.x, p.y);
   myBrush.display();
 
  }
    positionsList.add(new PVector(mouseX, mouseY));
      counter = counter + 0.01;
}

class Brush {
  color tempC;
  float xpos;
  float ypos;
  color c;

  Brush(color tempC, float tempXpos, float tempYpos) {
    
    
    
    c = tempC;
    xpos = tempXpos;
    ypos = tempYpos;
  }
  void display() {
    noStroke();
    fill(c);
    ellipse(xpos, ypos, 50, 50);
 
  }
}

Here is a version with an ArrayList and Object... The problem here is that all ellipse objects fade away at the same time... I would like to achieve that each ellipse is first drawn black and then after time X becomes white... Like a fingerprint on a sensor for example... A lot of pressure: black, little pressure (or no pressure): fade to white... Later on I want to draw everything on a PGraphics layer – therefore there is alyready this variable...

float counter;
PGraphics pg;
ArrayList<PVector> positionsList;

Brush myBrush;

void setup() {
  size(600, 600);
  positionsList = new ArrayList<PVector>();
  pg = createGraphics(width, height);
}


void draw() {
  background(255);
  color from = color(0);
  color to = color(255);
  color faded = lerpColor(from, to, counter);

  for (PVector p : positionsList) {
    myBrush = new Brush(faded, p.x, p.y);
   myBrush.display();
 
  }
    positionsList.add(new PVector(mouseX, mouseY));
      counter = counter + 0.01;
}

class Brush {
  color tempC;
  float xpos;
  float ypos;
  color c;

  Brush(color tempC, float tempXpos, float tempYpos) {
    
    
    
    c = tempC;
    xpos = tempXpos;
    ypos = tempYpos;
  }
  void display() {
    noStroke();
    fill(c);
    ellipse(xpos, ypos, 50, 50);
 
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文