-
Notifications
You must be signed in to change notification settings - Fork 13
Contributor Guide
This guide is intended for people that want to contribute to the development of q5. To learn how to use q5, visit q5js.org.
The website you're currently on is called GitHub, it was created for people to share and collaborate on coding projects, often called "repos" (short for repositories).
The easiest way to contribute to q5, or any other repo on GitHub, is by creating a GitHub account and editing files directly on this site.
The source of all the information and editable code examples shown on https://q5js.org/learn is the q5.d.ts (typescript definitions) file.
To contribute to q5's documentation, simply edit this file:
https://github.com/q5js/q5.js/blob/main/q5.d.ts
You may wonder why q5 even needs different examples? Why not copy directly from open source p5 example code?
I think contributors can take inspiration from p5's example code, since the essence of many of these examples is excellent, but they shouldn't directly copy from them.
Firstly, on p5js.org nearly every reference page example uses a canvas with a size of 100x100. This is debatably too small for modern displays. The default canvas size in q5 is 200x200 and this size will be the standard for the q5 docs.
Secondly, p5 examples are often too long. The primary purpose of the mini examples should be to provide a visual aid for the JSDoc description and simplest possible use case of the function or variable being described.
Yet, look at this p5 example for redraw
. Notice how there's so many comments verbosely explaining what all the other functions do. This would be like if you looked in a dictionary and each word had recursive definitions for all the words included in a word's definition! With the mini editor on the q5 Learn pages, users can hover over a function to see its documentation (thanks to @Tezumie). What value then would comments like "Turn off the draw loop." and "Draw a circle." provide? Each documentation page is not a stand-alone demo.
// Double-click the canvas to move the circle.
let x = 0;
function setup() {
createCanvas(100, 100);
// Turn off the draw loop.
noLoop();
describe(
'A white half-circle on the left edge of a gray square. The circle moves a little to the right when the user double-clicks.'
);
}
function draw() {
background(200);
// Draw the circle.
circle(x, 50, 20);
// Increment x.
x += 5;
}
// Run the draw loop when the user double-clicks.
function doubleClicked() {
redraw();
}
Here are some guidelines on how to write example code for the q5 documentation. These are some of the same strategies I used on p5play.org/learn
- keep things short and simple (9 lines or less)
- avoid defining a
setup
function, usecreateCanvas
to start the sketch or only write adraw
function - avoid declaring and using variables
- don't add comments or use
describe
in the code, all explanations should be given in the JSDoc - require only the simplest user interactions (moving the mouse, pressing left mouse button, or pressing the space key)
Here's a q5 example with the same essence as the p5 example, cut from 29 lines to just 8.
function draw() {
circle(frameCount * 5, 50, 20);
noLoop();
}
function mouseClicked() {
redraw();
}
Take a look at p5's incorrect JSDoc formatting too. @example
should be used to delimit multiple examples, but they wrap each example in html div
and code
blocks. @example
sections should only contain JS. Also the method is incorrectly labeled with @chainable
.
/**
* Sets the number of frames to draw per second.
*
* Calling `frameRate()` with one numeric argument, as in `frameRate(30)`,
* attempts to draw 30 frames per second (FPS). The target frame rate may not
* be achieved depending on the sketch's processing needs. Most computers
* default to a frame rate of 60 FPS. Frame rates of 24 FPS and above are
* fast enough for smooth animations.
*
* Calling `frameRate()` without an argument returns the current frame rate.
* The value returned is an approximation.
*
* @method frameRate
* @param {Number} fps number of frames to draw per second.
* @chainable
*
* @example
* <div>
* <code>
* function setup() {
* createCanvas(100, 100);
*
* describe('A white circle on a gray background. The circle moves from left to right in a loop. It slows down when the mouse is pressed.');
* }
*
* function draw() {
* background(200);
*
* // Set the x variable based
* // on the current frameCount.
* let x = frameCount % 100;
*
* // If the mouse is pressed,
* // decrease the frame rate.
* if (mouseIsPressed === true) {
* frameRate(10);
* } else {
* frameRate(60);
* }
*
* // Use x to set the circle's
* // position.
* circle(x, 50, 20);
* }
* </code>
* </div>
*
* <div>
* <code>
* function setup() {
* createCanvas(100, 100);
*
* describe('A number written in black on a gray background. The number decreases when the mouse is pressed.');
* }
*
* function draw() {
* background(200);
*
* // If the mouse is pressed, do lots
* // of math to slow down drawing.
* if (mouseIsPressed === true) {
* for (let i = 0; i < 1000000; i += 1) {
* random();
* }
* }
*
* // Get the current frame rate
* // and display it.
* let fps = frameRate();
* text(fps, 50, 50);
* }
* </code>
* </div>
*/
/**
* @method frameRate
* @return {Number} current frame rate.
*/
Look back at the frame rate example with the calculations intended to decrease the frame rate, but they don't make a difference on today's high-end computers. Try to avoid writing examples like this that are hardware dependent.
Here's q5's frameRate
JSDoc as an example of proper formatting in q5.d.ts.
/** ⭐️
* Sets the target frame rate or gets the sketch's current frame rate.
* @param {number} [hertz] - desired frame rate, default is 60
* @returns {number} current frame rate
* @example
function draw() {
background(200);
if (mouseIsPressed) frameRate(10);
else frameRate(60);
circle(frameCount % 200, 100, 50);
}
*/
function frameRate(hertz?: number): number;
Note that @method
or @function
is not necessary if the JSDoc comment is directly before the function type def. Also note that the code lines in the @example
section are not prefaced by *
, which makes the code easier to edit and read for contributors. It also uses tabs, not spaces, for file size efficiency.
Another thing to consider about p5's documentation is how it's presented. Each function and variable has a reference page that's separate from other reference pages. When developing p5play.org/learn I found that students learned better if I grouped related functions and variables on the same page. With p5.js, running lots of sketches on the same page could cause performance issues. But for q5's documentation, each sketch is written for global mode use, but is instanced behind the scenes. I also used the Intersection Observer API to ensure that q5 only loops sketches with canvases if they're being observed.
When contributing example code to the q5 documentation consider how one example can flow into the next and build upon previous examples. You can reorder the JSDoc and type defs.
All you need is a GitHub account to edit files on this site right in your web browser. Yet, most professional developers will download repos to their own computer to edit them "locally". Local development enables you to edit files using an editor app like Visual Studio Code that you can customize based on your own personal preferences and needs.
GitHub uses a program called Git, which keeps track of changes to a repo's files each time a "commit" is "pushed". This enables developers to edit a repo and then easily download, "pull", changes from other developers working on the same project.
- install the Google Chrome web browser for fastest overall performance
- Windows users need to install Git
- macOS users need to install Git via the command
xcode-select --install
in the Terminal app - install the Visual Studio Code editor
Open the Git Bash app on Windows or the Terminal app on macOS.
A terminal lets you navigate your computer and run programs via text based commands instead of via the graphical user interfaces of programs like File Explorer or Finder.
Let's use the cd
command to go to a folder that you want your code projects to be in, for example your "Documents" or "Desktop" folder.
cd ~/Desktop
The command git clone
downloads a git repo to your computer.
git clone https://github.com/q5js/q5.js.git
When the download is finished, open the Visual Studio Code app (commonly called "VSCode") and open the q5 folder in it.
Many text files you encounter on GitHub are written in Markdown format, with the .md
file extension.
Markdown enables you to format text, without using a word processor, yet it's simpler to use compared to HTML. Take a look at how to write markdown: https://www.markdownguide.org/cheat-sheet/
The best part about markdown is that code can be embedded between triple backticks.
alert('Wow! Markdown is great!');
Many developers prefer to communicate on messaging platforms like Discord and Slack, which support markdown syntax. That way they can send code to each other with syntax highlighting.
Join the q5 team in the "#dev" channel on the q5 community Discord.
In the Activity Bar on the left side of VSCode click the extension icon, which looks like one box being separated from three other boxes, you can search for the following extensions or use the links below to install them.
"Live Server" auto-refreshes the browser when you make changes to your code. https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer
"Prettier" is an extension that will automatically format your code for you when you save it so you won't have to worry about doing proper indentation and formatting yourself! https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode
"Markdown Preview Enhanced" is a great extension for previewing Markdown files. https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced
"vscode-color-picker" is a great extension for picking colors in JavaScript files. https://marketplace.visualstudio.com/items?itemName=AntiAntiSepticeye.vscode-color-picker
Try using the same VSCode settings that I use. If you don't like them, you can always change them later.
Press F1 on your keyboard (hold Fn then press F1 on macOS). Search the menu for "Preferences: Open Settings (JSON)". Add these settings to VSCode's settings.json
file:
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.guides.bracketPairs": true,
"editor.bracketPairColorization.enabled": true,
"editor.formatOnPaste": true,
"editor.minimap.enabled": false,
"editor.tabSize": 2,
"editor.insertSpaces": false,
"editor.formatOnSave": true,
"editor.wordWrap": "on",
"explorer.confirmDelete": false,
"explorer.confirmDragAndDrop": false,
"files.insertFinalNewline": true,
"files.trimFinalNewlines": true,
"prettier.jsxSingleQuote": true,
"prettier.singleQuote": true,
"prettier.trailingComma": "none",
"prettier.useTabs": true,
"prettier.printWidth": 120,
"diffEditor.wordWrap": "on",
"liveServer.settings.donotShowInfoMsg": true,
"editor.glyphMargin": false,
"editor.folding": false
Every major open-source project has its own style guide: a set of conventions (sometimes arbitrary) about how to write code for that project. It's much easier to understand a large codebase when it has a consistent style. “Style” covers a lot of ground, from "use camelCase for variable names" (aesthetic) to "never use global variables" (functional). - Google Style Guides
Code is a language art that can be subjectively judged by its effectiveness at communicating its functionality to humans. Code can also be objectively measured by its performance. Since JavaScript is served over a network, size is a factor as well.
Therefore, the q5 team strives to balance code readability with brevity and performance!
Keep it Simple! Usually the best, simplest solution to a problem is not immediately obvious.
Good enough isn't good enough! We strive for excellence when developing q5. Often during development you can start with some code that "just works" and iterate on it until you find a more perfect solution through experimentation.
Don't Repeat Yourself! keep code concise through reasonable use of abstractions instead of duplication.
- Use standard
for
orfor..of
loops instead ofArray.forEach
(slow)