---
title: Begin your 2023 with Genuary!
id: 742
html_url: "https://acmcsuf.com/blog/742"
discussion_url: "https://github.com/EthanThatOneKid/acmcsuf.com/discussions/742"
author: "EthanThatOneKid (https://github.com/EthanThatOneKid)"
labels: []
created: "2022-12-27T06:08:45.000Z"
edited: "2022-12-27T19:46:44.000Z"
---
Begin your 2023 with Genuary!
=============================
ACM AT CSUF WELCOMES GENURARY 2023!
Welcome to your introductory Genuary 2023 codelab where you will learn how to use
https://editor.p5js.org/ [https://editor.p5js.org/] to generate artwork for Genuary 2023.
WHAT IS GENUARY? ❄️
Genuary 2023's official website https://genuary.art/ [https://genuary.art/] defines Genuary as:
> Genuary is an artificially generated month of time where we build code that makes beautiful
> things.
There is a unique prompt for each day in the month of January. All of these prompts encourage the
practice of creative expression in programming.
In our club Discord server, members are encouraged to share their creations throughout the monthlong
event: Genuary 2023.
WHAT IS THIS CODELAB ABOUT?
In this codelab, you will learn how to create your first generative artwork with
https://editor.p5js.org/ [https://editor.p5js.org/] for Genuary 2023.
Once you have completed this codelab, you will have created a generative artwork using the 10print
algorithm.
* Set up https://editor.p5js.org [https://editor.p5js.org] for Genuary
* Create a 10print sketch
* Save the result as a GIF
QUICKLY, WHAT IS 10PRINT?
10print is a generative algorithm that creates a pattern of lines.
Simulated output of the 10PRINT one-liner BASIC program for the Commodore 64
[https://camo.githubusercontent.com/e9865db4dbc0f8c0d1f22c28c1e1b1f059a80a80bfd0c68a76f91e9190a8cb69/68747470733a2f2f75706c6f61642e77696b696d656469612e6f72672f77696b6970656469612f636f6d6d6f6e732f612f61612f31307072696e742e676966]https://camo.githubusercontent.com/e9865db4dbc0f8c0d1f22c28c1e1b1f059a80a80bfd0c68a76f91e9190a8cb69/68747470733a2f2f75706c6f61642e77696b696d656469612e6f72672f77696b6970656469612f636f6d6d6f6e732f612f61612f31307072696e742e676966
source: Wikipedia [https://commons.wikimedia.org/wiki/File:10print.gif#/media/File:10print.gif]
Our algorithm will draw out the pattern of lines on a canvas from the top left corner to the bottom
right corner.
The algorithm is based on the following rules:
* 50% of the time, draw a line from the top left corner to the bottom right corner.
* The other 50% of the time, draw a line from the bottom left corner to the top right corner.
Supplemental reading:
* 10print.org [https://10print.org/]
* Truchet tiles [https://en.wikipedia.org/wiki/Truchet_tiles]
SET UP HTTPS://EDITOR.P5JS.ORG/ [https://editor.p5js.org/] FOR GENUARY
SIGN IN
Sign in to https://editor.p5js.org/ [https://editor.p5js.org/] with your GitHub account.
CREATE A NEW SKETCH
To create a new sketch from scratch, go to https://editor.p5js.org/ [https://editor.p5js.org/] and
click on File > New.
Save the sketch with whatever name you like, or use a pattern such as genuary-2023-01-01.
In your sketch, you will see a setup() function and a draw() function.
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
}
Start by removing background() from the draw() function.
Also, add a stroke() function to the setup() function to set the color of the lines to white.
function setup() {
createCanvas(400, 400);
stroke(255);
}
MAKE GLOBALS FOR THE SKETCH
Above setup(), we will define global variables for the sketch.
let x = 0;
let y = 0;
let s = 10;
DRAW A DIAGONAL LINE
In the draw() function, draw a diagonal line with line() [https://p5js.org/reference/#/p5/line].
Press to reveal the code
function draw() {
line(x, y, x + s, y + s);
}
Run ▶️ the sketch to see that the line is drawn from the top left corner to the bottom right corner
of the first square, which is 10 pixels by 10 pixels.
DRAW A SECOND DIAGONAL LINE
To draw a second diagonal line, we will need to change the value of x by s pixels in each frame to
move the next diagonal line to the right.
Press to reveal the code
function draw() {
line(x, y, x + s, y + s);
x += s;
}
Run ▶️ the sketch to see that an entire row of diagonal lines is drawn.
DRAW THE SECOND ROW OF DIAGONAL LINES
To draw the second row of diagonal lines, we will need to change the value of y by s pixels each
time x reaches the end of the canvas to move the next diagonal line down. Do not forget to send x
back to 0 when x reaches the end of the canvas.
Press to reveal the code
function draw() {
line(x, y, x + s, y + s);
x += s;
if (x >= width) {
x = 0;
y += s;
}
}
Run ▶️ the sketch to see that the entire canvas is filled with diagonal lines, but they are all
drawn from the top left corner to the bottom right corner.
HOW MANY FRAMES DOES IT TAKE TO DRAW THE ENTIRE CANVAS?
Since we know the width and height of the canvas, we can calculate the number of frames it takes to
fill the canvas with one diagonal line per frame.
To do this, we will need to know the number of squares that fit horizontally and vertically on the
canvas.
* width / s = number of squares that fit horizontally
* height / s = number of squares that fit vertically
We can then multiply the number of squares that fit horizontally by the number of squares that fit
vertically to get the total number of squares.
(width / s) * (height / s) = total number of squares
Press to reveal the answer
Assuming you are drawing one diagonal line per frame, we can then calculate the number of frames it
takes to fill the canvas given that the canvas is 400 pixels by 400 pixels and each square is 10
pixels by 10 pixels.
(400 / 10) * (400 / 10) = 1600 frames
Keep in mind how to get the number of frames it takes to fill the canvas in order to create a GIF
later.
RANDOMIZE THE DIRECTION OF THE DIAGONAL LINE
To randomize the direction of the diagonal line, we can use random()
[https://p5js.org/reference/#/p5/random] to generate a random number between 0 and 1.
We can tell our program to draw a line from the top left corner to the bottom right corner if the
random number is greater than 0.5, and to draw a line from the bottom left corner to the top right
corner of the random number is less than 0.5.
Press to reveal the code
function draw() {
if (random() > 0.5) {
line(x, y, x + s, y + s);
} else {
line(x + s, y, x, y + s);
}
x += s;
if (x >= width) {
x = 0;
y += s;
}
}
Run ▶️ the sketch to see that the direction of the diagonal line is randomized.
DRAW INFINITELY
To start the animation over when it reaches the end of the canvas, we can set the y value back to 0
when y reaches the end of the canvas and clear() [https://p5js.org/reference/#/p5/clear] the canvas.
Press to reveal the code
function draw() {
if (y >= height) {
y = 0;
clear();
}
if (random() > 0.5) {
line(x, y, x + s, y + s);
} else {
line(x + s, y, x, y + s);
}
x += s;
if (x >= width) {
x = 0;
y += s;
}
}
SAVE THE ANIMATION AS A GIF
Use saveGif() [https://p5js.org/reference/#/p5/saveGif] to save the animation as a GIF.
Hint: Review saveGif() short [https://youtube.com/shorts/CEnfKhs6wLg?feature=share] on YouTube.
Press to reveal the code
Allocate a boolean variable filming to keep track of whether the animation is being recorded to GIF.
let x = 0;
let y = 0;
let s = 10;
let filming = false;
Set filming to false when the animation completes.
function draw() {
if (y >= height) {
filming = false;
y = 0;
clear();
}
if (random() > 0.5) {
line(x, y, x + s, y + s);
} else {
line(x + s, y, x, y + s);
}
x += s;
if (x >= width) {
x = 0;
y += s;
}
}
Make your call to saveGif() in the mouseClicked() function. When the mouse is pressed, the animation
will be restarted and recorded to GIF.
Feel free to change the name of the GIF, but make sure the number of frames is the same as the
number of frames it takes to fill the canvas.
function mousePressed() {
if (!filming) {
saveGif(
"genuary-2023-01-01.gif",
(width / s) * (height / s),
{ units: "frames", delay: 0 },
);
x = 0;
y = 0;
clear();
filming = true;
}
}
Run ▶️ the sketch and then click the canvas with your mouse to see that the animation is saved as a
GIF.
CONGRATULATIONS!
You have created your first animation for Genuary 2023 which concludes this
codelab!
Press to reveal the completed codelab
let x = 0;
let y = 0;
let s = 10;
let filming = false;
function setup() {
createCanvas(400, 400);
stroke(255);
}
function draw() {
if (y >= height) {
filming = false;
y = 0;
clear();
}
if (random() > 0.5) {
line(x, y, x + s, y + s);
} else {
line(x + s, y, x, y + s);
}
x += s;
if (x >= width) {
x = 0;
y += s;
}
}
function mousePressed() {
if (!filming) {
saveGif(
"genuary-2023-01-01.gif",
(width / s) * (height / s),
{ units: "frames", delay: 0 },
);
x = 0;
y = 0;
clear();
filming = true;
}
}
NEXT STEPS
Feel free to add more features to your animation, such as:
* Randomize the color of the diagonal line.
* Change the size of the diagonal line.
* Customize the way in which the diagonal lines are drawn.
If you are interested in learning more about p5.js [https://p5js.org/], check out the following
references:
* p5.js reference [https://p5js.org/reference/]
* p5.js examples [https://p5js.org/examples/]
MORE ON SAVEGIF()
It is no coincidence that this codelab features the saveGif()
[https://p5js.org/reference/#/p5/saveGif] API. The first prompt of Genuary 2023 is "Perfect loop /
Infinite loop / endless GIFs". The saveGif() API provided by p5.js is a powerful tool that happens
to help with Genuary 2023 day 1 in particular, and even with other prompts later this month at the
artist's discretion.
SOCIAL MEDIA
You are encouraged to share your GIF on your favorite social media and tag it with #genuary
[https://twitter.com/search?q=%23genuary] and #genuary2023
[https://twitter.com/search?q=%23genuary2023] and also #genuary1
[https://twitter.com/search?q=%23genuary1], #genuary2 [https://twitter.com/search?q=%23genuary2],
etc, depending on which prompt you are working on.
Do not forget to send your GIF to the associated thread on our club Discord server,
https://acmcsuf.com/discord [https://acmcsuf.com/discord]!
CREDITS
* https://genuary.art/ [https://genuary.art/]
* https://editor.p5js.org/ [https://editor.p5js.org/]