Common Patterns
Quick recipes covering typical simple use-cases. Copy-paste and tweak.
Start with these self-contained examples if you want the same ideas in full demo form:
For advanced techniques like GPU-driven positions and custom shaders, see Advanced Patterns.
1. Basic White Line
js
const line = new MeshLine()
.lines([[0,0,0],[1,1,0],[2,0,0]])
.color(0xffffff)
.lineWidth(1) // value in unit of threejs2. Closed Circle
js
const line = new MeshLine()
.lines(circlePositions(64))
.closed(true) // close the last 2 pointsshorter methods :
js
const line = new MeshLine()
.lines(circlePositions(64), true) // lines( lines, closed )3. Dashed Line
js
const line = new MeshLine()
.lines(circlePositions(64), true)
.dash({ count: 8, ratio: 0.5 }) // dash({ count, ratio = 0.5, offset = 0 })4. Gradient
js
const line = new MeshLine()
.lines(squarePositions(4), true)
.color(0xff0000) // start of the gradient will be Red
.gradientColor(0x0000ff) // end of the gradient will be Blue5. Textured Rope
js
const line = new MeshLine()
.lines(myFloat32Array)
.map(ropeTexture) // add your texture here.6. Variable Width
js
const line = new MeshLine()
.lines(sineWavePositions(100))
.widthCallback(t => 0.1 + t * 0.9) // Thin to thick7. Animated Dashes
js
const line = new MeshLine()
.lines(circlePositions(64), true)
.dash({ count: 12, ratio: 0.3 })
// In render loop:
line.material.dashOffset.value -= 0.01 // -= for clockwise movement8. Multi-Line Segments
js
const lines = [
[[0,0,0], [1,0,0], [1,1,0]], // First segment
[[2,0,0], [3,1,0], [3,2,0]], // Second segment
[[4,0,0], [5,0,1], [4,1,1]] // Third segment
]
// this will create 3 different lines
const meshLine = new MeshLine()
.lines(lines)
.color(0xffffff)9. Dynamic Updates
js
// Pre-allocate for performance
const positions = new Float32Array(NUM_POINTS * 3)
const line = new MeshLine({ lines: positions })
// Update positions efficiently
function animate() {
updatePositions(positions) // Your update logic
line.setPositions(positions) // optimized for fast CPU->GPU updates
requestAnimationFrame(animate)
}Note: check advanced examples for more performant full-GPU techniques: instancing and GPU positioning.
10. Window Resize Handling
js
const line = new MeshLine().lines(points)
window.addEventListener('resize', () => {
// or the size of your threejs canvas.
line.resize(window.innerWidth, window.innerHeight)
})11. Sharp Corners (Miter + Smoothing)
Two knobs work together to keep polylines with sharp corners looking clean at every camera angle:
- Optional corner smoothing (geometry):
smoothSharpBends(defaultfalse) subdivides any corner whose interior bend is sharper than ~60°, splitting it into two cutoff pointssmoothSharpBendsAlphaof the way back along each adjacent segment (default0.001once enabled — visually imperceptible). Enable it when cleaner static sharp corners matter more than exact input topology. - Miter clamp (shader):
.join({ limit })caps how far the miter offset can extend. Lower values flatten spikes earlier, higher values allow long pointy miters.
js
// Default combo — stable topology, miter clamp only
const line = new MeshLine()
.lines(squarePositions(16), true)
.lineWidth(2)
// Implicit: smoothSharpBends=false, miterLimit=4
// Very sharp static polyline (zigzag-style) — opt into smoothing
const zigzag = new MeshLine()
.lines(myZigzagPoints)
.lineWidth(2)
.smoothSharpBends(true) // subdivides sharp corners
.join({ limit: 2 }) // bevel residual spikes at very sharp bends
// Exact 1:1 GPU buffer mapping (animation pinned to input indices)
const exact = new MeshLine()
.lines(myPoints)
.join({ limit: 4 })