Skip to main content

Polygons

Interactive polygons allow users to manipulate shapes by dragging their vertices. This is useful for demonstrating geometric concepts, creating custom shapes, and building interactive diagrams.

Interactive Polygon

A polygon with multiple draggable vertices. Each vertex can be independently moved to reshape the polygon.

import { InteractivePolygon } from '@wangyaoshen/locus-interaction';

const polygon = new InteractivePolygon({
points: [
[250, 80],
[400, 150],
[350, 250],
[150, 250],
[100, 150],
],
strokeColor: '#9C27B0',
fillColor: 'rgba(156, 39, 176, 0.2)',
lineWidth: 3,
pointRadius: 12,
closed: true,
onChange: (points) => {
console.log('Polygon changed:', points);
},
});

Open Polygon (Polyline)

Set closed to false to create an open polyline instead of a closed polygon. The above demo can be configured as follows:

const polyline = new InteractivePolygon({
points: [
[50, 200],
[150, 100],
[250, 180],
[350, 80],
[450, 150],
],
closed: false,
strokeColor: '#9C27B0',
lineWidth: 3,
});

Constrained Vertices

Apply constraints to all vertices for controlled movement.

import {
InteractivePolygon,
horizontal,
circle,
} from '@wangyaoshen/locus-interaction';

// All vertices constrained to a circular region
const polygon = new InteractivePolygon({
points: [
[200, 100],
[300, 150],
[250, 250],
[150, 200],
],
constrain: circle([250, 175], 100),
onChange: (points) => {
console.log('Constrained polygon:', points);
},
});

Polygon Properties

The polygon component provides several computed properties:

const polygon = new InteractivePolygon({
points: [
[0, 0],
[100, 0],
[100, 100],
[0, 100],
],
});

// Get area (only for closed polygons)
const area = polygon.getArea(); // 10000

// Get perimeter
const perimeter = polygon.getPerimeter(); // 400

// Get centroid (center of mass)
const centroid = polygon.getCentroid(); // [50, 50]

// Check if a point is inside the polygon
const inside = polygon.containsPoint([50, 50]); // true

Props

NameTypeDefaultDescription
pointsVector2[][]Array of vertex positions
closedbooleantrueWhether the polygon is closed
strokeColorstring'#9C27B0'Edge stroke color
fillColorstring'rgba(156, 39, 176, 0.2)'Fill color (closed only)
lineWidthnumber3Edge stroke width
pointColorstring'#9C27B0'Vertex color
pointRadiusnumber12Vertex radius
showPointsbooleantrueShow vertex points
constrainConstraintFunction-Constraint for all vertices
onPointMove(index, pos) => void-Called when a vertex moves
onChange(points) => void-Called when polygon changes

Using with Motion Canvas 2D

In Motion Canvas 2D, you can use the InteractivePolygon component:

import { InteractivePolygon } from '@wangyaoshen/locus-2d';
import { Vector2 } from '@wangyaoshen/locus-core';

// In your scene
<InteractivePolygon
points={[
new Vector2(-100, 50),
new Vector2(100, 50),
new Vector2(0, -80),
]}
fill="rgba(156, 39, 176, 0.3)"
stroke="#9C27B0"
lineWidth={3}
vertexColor="#9C27B0"
vertexRadius={10}
showVertices={true}
interactive={true}
onChange={(points) => console.log('Polygon changed:', points)}
/>

InteractivePolygon Props

NameTypeDefaultDescription
pointsVector2[][]Array of vertex positions
interactivebooleanfalseEnable interaction
closedbooleantrueWhether the polygon is closed
vertexColorstring'#9C27B0'Vertex point color
vertexRadiusnumber10Vertex point radius
showVerticesbooleantrueShow vertex points
constrainConstraintFunction-Constraint for vertices
onVertexMove(index, pos) => void-Vertex move callback
onChange(points) => void-Polygon change callback

Use Cases

Shape Editor

const polygon = new InteractivePolygon({
points: [
[150, 100],
[350, 100],
[350, 200],
[150, 200],
],
onChange: (points) => {
updateShapePreview(points);
},
});

// Add vertex
polygon.addVertex([250, 250]);

// Remove vertex
polygon.removeVertex(2);

Area Calculator

const polygon = new InteractivePolygon({
points: [
[100, 100],
[300, 100],
[300, 250],
[100, 250],
],
onChange: (points) => {
const area = polygon.getArea();
document.getElementById('area').textContent =
`Area: ${area.toFixed(2)} sq px`;
},
});

Custom Shape Drawing

const polygon = new InteractivePolygon({
points: [],
closed: false,
});

// Add points on click
canvas.addEventListener('click', (e) => {
const point = getCanvasCoords(e);
polygon.addVertex(point);
});

// Close polygon on double-click
canvas.addEventListener('dblclick', () => {
polygon.setClosed(true);
});