Atlaslog
Atlaslog / Examples / three.js / Axes
three.js · Runnable Example

Axes

Runnable three.js example: Axes. Open the live demo, read the complete source, and copy the file into your project. No build step or API key.

Open standalone → Chinese notes All three.js examples
/demos/three-axes.htmlLIVE
single HTML file · CDN dependencies onlyinterface may contain Chinese labels

Source

demos/three-axes.html
<!--
  说明:在 three 的 Y 向上坐标系里摆出东、北、天三个方向,对照 GIS 的 Z 向上约定
  核心逻辑:ArrowHelper 画方向,Canvas 贴图给箭头做文字标签,Grid 提供水平参照
  依赖:three.js 0.160.0、OrbitControls · jsDelivr CDN(ESM + importmap)
-->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta name="robots" content="noindex,follow">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>坐标轴</title>
<style>
  html,body{height:100%;margin:0;background:#0d1117}
  body{display:flex;flex-direction:column;overflow:hidden;
       font:13px/1.6 -apple-system,"Segoe UI","PingFang SC",sans-serif;color:#e6e8ec}
  .bar{flex:0 0 auto;padding:8px 12px;background:#161b22;border-bottom:1px solid #252c36;
       display:flex;gap:10px;align-items:center;font-size:12px;color:#8b93a1;flex-wrap:wrap}
  .bar b{color:#58a6ff;font-weight:600}
  .bar button{font:inherit;font-size:12px;padding:4px 10px;border-radius:5px;cursor:pointer;
       border:1px solid #303845;background:#1d2531;color:#c8d2e0}
  .bar button:hover{background:#253040}
  .bar .sp{flex:1 1 auto}
  #stage{flex:1 1 auto;min-height:0;position:relative}
  #stage canvas{display:block}
</style>
</head>
<body>
<div class="bar">
  <span><b>X</b> 东 · <b>Z</b> 南 · <b>Y</b> 天(北向取 −Z)</span>
  <button id="gridbtn">隐藏网格</button>
  <button id="arrowbtn">隐藏坐标轴</button>
  <span class="sp"></span>
  <span>要素位置:E=4 m,N=3 m(即 z=−3)</span>
</div>
<div id="stage"></div>

<script type="importmap">
{
  "imports": {
    "three": "https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js",
    "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/"
  }
}
</script>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

const stage = document.getElementById('stage');
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.setSize(stage.clientWidth, stage.clientHeight);
renderer.outputColorSpace = THREE.SRGBColorSpace;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
stage.appendChild(renderer.domElement);

const scene = new THREE.Scene();
scene.background = new THREE.Color(0x0d1117);

const camera = new THREE.PerspectiveCamera(
  45, stage.clientWidth / stage.clientHeight, 0.1, 200
);
camera.position.set(9, 7, 12);

const controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 1.4, 0);
controls.enableDamping = true;
controls.dampingFactor = 0.08;
controls.maxPolarAngle = Math.PI * 0.495;
controls.update();

scene.add(new THREE.HemisphereLight(0xcfe4ff, 0x151d26, 1.15));
const key = new THREE.DirectionalLight(0xffffff, 2.2);
key.position.set(6, 10, 7);
scene.add(key);

/* GridHelper 位于 XZ 平面,等价于水平面 */
const grid = new THREE.GridHelper(20, 20, 0x3a5068, 0x1d2a36);
scene.add(grid);

/* 文字标签用 canvas 生成,不引入图片文件 */
function makeLabel(text, color) {
  const c = document.createElement('canvas');
  c.width = 128;
  c.height = 64;
  const g = c.getContext('2d');
  g.clearRect(0, 0, 128, 64);
  g.fillStyle = color;
  g.font = '600 34px "PingFang SC", "Microsoft YaHei", sans-serif';
  g.textAlign = 'center';
  g.textBaseline = 'middle';
  g.fillText(text, 64, 32);

  const tex = new THREE.CanvasTexture(c);
  tex.colorSpace = THREE.SRGBColorSpace;
  const mat = new THREE.SpriteMaterial({ map: tex, transparent: true, depthTest: false });
  const sprite = new THREE.Sprite(mat);
  sprite.scale.set(1.8, 0.9, 1);
  return sprite;
}

const ORIGIN = new THREE.Vector3(0, 0, 0);
const LEN = 5;

const axes = new THREE.Group();

const east = new THREE.ArrowHelper(
  new THREE.Vector3(1, 0, 0), ORIGIN, LEN, 0xff6b6b, 0.7, 0.36
);
const north = new THREE.ArrowHelper(
  new THREE.Vector3(0, 0, -1), ORIGIN, LEN, 0x63e6be, 0.7, 0.36
);
const up = new THREE.ArrowHelper(
  new THREE.Vector3(0, 1, 0), ORIGIN, LEN, 0x8ab4ff, 0.7, 0.36
);
axes.add(east, north, up);

const labelE = makeLabel('东 X', '#ff9b9b');
labelE.position.set(LEN + 1.1, 0.25, 0);
const labelN = makeLabel('北', '#8ff0d4');
labelN.position.set(0, 0.25, -LEN - 1.1);
const labelU = makeLabel('天 Y', '#a9c9ff');
labelU.position.set(0, LEN + 0.9, 0);
axes.add(labelE, labelN, labelU);

scene.add(axes);

/* 一个带高度的小体块,说明要素坐标 (E, N, U) 如何落到 three 的 (x, y, -z) */
const feature = new THREE.Mesh(
  new THREE.BoxGeometry(1.2, 2.2, 1.2),
  new THREE.MeshStandardMaterial({ color: 0xe0a458, roughness: 0.42, metalness: 0.18 })
);
feature.position.set(4, 1.1, -3);
scene.add(feature);

/* 从地面原点连到要素底部,标出平面偏移 */
const offsetLine = new THREE.Line(
  new THREE.BufferGeometry().setFromPoints([
    new THREE.Vector3(0, 0.01, 0),
    new THREE.Vector3(4, 0.01, 0),
    new THREE.Vector3(4, 0.01, -3)
  ]),
  new THREE.LineBasicMaterial({ color: 0x6b7f95 })
);
scene.add(offsetLine);

renderer.setAnimationLoop(function () {
  controls.update();
  renderer.render(scene, camera);
});

window.addEventListener('resize', function () {
  const w = stage.clientWidth;
  const h = stage.clientHeight;
  camera.aspect = w / h;
  camera.updateProjectionMatrix();
  renderer.setSize(w, h);
});

const gridBtn = document.getElementById('gridbtn');
let gridOn = true;
gridBtn.addEventListener('click', function () {
  gridOn = !gridOn;
  grid.visible = gridOn;
  gridBtn.textContent = gridOn ? '隐藏网格' : '显示网格';
});

const arrowBtn = document.getElementById('arrowbtn');
let axesOn = true;
arrowBtn.addEventListener('click', function () {
  axesOn = !axesOn;
  axes.visible = axesOn;
  arrowBtn.textContent = axesOn ? '隐藏坐标轴' : '显示坐标轴';
});
</script>
</body>
</html>
Language: the code and this page are in English; the full tutorial and API notes for this example are in Chinese. The demo itself is the authoritative version — it runs exactly as shown.

More three.js examples

three.js · EXAMPLEBuffer Lines three.js · EXAMPLECamera Cinematic three.js · EXAMPLECamera Logdepth