Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discussion: Custom Example for the Library Template #68

Open
SableRaf opened this issue Jan 16, 2025 · 18 comments
Open

Discussion: Custom Example for the Library Template #68

SableRaf opened this issue Jan 16, 2025 · 18 comments
Assignees

Comments

@SableRaf
Copy link
Collaborator

Context

The talented @stixan (@stigmollerhansen on Instagram) kindly agreed to create a custom example for the library template 💙

Here were the requirements I shared (let me know if I missed anything):

  • landscape with a 4:3 or 16:9 ratio.
  • It should feature text that says “hello library”.
  • For simplicity, the sketch should not use external assets.
  • Similarly, the code should fit in one file and not be too long.
  • It should not contain proprietary code or copyrighted content.
  • If there is animation it should also look good in a screenshot, as it will be exported to a static image for the home page.
  • The sketch code will be included in the template repository.

Motivation

I'm creating this issue mainly so that we can answer Stig's technical questions about the template and library example.

Open questions

Stig: I get that the idea is to demonstrate how a part of the code is contained in an imported library. I guess you need my sketch to do that too, e.g. mimic the way the current HelloCircles sketch is importing RandomCircles and SayHello from com.myDomain.myLibrary.*?

@mingness
Copy link
Collaborator

Hi there, looking forward to it!

@SableRaf your requirements sound good to me.

@stixan
Yes, the example should show how the library is used - in this case, the example library has two objects, RandomCircles and SayHello, so the example shows how to use them.

The SayHello returns the "hello library." text.
The RandomCircles object is an example that uses a dependency. This could be changed if you wished. I've set commons-math3 as a dependency, and use their random number generators in RandomCircles.

@stigmollerhansen
Copy link

Just to be clear, I am free to ditch both SayHello and RandomCircles and come up with new objects, as long as I keep the same overall structure (one main .pde sketch that includes X number of .java files compiled into one library)?

@SableRaf
Copy link
Collaborator Author

I should think so but I'll let @mingness confirm for sure.

@mingness
Copy link
Collaborator

You are free to ditch both SayHello and RandomCircles and come up with your own objects in the library if you wish - the objective is to keep these objects in the library relatively simple and clear. The objective of the example library in template is to show briefly how it might be structured in a working example, so if your library objects are similarly lean like the existing ones, that's great. I still think it is instructive to use an external dependency in the library - is this something that fits in your ideas?

@stigmollerhansen
Copy link

I’ll come up with an idea that includes an external dependency ✅

@stigmollerhansen
Copy link

Here's what I've come up with so far.

/* ---------------- MAIN SKETCH ---------------- */

Palette p;
Grid g;

void setup() {
  size(800, 800); // This sketch assumes a square canvas
  p = new Palette();
  makeGrid();
}

void draw() {
  background(0);
  g.show();
}

void mouseClicked() {
  makeGrid();
}

void makeGrid() {
  g = new Grid(p.getPalette());
}

/* ---------------- LIBRARY CLASS: DOT GRID ---------------- */

class Grid {
  ArrayList<Dot> dots;

  Grid(color[] palette) {
    dots = new ArrayList<Dot>();
    int gridSize = int(random(2, 12));
    float cellSize = width / float(gridSize);
    float dotSpeed = random(0.008, 0.064);
    for (int i = 0; i < gridSize * gridSize; i++) {
      int x = i % gridSize;
      int y = i / gridSize;
      float xpos = x * cellSize + cellSize / 2;
      float ypos = y * cellSize + cellSize / 2;
      color dotColor = palette[int(random(palette.length))];
      dots.add(new Dot(xpos, ypos, cellSize, dotSpeed, dotColor));
    }
  }

  void show() {
    for (Dot d : dots) {
      d.update();
      d.display();
    }
  }

  class Dot {
    float xpos, ypos;
    float diameterOriginal, diameterCurrent;
    float pulseValue, pulseSpeed;
    color colorFill;
    Dot(float x, float y, float d, float s, color c) {
      xpos = x;
      ypos = y;
      diameterOriginal = d;
      diameterCurrent = diameterOriginal;
      pulseValue = random(TWO_PI);
      pulseSpeed = random(s * 0.5, s * 2.0);
      colorFill = c;
    }
    void display() {
      pushStyle();
      fill(colorFill);
      noStroke();
      circle(xpos, ypos, diameterCurrent);
      popStyle();
    }
    void update() {
      pulseValue += pulseSpeed;
      diameterCurrent = map(sin(pulseValue), -1, 1, diameterOriginal * 0.1, diameterOriginal * 0.9);
    }
  }
}

/* ---------------- LIBRARY CLASS: PALETTE GENERATOR ---------------- */

class Palette {
  Palette() {
  }
  color[] getPalette() {
    int numColors = 5;
    color[] palette = new color[numColors];
    pushStyle();
    colorMode(HSB, 1.0, 1.0, 1.0);
    color mix = color(random(1.0), 1.0, 1.0);
    float h, s, b;
    for (int i=0; i<palette.length; i++) {
      h = (random(1.0) + hue(mix)) / 2;
      s = 1.0;
      b = random(1.0) < 0.2 ? 0.2 : 1.0;
      palette[i] = color(h, s, b);
    }
    popStyle();
    return palette;
  }
}

