html,body{margin:0px; padding:0px;overflow:hidden;}
let position;

function setup() {
    canvas = createCanvas(windowWidth, windowHeight);
    // Initializing a 2D vector
    position = createVector(-100, -100);
}

function draw() {
    clear();

    const hw = width / 2;
    const hh = height / 2;

    // Dracula theme background
    background('#282a36');

    push();
    translate(hw, hh);

    // Draw subgrids before the axes for a cleaner look
    drawSubgrid(hw, hh, 50); // Adjust the grid size as needed

    // Vector color: Pink, axis: Light blue
    fill('#ff79c6');
    stroke('#8be9fd');
    strokeWeight(2);

    // Drawing an arrow to represent the position vector
    drawArrow(0, 0, position.x, position.y);

    // Displaying the position vector's components in Green
    drawLabel(position.x, position.y, `Posição (${position.x.toPrecision(4)}, ${position.y.toPrecision(4)})`, LEFT);

    // Drawing axes in Light Blue
    stroke('#6272a4');
    strokeWeight(1);
    line(-hw, 0, hw, 0);  // X axis
    line(0, -hh, 0, hh);  // Y axis
    drawLabel(0, -4, "Origem (0, 0)", LEFT);

    pop();
}

// Draws the subgrid with lines spaced by gridSize and aligned to the main axes
function drawSubgrid(hw, hh, gridSize) {
    stroke('#44475a'); // Subgrid lines color (Dark gray)
    strokeWeight(0.5);

    // Align the grid with the axes by calculating the first grid line relative to the center (0, 0)

    // Vertical subgrid lines (aligned with Y axis)
    for (let x = -hw + (hw % gridSize); x <= hw; x += gridSize) {
        line(x, -hh, x, hh);
    }

    // Horizontal subgrid lines (aligned with X axis)
    for (let y = -hh + (hh % gridSize); y <= hh; y += gridSize) {
        line(-hw, y, hw, y);
    }
}

function drawArrow(x0, y0, x1, y1) {
    line(x0, y0, x1, y1);
    
    // Create a normalized direction vector from the start point to the end point of the arrow
    let v = createVector(x1 - x0, y1 - y0).normalize().mult(8);
    
    // Arrowhead: matching vector color (Pink)
    line(x1, y1, x1 - v.y - v.x, y1 + v.x - v.y);
    line(x1, y1, x1 + v.y - v.x, y1 - v.x - v.y);
}

// Update the vector's position only when the mouse is clicked
function mousePressed() {
    const hw = width / 2;
    const hh = height / 2;
    
    // Updating the position vector based on mouse coordinates when clicked
    position.set(mouseX - hw, mouseY - hh);
}

function drawLabel(x, y, label, align = CENTER) {
    push();
    strokeWeight(0);
    fill('#f8f8f2');
    textFont("monospace");
    textSize(14);
    textAlign(align);

    if (align == LEFT) x += 6;
    if (align == RIGHT) x -= 6;

    text(label, x, y);
    pop();
}

function windowResized() {
    resizeCanvas(windowWidth, windowHeight);
}
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdn.jsdelivr.net/npm/p5@latest/lib/p5.min.js