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
| Name | Type | Default | Description |
|---|---|---|---|
points | Vector2[] | [] | Array of vertex positions |
closed | boolean | true | Whether the polygon is closed |
strokeColor | string | '#9C27B0' | Edge stroke color |
fillColor | string | 'rgba(156, 39, 176, 0.2)' | Fill color (closed only) |
lineWidth | number | 3 | Edge stroke width |
pointColor | string | '#9C27B0' | Vertex color |
pointRadius | number | 12 | Vertex radius |
showPoints | boolean | true | Show vertex points |
constrain | ConstraintFunction | - | 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
| Name | Type | Default | Description |
|---|---|---|---|
points | Vector2[] | [] | Array of vertex positions |
interactive | boolean | false | Enable interaction |
closed | boolean | true | Whether the polygon is closed |
vertexColor | string | '#9C27B0' | Vertex point color |
vertexRadius | number | 10 | Vertex point radius |
showVertices | boolean | true | Show vertex points |
constrain | ConstraintFunction | - | 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);
});