I have made numerous failed attempts, all of which have exploded in size because of my vain desire to show off. In this sketch, I have attempted to strike a balance between simplicity and aesthetics. Let me know what you think before I have a go at turning it into an actual library. I may need a bit of guidance, though – @mingness, are you available for questions?

@stigmollerhansen
Copy link

(I'll add external dependencies when I move the sketch to the library template)

@stigmollerhansen
Copy link

I've incorporated a fair number of Processing functions into library classes. I think it's important to highlight that this is possible—especially for potential library developers who are familiar with Processing but lack experience with Java (myself and many of my students included).

@SableRaf
Copy link
Collaborator Author

Hey @stigmollerhansen,

This looks fantastic! I really appreciate the effort you’ve put into it 😃

One thing to adjust: the example needs to fit a landscape 4:3 or 16:9 ratio (currently it assumes a square canvas). The other requirement is to include the text "hello library" in the sketch. Here's my attempt at a modified version:

/* ---------------- MAIN SKETCH ---------------- */

Palette p;
Grid g;

void setup() {
  size(1280, 720); // Adjusted for a 16:9 aspect ratio
  p = new Palette();
  makeGrid();
}

void draw() {
  background(0);
  g.show();
  displayText();
}

void mouseClicked() {
  makeGrid();
}

void makeGrid() {
  g = new Grid(p.getPalette());
}

void displayText() {
  fill(255);
  textAlign(CENTER, CENTER);
  textSize(200);
  text("Hello Library", width / 2, height / 2 - 30);
}

/* ---------------- LIBRARY CLASS: DOT GRID ---------------- */

class Grid {
  ArrayList<Dot> dots;

  Grid(color[] palette) {
    dots = new ArrayList<Dot>();
    int gridSizeX = int(random(3, 16)); // Adjusted for aspect ratio
    int gridSizeY = int(gridSizeX * (9.0 / 16.0)); // Adjusted for aspect ratio
    float cellSizeX = width / float(gridSizeX);
    float cellSizeY = height / float(gridSizeY);
    float dotSpeed = random(0.008, 0.064);
    for (int y = 0; y < gridSizeY; y++) {
      for (int x = 0; x < gridSizeX; x++) {
        float xpos = x * cellSizeX + cellSizeX / 2;
        float ypos = y * cellSizeY + cellSizeY / 2;
        color dotColor = palette[int(random(palette.length))];
        dots.add(new Dot(xpos, ypos, min(cellSizeX, cellSizeY), dotSpeed, dotColor));
      }
    }
  }

  void show() {
    for (Dot d : dots) {
      d.update();
      d.display();
    }
  }

  class Dot {
    float xpos, ypos;
    float diameterOriginal, diameterCurrent;
    float pulseValue, pulseSpeed;
    color colorFill;
    Dot(float x, float y, float d, float s, color c) {
      xpos = x;
      ypos = y;
      diameterOriginal = d;
      diameterCurrent = diameterOriginal;
      pulseValue = random(TWO_PI);
      pulseSpeed = random(s * 0.5, s * 2.0);
      colorFill = c;
    }
    void display() {
      pushStyle();
      fill(colorFill);
      noStroke();
      circle(xpos, ypos, diameterCurrent);
      popStyle();
    }
    void update() {
      pulseValue += pulseSpeed;
      diameterCurrent = map(sin(pulseValue), -1, 1, diameterOriginal * 0.1, diameterOriginal * 0.9);
    }
  }
}

/* ---------------- LIBRARY CLASS: PALETTE GENERATOR ---------------- */

class Palette {
  Palette() {
  }
  color[] getPalette() {
    int numColors = 5;
    color[] palette = new color[numColors];
    pushStyle();
    colorMode(HSB, 1.0, 1.0, 1.0);
    color mix = color(random(1.0), 1.0, 1.0);
    float h, s, b;
    for (int i=0; i<palette.length; i++) {
      h = (random(1.0) + hue(mix)) / 2;
      s = 1.0;
      b = random(1.0) < 0.2 ? 0.2 : 1.0;
      palette[i] = color(h, s, b);
    }
    popStyle();
    return palette;
  }
}

Image

Image

Image

@SableRaf
Copy link
Collaborator Author

I have small suggestions for some color tweaks to soften things a bit:

  • Background → background(18); for a slightly softer dark tone.
  • Text color → fill(240); to make the "hello library" text a little less stark.
  • Saturation variation → s = random(0.8, 0.95); to introduce a bit of variation and keep the saturation a little muted.

Image

@stigmollerhansen
Copy link

Ha ha, I fell victim to the one thing I always tell my students: "READ THE BRIEF!" 😂 Thanks for reminding me of the specs I even asked for myself and then forgot all about, @SableRaf. I agree with your suggestions on both colors and code. I'll add them to the code.

@stigmollerhansen
Copy link

I might also tweak how the number of rows and columns are calculated to match the aspect ratio and fill out the entire canvas.

@SableRaf
Copy link
Collaborator Author

SableRaf commented Jan 17, 2025

I might also tweak how the number of rows and columns are calculated to match the aspect ratio and fill out the entire canvas.

This should already be the case in my tweaked code but of course feel free to adjust as you see fit :)

