Interactive Components
@wangyaoshen/locus-interaction provides several interactive components for creating engaging user experiences.
InteractivePoint
A draggable point component.
import { InteractivePoint } from '@wangyaoshen/locus-interaction';
const point = new InteractivePoint({
position: [100, 100], // Initial position
color: '#E91E63', // Color
radius: 15, // Radius
interactive: true, // Enable interaction
constrain: horizontal(100), // Constraint function
onMove: (pos) => { // Move callback
console.log('New position:', pos);
},
});
// Get/set position
point.getPosition(); // [100, 100]
point.setPosition([200, 200]);
// Drag control
point.startDrag();
point.drag([150, 150]);
point.endDrag();
// Keyboard control
point.moveByKey([1, 0], 10); // Move right 10 pixels
// State subscription
point.subscribe((state) => {
console.log('State changed:', state);
});
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
position | Vector2 | [0, 0] | Initial position |
color | string | '#E91E63' | Point color |
radius | number | 10 | Point radius |
interactive | boolean | true | Enable/disable interaction |
constrain | ConstraintFunction | - | Movement constraint |
onMove | (pos: Vector2) => void | - | Move callback |
Slider
A slider control for numeric values.
import { Slider } from '@wangyaoshen/locus-interaction';
const slider = new Slider({
min: 0, // Minimum value
max: 100, // Maximum value
value: 50, // Current value
step: 1, // Step value
direction: 'horizontal', // Direction
length: 200, // Track length
position: [100, 100], // Track start position
onChange: (value) => { // Value change callback
console.log('New value:', value);
},
});
// Get/set value
slider.getValue(); // 50
slider.setValue(75);
// Increment/decrement
slider.increment();
slider.decrement();
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
min | number | 0 | Minimum value |
max | number | 100 | Maximum value |
value | number | 50 | Initial value |
step | number | 1 | Step increment |
direction | 'horizontal' | 'vertical' | 'horizontal' | Slider direction |
length | number | 200 | Track length |
position | Vector2 | [0, 0] | Track start position |
onChange | (value: number) => void | - | Value change callback |
InteractiveLine
A draggable line segment with movable endpoints.
import { InteractiveLine } from '@wangyaoshen/locus-interaction';
const line = new InteractiveLine({
start: [0, 0], // Start point
end: [100, 100], // End point
constrainStart: horizontal(0), // Start point constraint
constrainEnd: vertical(100), // End point constraint
onChange: (start, end) => {
console.log('Line changed:', start, end);
},
});
// Get line properties
line.getLength(); // Line length
line.getMidpoint(); // Midpoint position
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
start | Vector2 | [0, 0] | Start point position |
end | Vector2 | [100, 100] | End point position |
constrainStart | ConstraintFunction | - | Start point constraint |
constrainEnd | ConstraintFunction | - | End point constraint |
onChange | (start, end) => void | - | Change callback |
InteractiveCurve
A Bezier curve with draggable control points.
import { InteractiveCurve } from '@wangyaoshen/locus-interaction';
// Cubic Bezier curve
const curve = new InteractiveCurve({
type: 'cubic',
start: [0, 0],
control1: [30, 100],
control2: [70, 100],
end: [100, 0],
editableEndpoints: true, // Allow endpoint editing
showControlLines: true, // Show control lines
onChange: (points) => {
console.log('Curve changed:', points);
},
});
// Get points on curve
curve.getPointAt(0.5); // Point at t=0.5
curve.getSamplePoints(50); // 50 sample points
curve.getTangentAt(0.5); // Tangent at t=0.5
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
type | 'quadratic' | 'cubic' | 'cubic' | Curve type |
start | Vector2 | - | Start point |
control1 | Vector2 | - | First control point |
control2 | Vector2 | - | Second control point (cubic only) |
end | Vector2 | - | End point |
editableEndpoints | boolean | true | Allow endpoint editing |
showControlLines | boolean | true | Show control lines |
onChange | (points: CurvePoints) => void | - | Change callback |
Math Utilities
The package includes 2D vector and matrix operations:
import { Vector2, add, sub, scale, dist, normalize } from '@wangyaoshen/locus-interaction';
const v1: Vector2 = [100, 200];
const v2: Vector2 = [50, 50];
add(v1, v2); // [150, 250]
sub(v1, v2); // [50, 150]
scale(v1, 2); // [200, 400]
dist(v1, v2); // Distance between points
normalize(v1); // Unit vector