location
Parameter Documentation
location
Parameter DocumentationParameter Name
location
Data Type
Array[Array[float, float]]
- The outer array must have a fixed length of
4
(must contain 4 vertices) - The inner array must have a fixed length of
2
(each vertex contains[x, y]
coordinates)
Description
Represents the position and orientation of a shape on the canvas. The rectangle (including rotated rectangles) is defined by four vertex coordinates. The vertices must be listed in continuous clockwise order (recommended; all examples and code use clockwise order):
- Left Top (
left_top
) - Right Top (
right_top
) - Right Bottom (
right_bottom
) - Left Bottom (
left_bottom
)
The coordinate system uses normalized coordinates for adaptive support across different canvas resolutions:
- Origin
(0, 0)
: Top-left corner of the canvas - Bottom-right
(1, 1)
: Bottom-right corner of the canvas - Coordinate range: unrestricted (values outside
[0, 1]
indicate the shape is partially outside the canvas) - Normalization formula (actual coordinate → normalized coordinate):
-
normalized_x = actual_x / canvas_width normalized_y = actual_y / canvas_height
- For example, actual coordinate (200, 100) on a 1000×500 canvas is normalized to (0.2, 0.2).
-
Vertex Order and Meaning
Index | Vertex Name | Description | Example [x, y] |
---|---|---|---|
0 | left_top | Top-left vertex | [0.2, 0.2] |
1 | right_top | Top-right vertex | [0.6, 0.2] |
2 | right_bottom | Bottom-right vertex | [0.6, 0.6] |
3 | left_bottom | Bottom-left vertex | [0.2, 0.6] |
Key Rules:
- Vertices must be listed in continuous clockwise or counterclockwise order to form a closed rectangle (if using counterclockwise, ensure the order is continuous and closed; otherwise, rotation and other operations may not work as expected)
- Coordinate values may exceed
[0, 1]
, indicating the shape is partially outside the canvas (as long as any part is inside, it is considered valid)
Example Values
The black box represents the valid canvas area; x and y are normalized values relative to the actual width and height.
- A rectangle fully inside the canvas:
{
"location": [
[0.2, 0.2], // left_top
[0.6, 0.2], // right_top
[0.6, 0.6], // right_bottom
[0.2, 0.6] // left_bottom
]
}

- A rectangle partially outside the canvas
{
"location": [
[-0.2, -0.2], // left_top
[0.2, -0.2], // right_top
[0.2, 0.2], // right_bottom
[-0.2, 0.2] // left_bottom
]
}

- Rectangle from Example 1 rotated 45 degrees clockwise
"location": [
[0.4, 0.1172], // left_top
[0.6828, 0.4], // right_top
[0.4, 0.6828], // right_bottom
[0.1172, 0.4] // left_bottom
]

Sample code for calculating rotated coordinates:
A positive rotation angle means clockwise; negative means counterclockwise.
function rotatePoint(point, center, angleDegrees) {
const angleRadians = angleDegrees * Math.PI / 180;
const cosTheta = Math.cos(angleRadians);
const sinTheta = Math.sin(angleRadians);
const offsetX = point[0] - center[0];
const offsetY = point[1] - center[1];
const rotatedX = center[0] + offsetX * cosTheta - offsetY * sinTheta;
const rotatedY = center[1] + offsetX * sinTheta + offsetY * cosTheta;
return [parseFloat(rotatedX.toFixed(4)), parseFloat(rotatedY.toFixed(4))];
}
function rotateRectangle(vertices, angleDegrees) {
// Calculate the center as the average of the four points
const centerX = (vertices[0][0] + vertices[1][0] + vertices[2][0] + vertices[3][0]) / 4;
const centerY = (vertices[0][1] + vertices[1][1] + vertices[2][1] + vertices[3][1]) / 4;
const center = [centerX, centerY];
return vertices.map(vertex => rotatePoint(vertex, center, angleDegrees));
}
// Example input
const rectangleVertices = [
[0.2, 0.2], // topLeft
[0.6, 0.2], // topRight
[0.6, 0.6], // bottomRight
[0.2, 0.6] // bottomLeft
];
const rotatedVertices = rotateRectangle(rectangleVertices, 45);
console.log(rotatedVertices);
// Output: [ [0.4, 0.1172], [0.6828, 0.4], [0.4, 0.6828], [0.1172, 0.4] ]
Sample Code: Strictly Checking If Four Vertices (Fixed Order) Form a Rectangle
// Check if four points form a rectangle (vertex order: left_top, right_top, right_bottom, left_bottom)
function isRectangleStrict(vertices) {
if (!Array.isArray(vertices) || vertices.length !== 4) return false;
function vector(a, b) {
return [b[0] - a[0], b[1] - a[1]];
}
function dot(u, v) {
return u[0] * v[0] + u[1] * v[1];
}
function length2(u) {
return u[0] * u[0] + u[1] * u[1];
}
const v01 = vector(vertices[0], vertices[1]); // left_top -> right_top
const v12 = vector(vertices[1], vertices[2]); // right_top -> right_bottom
const v23 = vector(vertices[2], vertices[3]); // right_bottom -> left_bottom
const v30 = vector(vertices[3], vertices[0]); // left_bottom -> left_top
// Check if all four angles are right angles
const rightAngles =
Math.abs(dot(v01, v12)) < 1e-8 &&
Math.abs(dot(v12, v23)) < 1e-8 &&
Math.abs(dot(v23, v30)) < 1e-8 &&
Math.abs(dot(v30, v01)) < 1e-8;
// Check if opposite sides are equal in length
const equalOppositeSides =
Math.abs(length2(v01) - length2(v23)) < 1e-8 &&
Math.abs(length2(v12) - length2(v30)) < 1e-8;
return rightAngles && equalOppositeSides;
}
// 1. Standard rectangle, correct order
const rect1 = [
[0, 0], // left_top
[2, 0], // right_top
[2, 1], // right_bottom
[0, 1] // left_bottom
];
console.log(isRectangleStrict(rect1)); // true
// 2. Standard rectangle, wrong order (right_top, left_top, left_bottom, right_bottom)
const rect2 = [
[2, 0], // right_top
[0, 0], // left_top
[0, 1], // left_bottom
[2, 1] // right_bottom
];
console.log(isRectangleStrict(rect2)); // false
// 3. Not a rectangle
const notRect = [
[0, 0],
[2, 0],
[1.5, 1],
[0, 1]
];
console.log(isRectangleStrict(notRect)); // false
// 4. Degenerate case (duplicate points)
const degenerate = [
[0, 0],
[2, 0],
[2, 0],
[0, 1]
];
console.log(isRectangleStrict(degenerate)); // false
Notes:
- The vertex order must be strictly: left_top, right_top, right_bottom, left_bottom.
- Incorrect order will return
false
.- Supports rotation and normalized coordinates.
Notes
- The vertex order must be strictly maintained; otherwise, operations like rotation and rendering may not work as expected.
- Normalized coordinates are suitable for responsive and multi-resolution canvas scenarios.
- Coordinates can exceed
[0, 1]
as long as any part of the shape is within the canvas.
Let me know if you need a concise version or OpenAPI schema!