# Jump Pad

> A springy bounce pad for platformers and party games: a dark metal base ring with a yellow bumper, a chrome coil spring and a glowing launch plate marked with upward arrow chevrons. Diameter snaps to whole meters and the glow color is adjustable for different jump strengths.

![Jump Pad preview](https://codels.download/m/jump-pad.png)

Multi-view sheet (3/4, front, side, top): https://codels.download/m/jump-pad.sheet.png

## Facts

- Category: Game Kit › Platforms
- Size (W × H × D): 2.00 × 0.75 × 2.00 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 1,248 · Meshes: 6 · Materials: 5
- License: CC0-1.0 (Codels built-in)
- Tags: jump-pad, launcher, spring, cartoon, low-poly, stylized, sci-fi, party-game, platformer, interactable, platform, metal, round, emissive, game-ready, mobile-friendly, parametric, color-blue, color-cyan, size-medium, poly-low
- Page: https://codels.download/models/jump-pad

## Files

| Format | URL |
|---|---|
| three.js ES module (`createJumpPad()`) | https://codels.download/m/jump-pad.js |
| React Three Fiber component (`<JumpPad />`) | https://codels.download/m/jump-pad.jsx |
| Instancing module (`createJumpPadInstances(count, place)`, one draw call per material) | https://codels.download/m/jump-pad.instanced.js |
| Standalone HTML demo | https://codels.download/m/jump-pad.html |
| glTF binary | https://codels.download/m/jump-pad.glb |
| glTF binary, Meshopt-compressed (2–3× smaller; GLTFLoader needs `setMeshoptDecoder(MeshoptDecoder)`) | https://codels.download/m/jump-pad.glb?compress=meshopt |
| glTF JSON | https://codels.download/m/jump-pad.gltf |
| OBJ (vertex colors) + MTL | https://codels.download/m/jump-pad.obj · https://codels.download/m/jump-pad.mtl |
| STL | https://codels.download/m/jump-pad.stl |
| CodelSpec JSON | https://codels.download/m/jump-pad.json |

## Parameters

Append them as query parameters to any URL above to get a customized variant (e.g. `?color=...`).

| Param | Type | Range / options | Default | Current |
|---|---|---|---|---|
| `color` | color | #rrggbb | #2fd6c3 | #2fd6c3 |
| `size` | int | 1 – 4 | 2 | 2 |
| `arrows` | boolean | true \| false | true | true |

## Parts

- jumpPad (group)
  - base (lathe · base)
  - bumper (torus · bumper)
  - spring (tube · spring)
  - plate (lathe · pad)
  - chevron1 (extrude · arrow)
  - chevron2 (extrude · arrow)

## How to use

Save the code below as `jump-pad.js`, then:

```js
import { createJumpPad } from './jump-pad.js';
const model = createJumpPad();
scene.add(model);
```

## Code

```js
/**
 * Jump Pad — Codels 3D model library (https://codels.download/models/jump-pad)
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 1,248 · Size (W × H × D): 2.00 × 0.75 × 2.00 m
 *
 * Usage:
 *   import { createJumpPad } from './jump-pad.js';
 *   
 *   const model = createJumpPad();
 *   model.position.set(0, 0, 0);
 *   scene.add(model);
 */
import * as THREE from 'three';

const deg = THREE.MathUtils.degToRad;

// Revolve a 2D profile [[radius, y], ...] around the Y axis.
function lathe(points, segments, phiStart = 0, phiLength = Math.PI * 2) {
  return new THREE.LatheGeometry(points.map(([x, y]) => new THREE.Vector2(x, y)), segments, phiStart, phiLength);
}

// Extrude a 2D outline along Z (centered). bevel = [thickness, size, segments].
function extrude(outline, depth, holes = [], bevel = null) {
  const shape = new THREE.Shape(outline.map(([x, y]) => new THREE.Vector2(x, y)));
  for (const hole of holes) shape.holes.push(new THREE.Path(hole.map(([x, y]) => new THREE.Vector2(x, y))));
  const options = bevel
    ? { depth, bevelEnabled: true, bevelThickness: bevel[0], bevelSize: bevel[1], bevelSegments: bevel[2] }
    : { depth, bevelEnabled: false };
  return new THREE.ExtrudeGeometry(shape, options).translate(0, 0, -depth / 2);
}

// Tube along a smooth curve through the given points.
function tube(path, radius, tubularSegments, radialSegments, closed = false) {
  const curve = new THREE.CatmullRomCurve3(path.map(([x, y, z]) => new THREE.Vector3(x, y, z)), closed);
  return new THREE.TubeGeometry(curve, tubularSegments, radius, radialSegments, closed);
}

export function createJumpPad() {
  const root = new THREE.Group();
  root.name = 'JumpPad';

  // Materials
  const baseMat = new THREE.MeshStandardMaterial({ name: 'base', color: 0x323a4a, roughness: 0.6, metalness: 0.3, flatShading: true });
  const bumperMat = new THREE.MeshStandardMaterial({ name: 'bumper', color: 0xffc83d, roughness: 0.55, flatShading: true });
  const springMat = new THREE.MeshStandardMaterial({ name: 'spring', color: 0xcfd6e0, roughness: 0.3, metalness: 0.7, flatShading: true });
  const padMat = new THREE.MeshStandardMaterial({ name: 'pad', color: 0x2fd6c3, roughness: 0.4, emissive: 0x2fd6c3, emissiveIntensity: 0.35, flatShading: true });
  const arrowMat = new THREE.MeshStandardMaterial({ name: 'arrow', color: 0xffffff, roughness: 0.4, emissive: 0xffffff, emissiveIntensity: 0.6, flatShading: true });

  // Shared geometries
  const extrudeGeo = extrude([[0, 0.09], [0.17, -0.08], [0.17, -0.155], [0, 0.015], [-0.17, -0.155], [-0.17, -0.08]], 0.016);

  // Parts
  const jumpPad = new THREE.Group();
  jumpPad.name = 'jumpPad';
  jumpPad.scale.setScalar(2);
  root.add(jumpPad);
  const base = new THREE.Mesh(lathe([[0, 0], [0.5, 0], [0.5, 0.07], [0.46, 0.13], [0.3, 0.13], [0.3, 0.1], [0, 0.1]], 20), baseMat);
  base.name = 'base';
  jumpPad.add(base);
  const bumper = new THREE.Mesh(new THREE.TorusGeometry(0.45, 0.032, 6, 24), bumperMat);
  bumper.name = 'bumper';
  bumper.position.set(0, 0.135, 0);
  bumper.rotation.set(deg(90), 0, 0);
  jumpPad.add(bumper);
  const spring = new THREE.Mesh(tube([[0.26, 0.1, 0], [0.1838, 0.1083, 0.1838], [0, 0.1167, 0.26], [-0.1838, 0.125, 0.1838], [-0.26, 0.1333, 0], [-0.1838, 0.1417, -0.1838], [0, 0.15, -0.26], [0.1838, 0.1583, -0.1838], [0.26, 0.1667, 0], [0.1838, 0.175, 0.1838], [0, 0.1833, 0.26], [-0.1838, 0.1917, 0.1838], [-0.26, 0.2, 0], [-0.1838, 0.2083, -0.1838], [0, 0.2167, -0.26], [0.1838, 0.225, -0.1838], [0.26, 0.2333, 0], [0.1838, 0.2417, 0.1838], [0, 0.25, 0.26], [-0.1838, 0.2583, 0.1838], [-0.26, 0.2667, 0], [-0.1838, 0.275, -0.1838], [0, 0.2833, -0.26], [0.1838, 0.2917, -0.1838], [0.26, 0.3, 0]], 0.024, 48, 5), springMat);
  spring.name = 'spring';
  jumpPad.add(spring);
  const plate = new THREE.Mesh(lathe([[0, 0.28], [0.4, 0.28], [0.43, 0.31], [0.42, 0.35], [0.38, 0.365], [0, 0.365]], 20), padMat);
  plate.name = 'plate';
  jumpPad.add(plate);
  const chevron1 = new THREE.Mesh(extrudeGeo, arrowMat);
  chevron1.name = 'chevron1';
  chevron1.position.set(0, 0.368, 0.1);
  chevron1.rotation.set(deg(-90), 0, 0);
  jumpPad.add(chevron1);
  const chevron2 = new THREE.Mesh(extrudeGeo, arrowMat);
  chevron2.name = 'chevron2';
  chevron2.position.set(0, 0.368, -0.06);
  chevron2.rotation.set(deg(-90), 0, 0);
  jumpPad.add(chevron2);

  root.traverse((o) => {
    if (o.isMesh) {
      o.castShadow = true;
      o.receiveShadow = true;
    }
  });
  return root;
}

export default createJumpPad;
```

---
Codels — 3D models as code for three.js. Search more: https://codels.download/api/v1/models?q=<query> · Guide: https://codels.download/llms.txt
