JSCAD Examples

Practical examples and templates to get you started with JSCAD

Basic Shapes

Start with fundamental geometric primitives and transformations.

Simple Cube

function main() {
  const { cube } = jscad.primitives;
  return cube({ size: 10 });
}

Parametric Sphere

function getParameterDefinitions() {
  return [
    { name: 'radius', type: 'float', initial: 5, min: 1, max: 20 },
    { name: 'segments', type: 'int', initial: 32, min: 8, max: 64 }
  ];
}

function main(params) {
  const { sphere } = jscad.primitives;
  return sphere({ 
    radius: params.radius, 
    segments: params.segments 
  });
}

Transformed Cylinder

function main() {
  const { cylinder } = jscad.primitives;
  const { translate, rotate } = jscad.transforms;
  
  const base = cylinder({ radius: 5, height: 10 });
  const rotated = rotate([0, 0, Math.PI / 4], base);
  const positioned = translate([10, 0, 0], rotated);
  
  return positioned;
}

Parametric Designs

Create flexible designs that adapt to different parameters.

Adjustable Box

function getParameterDefinitions() {
  return [
    { name: 'width', type: 'float', initial: 20, min: 5, max: 50 },
    { name: 'height', type: 'float', initial: 15, min: 5, max: 50 },
    { name: 'depth', type: 'float', initial: 10, min: 5, max: 50 },
    { name: 'wallThickness', type: 'float', initial: 2, min: 0.5, max: 5 }
  ];
}

function main(params) {
  const { cube } = jscad.primitives;
  const { subtract } = jscad.booleans;
  
  const outer = cube({ 
    size: [params.width, params.height, params.depth] 
  });
  
  const inner = cube({ 
    size: [
      params.width - 2 * params.wallThickness,
      params.height - 2 * params.wallThickness,
      params.depth - 2 * params.wallThickness
    ]
  });
  
  return subtract(outer, inner);
}

Gear Generator

function getParameterDefinitions() {
  return [
    { name: 'teeth', type: 'int', initial: 20, min: 8, max: 100 },
    { name: 'pitchDiameter', type: 'float', initial: 30, min: 10, max: 100 },
    { name: 'thickness', type: 'float', initial: 5, min: 1, max: 20 },
    { name: 'pressureAngle', type: 'float', initial: 20, min: 14, max: 25 }
  ];
}

function main(params) {
  const { cylinder } = jscad.primitives;
  const { subtract, union } = jscad.booleans;
  const { translate, rotate } = jscad.transforms;
  
  const pitchRadius = params.pitchDiameter / 2;
  const toothHeight = pitchRadius * 0.3;
  const toothWidth = (Math.PI * params.pitchDiameter) / params.teeth * 0.4;
  
  // Create base cylinder
  const base = cylinder({ 
    radius: pitchRadius, 
    height: params.thickness 
  });
  
  // Create teeth
  const teeth = [];
  for (let i = 0; i < params.teeth; i++) {
    const angle = (i * 2 * Math.PI) / params.teeth;
    const tooth = translate([
      pitchRadius * Math.cos(angle),
      pitchRadius * Math.sin(angle),
      0
    ], cylinder({ 
      radius: toothWidth / 2, 
      height: params.thickness 
    }));
    teeth.push(tooth);
  }
  
  return union(base, ...teeth);
}

Complex Geometries

Advanced examples using Boolean operations and complex transformations.

Honeycomb Pattern

function main() {
  const { cylinder } = jscad.primitives;
  const { union, subtract } = jscad.booleans;
  const { translate } = jscad.transforms;
  
  const hexRadius = 5;
  const hexHeight = 2;
  const spacing = hexRadius * 1.8;
  
  const hexagons = [];
  
  // Create hexagonal grid
  for (let row = 0; row < 5; row++) {
    for (let col = 0; col < 5; col++) {
      const x = col * spacing + (row % 2) * spacing / 2;
      const y = row * spacing * Math.sqrt(3) / 2;
      
      const hex = translate([x, y, 0], cylinder({
        radius: hexRadius,
        height: hexHeight,
        segments: 6
      }));
      
      hexagons.push(hex);
    }
  }
  
  return union(...hexagons);
}

Spiral Staircase

function getParameterDefinitions() {
  return [
    { name: 'steps', type: 'int', initial: 20, min: 5, max: 50 },
    { name: 'stepHeight', type: 'float', initial: 2, min: 1, max: 5 },
    { name: 'stepWidth', type: 'float', initial: 8, min: 5, max: 15 },
    { name: 'radius', type: 'float', initial: 15, min: 10, max: 30 }
  ];
}

function main(params) {
  const { cube, cylinder } = jscad.primitives;
  const { union } = jscad.booleans;
  const { translate, rotate } = jscad.transforms;
  
  const steps = [];
  
  for (let i = 0; i < params.steps; i++) {
    const angle = (i * 2 * Math.PI) / params.steps;
    const height = i * params.stepHeight;
    const radius = params.radius;
    
    const step = translate([
      radius * Math.cos(angle),
      radius * Math.sin(angle),
      height
    ], rotate([0, 0, angle], cube({
      size: [params.stepWidth, 2, params.stepHeight]
    })));
    
    steps.push(step);
  }
  
  // Add central column
  const column = cylinder({
    radius: 2,
    height: params.steps * params.stepHeight
  });
  
  return union(column, ...steps);
}