@stigmollerhansen
Copy link

Great suggestions @SableRaf. I've made a few minor tweaks:

  • Due to the 16:9 aspect ratio, the height (rows) is the smallest side. For aesthetic reasons, I have decided to raise the minimum number of rows to three.
  • The number of columns is now calculated from the number of rows.
/* ---------------- MAIN SKETCH ---------------- */

Palette p;
Grid g;

void setup() {
  size(1280, 720);
  p = new Palette();
  makeGrid();
}

void draw() {
  background(16);
  g.show();
  displayText();
}

void mouseClicked() {
  makeGrid();
}

void makeGrid() {
  g = new Grid(p.getPalette());
}

void displayText() {
  fill(240);
  textAlign(CENTER, CENTER);
  textSize(200);
  text("Hello Library", width / 2, height / 2);
}

/* ---------------- LIBRARY CLASS: DOT GRID ---------------- */

class Grid {
  ArrayList<Dot> dots;
  Grid(color[] palette) {
    dots = new ArrayList<Dot>();
    int gridSizeY = int(random(3, 16));
    int gridSizeX = int(gridSizeY * (float(width) / height));
    float cellSizeY = height / float(gridSizeY);
    float cellSizeX = width / float(gridSizeX);
    float dotSpeed = random(0.008, 0.064);
    for (int y = 0; y < gridSizeY; y++) {
      for (int x = 0; x < gridSizeX; x++) {
        float xpos = x * cellSizeX + cellSizeX / 2;
        float ypos = y * cellSizeY + cellSizeY / 2;
        color dotColor = palette[int(random(palette.length))];
        dots.add(new Dot(xpos, ypos, min(cellSizeX, cellSizeY), dotSpeed, dotColor));
      }
    }
  }

  void show() {
    for (Dot d : dots) {
      d.update();
      d.display();
    }
  }

  class Dot {
    float xpos, ypos;
    float diameterOriginal, diameterCurrent;
    float pulseValue, pulseSpeed;
    color colorFill;
    Dot(float x, float y, float d, float s, color c) {
      xpos = x;
      ypos = y;
      diameterOriginal = d;
      diameterCurrent = diameterOriginal;
      pulseValue = random(TWO_PI);
      pulseSpeed = random(s * 0.5, s * 2.0);
      colorFill = c;
    }
    void display() {
      pushStyle();
      fill(colorFill);
      noStroke();
      circle(xpos, ypos, diameterCurrent);
      popStyle();
    }
    void update() {
      pulseValue += pulseSpeed;
      diameterCurrent = map(sin(pulseValue), -1, 1, diameterOriginal * 0.1, diameterOriginal * 0.9);
    }
  }
}

/* ---------------- LIBRARY CLASS: PALETTE GENERATOR ---------------- */

class Palette {
  Palette() {
  }
  color[] getPalette() {
    int numColors = 5;
    color[] palette = new color[numColors];
    pushStyle();
    colorMode(HSB, 1.0, 1.0, 1.0);
    color mix = color(random(1.0), 1.0, 1.0);
    float h, s, b;
    for (int i=0; i<palette.length; i++) {
      h = (random(1.0) + hue(mix)) / 2;
      s = random(0.8, 1.0);
      b = random(1.0) < 0.2 ? 0.2 : 1.0;
      palette[i] = color(h, s, b);
    }
    popStyle();
    return palette;
  }
}

@stigmollerhansen
Copy link

I've thought of several things I could add, but I've slapped my hand and reminded myself that this is supposed to be a SHORT and generic template 😅

If you consider this a final version, feel free to port the code into the library template. I'll take a stab at doing that myself, as I would love to learn how to contribute libraries to Processing. However, my virtually non-existent Java dev skills will likely delay the process.

@mingness
Copy link
Collaborator

@stigmollerhansen @SableRaf The example looks amazing. Great work!

I'm around if you'd still like to chat @stigmollerhansen ? I'd be happy to work with you to port the code into the template.
The example is more than what's there now - maybe we could use some comments to lead beginners through the example? Would you have students that could test readability of the example and comments for us?

@stigmollerhansen
Copy link

For the next three days, I’m busy taking my students to their semester exams. I hope I’m not becoming a bottleneck in releasing the template?

Next week, I’d love to schedule a brief chat/talk with you, @mingness, to get some guidance. Once I get the code ported to the library template, I can easily run it past my students on the Coded Design program—I’m sure they will provide some valuable feedback.

@mingness
Copy link
Collaborator

@stigmollerhansen there's no rush, we can be gentle with ourselves.
Absolutely happy to chat next week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants