JoyStick
Introduced 1.1.0
Sketch code
const X = 10, Y = 10, W = 450, H = 300;
let gui;
let speed = 0, angle = 0, s = 20, pos = { x: W / 2, y: H / 2 };
let holes, exitHole = -1;
function setup() {
    let p5canvas = createCanvas(640, 400);
    p5canvas.parent('sketch');
    cursor(CROSS);
    makeHoles(7);
    createGUI(p5canvas);
}
function createGUI(p5canvas) {
    gui = GUI.get(p5canvas);
    gui.joystick('js0', X + W + 10, Y + H - 120, 120, 120).scheme('blue')
        .setAction((info) => {
            angle = info.angle; 
            speed = info.final ? 0 : info.mag * 100 / 1000;
        });
    gui.label('title', X, Y + H + 20, W, 40).corners([10, 10, 10, 10])
        .scheme('dark').textSize(26).text('Space Travel using Wormholes');
}
function makeHoles(n) {
    holes = [];
    let cx = 0.5 * W, cy = 0.5 * H, rx = 0.5 * W - s, ry = 0.5 * H - s;
    let da = 2 * PI / n, sa = random(0, PI);
    for (let i = 0; i < n; i++) {
        let a = sa + i * da;
        px = cx + rx * cos(a) * random(0.4, 1);
        py = cy + ry * sin(a) * random(0.4, 1);
        holes.push({ x: px, y: py });
    }
}
function draw() {
    background(24, 160, 160);
    push();
    translate(X, Y);
    updateShip(deltaTime);
    drawSpace();
    drawHoles();
    drawShip();
    pop();
    gui.draw();
}
function drawSpace() {
    push();
    fill(0); stroke(192); strokeWeight(5);
    rect(0, 0, W, H);
    pop();
}
function drawHoles() {
    push();
    stroke(140, 160, 0); strokeWeight(3); fill(60);
    holes.forEach(h => ellipse(h.x, h.y, s, s));
    pop();
}
function drawShip() {
    push();
    translate(pos.x, pos.y); rotate(angle);
    fill(220, 64, 64); noStroke();
    triangle(-s * 0.5, -s * 0.3, -s * 0.5, s * 0.3, s * 0.5, 0);
    pop();
}
function updateShip(dt) {
    pos.x = (pos.x + speed * dt * cos(angle) + W) % W;
    pos.y = (pos.y + speed * dt * sin(angle) + H) % H;
    for (let i = 0, n = holes.length; i < n; i++) {
        if (exitHole != i) { // Ignore the hole last exited
            let dx = pos.x - holes[i].x, dy = pos.y - holes[i].y;
            let d = sqrt(dx * dx + dy * dy), to;
            if (d < s / 2) {
                do { exitHole = floor(random(0, n)); } while (exitHole == i);
                pos.x = holes[exitHole].x; pos.y = holes[exitHole].y;
                break;
            }
        }
    }
}Event information
The info object contains the following fields - 
| Field | Description | 
| source | A reference to the control that generated the event | 
| p5Event | A reference to original event generated by p5.js | 
| mag | In the range ≥0 and ≤1 depending on how far the joystick has been pushed from the rest position (center). | 
| angle | The angle made by the joystick in the range from 0to2π. It is measured
              from the poistive x axis and increments in the clockwise direction.In modes 'X4' and 'X8' the angle is constrained to the directions allowed by the mode. | 
| dir | An integer that indicates the direction the stick is pushed. The values returned depend on the current
              mode - 
     5   6   7
      \  |  /
       \ | /
   4 --- Z --- 0       Z is the dead zone value is -1.
       / | \
      /  |  \          If control is in mode 'X0' or the joystick
     3   2   1         position is in the dead zone the the value is -1
              
                 | 
| dead | trueif the joystick is in the dead zone elsefalse | 
| final | falseif the joystick is still being moved and elsetruewhen released. |