Real-World Projects

Practical examples for common 3D printing and manufacturing projects.

Phone Stand

function getParameterDefinitions() {
  return [
    { name: 'phoneWidth', type: 'float', initial: 75, min: 60, max: 90 },
    { name: 'phoneHeight', type: 'float', initial: 150, min: 120, max: 180 },
    { name: 'standHeight', type: 'float', initial: 80, min: 60, max: 120 },
    { name: 'wallThickness', type: 'float', initial: 3, min: 2, max: 5 }
  ];
}

function main(params) {
  const { cube } = jscad.primitives;
  const { union, subtract } = jscad.booleans;
  const { translate, rotate } = jscad.transforms;
  
  // Base plate
  const base = cube({
    size: [params.phoneWidth + 20, 20, params.wallThickness]
  });
  
  // Back support
  const backSupport = translate([0, 10, 0], cube({
    size: [params.phoneWidth + 20, params.wallThickness, params.standHeight]
  }));
  
  // Phone holder
  const holder = translate([0, 0, params.standHeight - 20], cube({
    size: [params.phoneWidth + 10, 15, 20]
  }));
  
  // Cut out phone space
  const phoneSpace = translate([0, 0, params.standHeight - 15], cube({
    size: [params.phoneWidth, 10, 15]
  }));
  
  const mainShape = union(base, backSupport, holder);
  return subtract(mainShape, phoneSpace);
}

Cable Organizer

function getParameterDefinitions() {
  return [
    { name: 'cableCount', type: 'int', initial: 4, min: 2, max: 8 },
    { name: 'cableDiameter', type: 'float', initial: 6, min: 3, max: 12 },
    { name: 'baseSize', type: 'float', initial: 40, min: 30, max: 60 }
  ];
}

function main(params) {
  const { cube, cylinder } = jscad.primitives;
  const { union, subtract } = jscad.booleans;
  const { translate } = jscad.transforms;
  
  // Base plate
  const base = cube({
    size: [params.baseSize, params.baseSize, 3]
  });
  
  // Cable holders
  const holders = [];
  const spacing = params.baseSize / (params.cableCount + 1);
  
  for (let i = 0; i < params.cableCount; i++) {
    const x = (i + 1) * spacing - params.baseSize / 2;
    const y = 0;
    
    // Outer ring
    const outerRing = translate([x, y, 0], cylinder({
      radius: params.cableDiameter / 2 + 2,
      height: 8,
      segments: 32
    }));
    
    // Inner cutout
    const innerCutout = translate([x, y, 0], cylinder({
      radius: params.cableDiameter / 2,
      height: 8,
      segments: 32
    }));
    
    const holder = subtract(outerRing, innerCutout);
    holders.push(holder);
  }
  
  return union(base, ...holders);
}

Interactive Examples

Examples that demonstrate real-time parameter changes and animations.

Animated Wave Pattern

function getParameterDefinitions() {
  return [
    { name: 'waveCount', type: 'int', initial: 5, min: 1, max: 20 },
    { name: 'amplitude', type: 'float', initial: 10, min: 1, max: 30 },
    { name: 'frequency', type: 'float', initial: 1, min: 0.1, max: 5 },
    { name: 'time', type: 'float', initial: 0, min: 0, max: 2 * Math.PI }
  ];
}

function main(params) {
  const { cube } = jscad.primitives;
  const { union } = jscad.booleans;
  const { translate } = jscad.transforms;
  
  const waves = [];
  const segments = 50;
  
  for (let i = 0; i < segments; i++) {
    const x = (i / segments) * 100 - 50;
    const waveHeight = Math.sin(x * params.frequency + params.time) * params.amplitude;
    
    const block = translate([x, 0, waveHeight], cube({
      size: [2, 2, 2]
    }));
    
    waves.push(block);
  }
  
  return union(...waves);
}

Morphing Shape

function getParameterDefinitions() {
  return [
    { name: 'shape', type: 'choice', choices: ['cube', 'sphere', 'cylinder'], initial: 'cube' },
    { name: 'size', type: 'float', initial: 10, min: 5, max: 20 },
    { name: 'segments', type: 'int', initial: 32, min: 8, max: 64 },
    { name: 'morphFactor', type: 'float', initial: 0.5, min: 0, max: 1 }
  ];
}

function main(params) {
  const { cube, sphere, cylinder } = jscad.primitives;
  const { scale } = jscad.transforms;
  
  let geometry;
  
  switch (params.shape) {
    case 'sphere':
      geometry = sphere({ 
        radius: params.size / 2, 
        segments: params.segments 
      });
      break;
    case 'cylinder':
      geometry = cylinder({ 
        radius: params.size / 2, 
        height: params.size, 
        segments: params.segments 
      });
      break;
    default:
      geometry = cube({ size: params.size });
  }
  
  // Apply morphing effect
  const morphScale = [
    1 + params.morphFactor * 0.5,
    1 - params.morphFactor * 0.3,
    1 + params.morphFactor * 0.2
  ];
  
  return scale(morphScale, geometry);
}

Quick Actions

Try in Editor

💡 Tips

• Start with simple examples and gradually increase complexity

• Use parameters to make designs flexible

• Test your code frequently as you build

• Consider performance for complex geometries