Web Trail V7 is a zero-latency, highly interactive web-based cursor and multi-touch trail animation designed to stream coordinate data directly into TouchDesigner in real-time. By leveraging a zero-dependency Bun.js WebSocket server and a custom binary protocol, it achieves minimum CPU and network overhead for production-grade installations.
- Spring-Friction Physics Chain: High-refresh-rate particle physics simulation mapping elastic inertia, heading spring tension, and friction constraints to all trail points.
- Dual-Canvas Rendering: Double-buffered layering with a background
#blurredCanvasrunning CSS bloom/neon glow and a foreground#mainCanvasexecuting sharp rendering passes. - Four-Pass Tapered Rendering: Multiple layered draws per frame featuring unrounded float tapering, dark depth masking (gloss/depth effect), and color-tinted crisp cores.
- Cubic Bézier & Catmull-Rom Modes: Choose between velocity-driven Cubic Bézier ribbon stretching, smooth Catmull-Rom splines, or high-performance Quadratic midpoint joins.
- Distance Constraint Chain: Rigid (exact distance) or Clamped (maximum distance) physical bonds between consecutive trail points for chain-like physical feedback.
- Interactive Multi-Color Ripples: Concentric physical ripples spawned on clicks or touchstarts, dynamically color-coded by mouse buttons (Left = trail color, Middle = Amber/gold, Right = Crimson warning).
- Multi-Touch Support: Tracks up to 10 simultaneous touches (11 total trails including mouse) with dedicated trail instances and fade-decay protection to prevent coordinate collisions.
- Zero-Dependency Bun.js Server: Zig-native, high-frequency relay server (
Bun.serve) broadcasting packets in microseconds without Node.js ornode_modules. - Binary Coordinate Protocol: Sub-microsecond packaging of normalized coordinate data into raw 8-byte frames (client-to-server) and 11-byte frames (server-to-TouchDesigner), bypassing JSON text overhead entirely.
- Glassmorphic Debug Menu: Fully-customizable parameter control panel featuring animated sliders, color pickers, auto-saved connection modes, and a live-rendering scrolling FPS graph.
- README.md — This primary documentation guide
- index.html — HTML5 Scaffold & Google Font links
- stylesheet.css — Glassmorphic styles, controls, and canvas layout
- script.js — Animation loop, FrameTime buffers, and WebSockets
- trail-system.js — Physics, LazyBrush, click ripples, and curve renders
- input_handler.js — Mouse, click, and multi-touch routing
- debug_menu.js — Data-driven control UI, stats, and FPS graph
- TD_websocket_callbacks_V7.txt — TouchDesigner Python DAT binary callbacks
- TD-Socket-Server-V4/README.md — Server setup and low-level protocol details
- TD-Socket-Server-V4/main.js — Native Bun.js binary WebSocket relay server
- TD-Socket-Server-V4/package.json — Server start definition (bun start)
Ensure you have Bun installed. Navigate to the server folder and start the script:
cd TD-Socket-Server-V4
bun main.jsThe server will boot on port 3000 with the default TouchDesigner receiver authentication token: SECRET_RECEIVER_TOKEN_123.
Simply double-click the index.html file to launch it locally in your browser.
- Local Mode: Connects to the local server at
ws://127.0.0.1:3000. - VPS Mode: Connects to the server running on the web domain hosted by the browser. Toggle modes in the debug menu.
- Add a WebSocket DAT in your TouchDesigner network.
- Set Network Address to
ws://127.0.0.1:3000(or your VPS address). - Assign TD_websocket_callbacks_V7.txt to the Callbacks DAT parameter.
- Activate the DAT toggle. TouchDesigner will authenticate automatically and start writing client positions directly into its own output table.
To keep latency at absolute zero, data is serialized into raw binary buffers instead of JSON strings.
- Sent once per browser frame (
requestAnimationFrame) to prevent network flooding. - Normalized UV coordinates:
X ∈ [0.0, 1.0],Y ∈ [0.0, 1.0](Y-flipped for TouchDesigner). - Format: two 32-bit little-endian floats.
+------------------------+------------------------+
| normX (Float32LE) | normY (Float32LE) |
| 4 bytes | 4 bytes |
+------------------------+------------------------+
The server prefixes the coordinate packet with a client routing header.
- Coordinate Update (11 bytes):
Byte 0: Packet Type (0x01) Bytes 1-2: Client ID (Uint16, big-endian) Bytes 3-10: Coordinate Payload (normX, normY) - Client Disconnect (3 bytes):
Allows TouchDesigner to immediately purge stale instances from memory:
Byte 0: Packet Type (0x02) Bytes 1-2: Client ID (Uint16, big-endian)
| Feature / Metric | V6 (Baseline) | V7 (Optimized) | Benefit |
|---|---|---|---|
| Server Engine | uWebSockets.js on Node |
Native Bun.js (Bun.serve) |
Easy compilation-free execution on Windows. |
| Payload Size | ~35-40 bytes (JSON) | 8 bytes (Binary) | ~5x reduction in network bandwidth. |
| Client Serialization | JSON.stringify |
DataView Write |
Minimal CPU cost. |
| Server Processing | JSON parse + rebuild | Zero-Copy Byte Forwarding | High scalability for multiple concurrent clients. |
| TouchDesigner Unpack | json.loads in Python |
struct.unpack |
Unpacking runs in microseconds instead of milliseconds. |
| Send Frequency | Event-driven (~1000Hz) | Frame-throttled (~60Hz) | Eliminates socket packet congestion. |