-
Notifications
You must be signed in to change notification settings - Fork 45
Code Documentation
This page is dedicated to a simplistic documentation and overview of the architecture of the application. The objective of this page is to provide an easy reference to understand some objects and subsystems of openOutpaint.
There are some functions and helper objects that were isolated in the util.js, due to their simplicity and usefulness in various contexts in the source code.
The Observer
class is a very simple implementation of the The Observer Pattern, and while currently being used mostly for event listeners for input, it could be used in other scenarios, such as an application-wide messaging system.
The class contains three methods:
A method that registers a new listener function for events emitted on this observer.
Receives a callback function with a single message
argument. Message can be an arbitrary object sent by an emitter. Returns the callback reference passed on the callback
parameter.
A method that searches for and removes a listener given a reference to the original callback.
Receives a callback function that could have been registered on this observer before. Returns whether the element existed or not before deletion.
Sends a message to the observer. All registered callbacks are run, receiving the message
parameter passed to the method. Message can be any arbitrary javascript object.
// Creates an Observer object
const observer = new Observer();
// Sets up a listener
const listener = observer.on((message) => console.debug(message));
// Emits a message to the listener
observer.emit("this is a simple test message");
// Removes the registered listener
const success = observer.clear(listener);
A simple function that generates alphanumeric IDs (0-9a-f) in the format xxxx-xxxx-xxxx-...-xxxx
. By default generates 3 groups of 4 characters each split by dashes. Can receive a single parameter for deciding the number of dash-separated groups to be generated.
It is currently used mostly to create resource identifiers, such as file identifiers, history entry modifiers, etc.
// Generates a simple ID
const id1 = guid();
// -> 8a61-6c18-2363
const id2 = guid(5);
// -> bdd3-bc38-4996-fb63-a494
A function that is used to set default options to object parameters. Object parameters are great when a function requires many parameters, but many are optional and have default values.
// If we create the function this way, someone that calls the function
// but only needs to set the city would have to provide color and weight
// as well
function createVehicle(
plate,
weight = 5,
color = "red",
city = "somecity"
) {
// Do stuff
}
createVehicle("plate", 5, "red", "city");
// This is better
function createVehicle2(
plate,
options = {}
) {
defaultOpt(options, {
weight = 5,
color = "red",
city = "somecity"
})
// Do stuff
}
createVehicle2("plate", {city: "city"});
The function snap(i, scaled?, gridSize?)
returns an offset to the nearest snapping point in a abstract one-dimensional grid. i
is the value to be snapped; scaled is if we consider the scaleFactor
value during snapping (odd values for scale factor need to be able to snap to the center of cells); gridSize
is the size of each cell in the abstract grid.
// Snaps a value (in this case, could be the x coordinate of the cursor)
const offx = snap(cx, true, 64);
// examples in this case (scaleFactor = 8)
// cx = 20 => x = -20 (20 + (-20) = 0)
// cx = 36 => x = 28 (36 + 28 = 64)
// cx = 47 => x = 17 (47 + 17 = 64)
// cx = 358 => x = 26 (358 + 26 = 384 = 64 * 6)
The function getBoundingBox(cx, cy, w, h, gridSnap?)
returns a bounding box object {x, y, w, h}
centered on the given coordinates (cx
, cy
) and with size (w
, h
). It uses snap
internally to snap coordinates to the grid, if given a grid size.
// Gets a bounding box of size 512, 512 around the cursor,
// snapping to a grid of size 64:
const bb = getBoundingBox(
cursor.x,
cursor.y,
512,
512,
64
);
These are some functions to easily crop canvas to content and to download a canvas as a PNG file.
The function cropCanvas(src)
receives a canvas element, and returns a new canvas of a smaller or equal size, containing only the non-transparent content of the canvas.
The function downloadCanvas(options?: {cropToContent?, canvas?, filename?})
is used to trigger a file download of a canvas, cropping content. By default, the function crops canvas to content, uses the imgCanvas
as a source, and saves a file in the format: {ISO Date} {Hours} {Minutes} {Seconds} openOutpaint image.png
// Gets content from Mask Canvas
const maskContent = cropCanvas(maskPaintCanvas);
// Saves full mask layer content to disk
downloadCanvas({
cropToContent: false,
canvas: maskPaintCanvas,
filename: "mask-layer.png"
});
The code is mostly structured so library files have one or two globally accessible objects that can then be acessed by other components of the application. Currently, the most relevant available global objects are:
-
mouse
- Mouse input handling object -
keyboard
- Keyboard input handling object -
commands
- Command Pattern implementation to provide undo/redo and history -
toolbar
- Information regarding the toolbar of the application
Input handling in the application is mostly done via the mouse
and keyboard
global objects, defined on the input.js file.
Handling should be done mostly via listeners on the Observer
objects, located in each input context.