An interactive educational tool for learning vector operations through visual experimentation. Draw vectors on a 2D Cartesian plane and perform operations like addition, subtraction, scalar multiplication, and dot products with smooth animated visualizations.
- Interactive Vector Creation: Click and drag on the grid to create vectors (up to 12, each with its own color)
- Choose Your Operands: Every operation has dropdowns to pick which vectors it uses
- Real-time Calculations: View coordinates, magnitude, and angle for each vector
- Animated Operations: Smooth transitions showing vector transformations
- Formula Display: Mathematical formulas and calculations shown for each operation
- Tensor Visualization: Interactive 3D visualization of tensors (scalars, vectors, matrices, 3D tensors)
- ✅ Vector Addition (v₁ + v₂)
- ✅ Vector Subtraction (v₁ - v₂)
- ✅ Scalar Multiplication (with custom scalar values)
- ✅ Dot Product (v₁ · v₂)
- ✅ Magnitude Calculation (||v||)
- ✅ Angle Measurement (in degrees from positive x-axis)
The application supports three interaction modes:
- Vector Mode: Draw and manipulate vectors on a 2D Cartesian plane with animated operations
- Matrix Mode: Visualize 2×2 matrix transformations and their effects on basis vectors
- Tensor Mode: Explore tensors of different ranks (0-3) in an interactive 3D space
Modes can be enabled/disabled via the enabledModes array in client/config.json. The default mode is set via the mode property in the config file.
Every sidebar section can be shown or hidden from client/config.json, so a practice can expose only the tools it needs. Students cannot change this from the page: hidden sections are removed, not just styled away.
"vectorMode": {
"sections": {
"addition": { "shown": true },
"dotProduct": { "shown": false }
}
}| Mode | Section keys |
|---|---|
vectorMode |
coordinateMode, reset, vectorList, addition, scalarMultiplication, dotProduct, projectionAngle, normalization, perpendicular, reflection, linearCombination |
matrixMode |
reset, addition, scalarMultiplication, multiplication, linearTransformation, determinant |
tensorMode |
reset, rank0, rank1, rank2, rank3, controlsHint |
- Sections left out of the config are shown. Misspelled keys are ignored with a warning in the browser console.
- The "Operations" heading disappears when every operation in it is hidden.
- Matrix mode's
includeVectorstill applies: with a vector, the two-matrix operations stay hidden; without one,linearTransformationstays hidden. - In Tensor mode, the first visible rank is selected on load, and the rank selector disappears when only one rank is visible.
- The older
operationGroupsbooleans (e.g."dotProduct": false) still work;sectionstakes precedence.
- Left Sidebar: Control panel with mode-specific information and operation buttons
- Main Canvas: Full-screen coordinate plane (2D for vector/matrix modes, 3D for tensor mode)
- No Scrolling: Fully responsive, single-page layout
- Help System: Comprehensive help modal with instructions and FAQ
-
Start the development server:
npm install npm start
Vite serves the app at
http://localhost:3000. The logging and WebSocket API runs on port 3001 and is proxied through Vite. -
Choose a mode:
- Use the mode switcher buttons (if multiple modes are enabled)
- Default mode is set in
client/config.json(modeproperty) - Available modes: Vector, Matrix, Tensor
-
Vector Mode:
- Click and drag anywhere on the grid to create vectors (v₁ to v₁₂), or press + in the sidebar and type the coordinates
- Drag a vector's tip, or type into its sidebar fields (x/y in Cartesian, r/θ° in Polar), to change it; press × to remove it
- Pick operands from each operation's dropdowns, then press its button
- Watch animated results and read formulas in the Results section
-
Matrix Mode:
- Enter values in the 2×2 matrix input grid
- See how the matrix transforms basis vectors î and ĵ
- Toggle determinant visualization to see area scaling
-
Tensor Mode:
- Select a tensor rank (0-3) using the rank buttons
- Rank 0: Scalar (single value)
- Rank 1: Vector (x, y components)
- Rank 2: Matrix (2×2 grid)
- Rank 3: 3D Tensor (2×2×2 cube)
- Enter values in the input fields to modify tensor components
- Drag to rotate the 3D visualization, scroll to zoom
- See detailed help in
help-content-tensor.html
learn-bespoke-linear-algebra/
├── client/
│ ├── index.html # Main HTML structure
│ ├── bespoke.css # Core CSS framework
│ ├── linear-algebra.css # App-specific styles
│ ├── linear-algebra.js # Main application logic
│ ├── help-modal.js # Help modal component
│ ├── help-content-*.html # Mode-specific help content
│ ├── app.js # WebSocket/status handling
│ ├── config.json # Application configuration
│ ├── core/ # Shared services
│ │ ├── config.js # Config service
│ │ ├── mode-manager.js # Mode switching
│ │ ├── theme-service.js # Theme management
│ │ ├── coordinate-system.js # Coordinate system (per-mode pan/zoom view)
│ │ ├── viewport-controller.js # Pan + zoom input for 2D modes
│ │ └── ... # Other core services
│ ├── modes/ # Mode controllers
│ │ ├── vector-mode.js # Vector mode controller
│ │ ├── matrix-mode.js # Matrix mode controller
│ │ ├── tensor-mode.js # Tensor mode controller
│ │ ├── tensor-canvas-3d.js # 3D canvas renderer
│ │ └── ... # Other mode files
│ └── entities/ # Data models
│ └── matrix.js # Matrix class
├── server.js # Development server
├── package.json # Dependencies
└── README.md # This file
- Frontend: Vanilla JavaScript (ES6+), HTML5 Canvas, CSS3
- Backend: Node.js (development server)
- No Frameworks: Pure JavaScript for educational clarity
Main application class managing:
- Canvas rendering and coordinate system
- Vector creation and manipulation
- Mouse interaction handling
- Animation system
- UI updates
Mathematical vector class with:
- Component storage (x, y)
- Operations (add, subtract, scale, dot)
- Calculation methods (magnitude, angle)
- Cartesian coordinate system with origin at center
- Grid rendering with axis labels
- Coordinate transformation (screen ↔ mathematical)
- High DPI display support
Edit the STYLE_CONSTANTS object in linear-algebra.js:
const STYLE_CONSTANTS = {
gridSize: 40, // pixels per unit
arrowHeadSize: 12, // pixels
vectorLineWidth: 3,
animationDuration: 800, // milliseconds
colors: {
vectorPalette: ['#ef4444', '#3b82f6', /* ...one color per vector, 12 total */],
result: '#10b981', // green
// ...
}
};- Linear Algebra Courses: Visual supplement to theoretical concepts
- Physics Education: Understanding force vectors and motion
- Computer Graphics: Intuition for vector operations
- Self-Study: Interactive exploration of vector mathematics
Modern browsers with Canvas support:
- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
Use this checklist to verify all modes work correctly after changes:
- Mode switcher buttons appear/disappear based on
enabledModesconfig - Switching between modes updates the UI correctly
- Each mode displays its own sidebar content
- Canvas renders correctly for each mode
- Click and drag creates vectors on the canvas
- Vector operations (add, subtract, scalar multiply, dot product) work
- Animations play smoothly
- Results panel displays calculation formulas
- Status remains "Ready" after operations
- Matrix input grid accepts numeric values
- Basis vectors update when matrix changes
- Determinant visualization toggles correctly (if enabled)
- Reset button restores identity matrix
- Status remains "Ready" after operations
- Rank buttons (0-3) update UI inputs correctly
- Rank toggle updates 3D render visualization
- Scalar input (rank 0) updates single cube visualization
- Vector inputs (rank 1) update two-cube visualization
- Matrix inputs (rank 2) update 2×2 grid visualization
- Tensor3D inputs (rank 3) update 2×2×2 cube visualization
- Drag interaction rotates 3D view smoothly
- Scroll/zoom interaction works correctly
- Reset button restores default tensor values
- Help button shows tensor help content when tensor mode is active
- Status remains "Ready" after all interactions
- Theme changes update all mode visualizations correctly
- Switching away from a mode cleans up properly (no memory leaks)
- Event listeners are removed when modes are destroyed
- Canvas interaction handlers are cleaned up (especially tensor mode 3D canvas)
The core CSS framework providing:
- Consistent design tokens (colors, spacing, typography)
- Light and dark theme support
- Reusable component styles (buttons, forms, modals, cards)
- Responsive design utilities
A base HTML template that includes:
- Navigation header with app name and help button
- Main layout structure (sidebar + content area)
- Help modal integration
- Proper CSS and JavaScript loading
A dependency-free JavaScript module for the help modal system:
- Consistent modal behavior across all apps
- Keyboard navigation (ESC to close)
- Focus management
- Custom event system
A template for creating consistent help content:
- Table of contents navigation
- Standardized section structure
- FAQ with collapsible details
- Image integration guidelines
-
Fork the repository
-
Customize the HTML template by replacing placeholders:
<!-- APP_TITLE -->- Your application title<!-- APP_NAME -->- Your application name (appears in header)<!-- APP_SPECIFIC_HEADER_CONTENT -->- Any additional header elements<!-- APP_SPECIFIC_MAIN_CONTENT -->- Your main content area<!-- APP_SPECIFIC_CSS -->- Links to your app-specific CSS files<!-- APP_SPECIFIC_SCRIPTS -->- Links to your app-specific JavaScript files
-
Implement your application logic. You can use Cursor or other agents for it. There is a file called
AGENTS.mdthat contains context LLM can use. -
Customise your help content using the help content template
Use the help-content-template.html as a starting point:
- Replace placeholders like
<!-- APP_NAME -->with your actual content - Add sections as needed for your application
- Include images by placing them in a
help/img/directory - Use the provided structure for consistency across applications
bespoke.css now consumes the CodeSignal Design System tokens directly. Use
those tokens in your overrides instead of the legacy --bespoke-* variables:
.sidebar {
background: var(--Colors-Backgrounds-Main-Medium);
padding: var(--UI-Spacing-spacing-ms);
border-radius: var(--UI-Radius-radius-s);
}The HelpModal class provides several methods:
// Initialize
const modal = HelpModal.init({
triggerSelector: '#btn-help',
content: helpContent,
theme: 'auto'
});
// Update content dynamically
modal.updateContent(newHelpContent);
// Destroy the modal
modal.destroy();Development uses Vite for the app and server.js for the API:
- Vite serves the files in
client/on port 3000 and proxies/logand/message server.jsaccepts those requests and the WebSocket broadcast on port 3001
npm install
npm startThe app is at http://localhost:3000. npm run start:prod serves client/ from server.js without Vite.
The server provides a POST /message endpoint that allows you to send real-time messages to connected clients. This can be used to signal changes in the client during events like "Run" or "Submit". When a message is sent, the preview window with the application open will display an alert with the message.
It uses the ws package, so if you want to use it, install the packages (but this is optional).
npm install
Request Format:
{
"message": "Your message here"
}Example using curl:
curl -X POST http://localhost:3000/message \
-H "Content-Type: application/json" \
-d '{"message": "Hello from the server!"}'