css Audio - Active file-generic CSS - Active Generic - Active HTML - Active JS - Active SVG - Active Text - Active file-generic Video - Active header Love html icon-new-collection icon-person icon-team numbered-list123 pop-out spinner split-screen star tv

Pen Settings

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

You're using npm packages, so we've auto-selected Babel for you here, which we require to process imports and make it all work. If you need to use a different JavaScript preprocessor, remove the packages in the npm tab.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Use npm Packages

We can make npm packages available for you to use in your JavaScript. We use webpack to prepare them and make them available to import. We'll also process your JavaScript with Babel.

⚠️ This feature can only be used by logged in users.

Code Indentation


Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

HTML Settings

Here you can Sed posuere consectetur est at lobortis. Donec ullamcorper nulla non metus auctor fringilla. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec id elit non mi porta gravida at eget metus. Praesent commodo cursus magna, vel scelerisque nisl consectetur et.

              <script src="https://unpkg.com/three"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
              * {
  margin: 0;
  padding: 0;

body {
  height: 100%;
  overflow: hidden;
              function init() {
      // 获取浏览器窗口的宽高,后续会用
      var width = window.innerWidth
      var height = window.innerHeight

      // 创建一个场景
      var scene = new THREE.Scene()

      // 创建一个具有透视效果的摄像机
      var camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000)

      // 设置摄像机位置,并将其朝向场景中心
      camera.position.set(0, 125, 125)
      camera.lookAt(new THREE.Vector3(0, 0, 0))

      // 创建一个 WebGL 渲染器,Three.js 还提供 <canvas>, <svg>, CSS3D 渲染器。
      var renderer = new THREE.WebGLRenderer({
        antialias: true

      // 设置渲染器的清除颜色(即背景色)和尺寸
      renderer.setSize(width, height)

      // 将渲染器的输出(此处是 canvas 元素)插入到 body

      // 创建 环境光
      var ambientLight = new THREE.AmbientLight(0x777777)

      // 添加聚光灯
      var spotLight = new THREE.SpotLight(0xaaaaaa)
      spotLight.position.set(-40, 40, 80)

      function render() {
        // 渲染,即摄像机拍下此刻的场景
        renderer.render(scene, camera)

      // 创建一个平面 PlaneGeometry(width, height, widthSegments, heightSegments)
      var planeGeometry = new THREE.PlaneGeometry(120, 90, 1, 1)

      // 创建 Lambert 材质:会对场景中的光源作出反应,但表现为暗淡,而不光亮。
      var planeMaterial = new THREE.MeshLambertMaterial({
        color: 0xffffff
      var plane = new THREE.Mesh(planeGeometry, planeMaterial)

      // 以自身中心为旋转轴,绕 x 轴顺时针旋转 45 度
      plane.rotation.x = -0.5 * Math.PI
      plane.position.set(0, -10.5, -20)

      // 初始化摄像机插件(用于拖拽旋转摄像机,产生交互效果)
      var orbitControls = new THREE.OrbitControls(camera);
      orbitControls.autoRotate = true

      // 创建红色的线材质
      var lineMaterial = new THREE.LineBasicMaterial({
        color: 0xff0000

      // 创建一个半径为 8 个球体
      var boxGeometry = new THREE.SphereGeometry(8)

      // This can be used as a helper object to view the edges of a Geometry object
      var edgesGeometry = new THREE.EdgesGeometry(boxGeometry)
      var edgesLine = new THREE.LineSegments(edgesGeometry, lineMaterial)
      edgesLine.position.x = -30

      // This can be used as a helper object to view a Geometry object as a wireframe.
      var wrieframe = new THREE.WireframeGeometry(boxGeometry)
      var wrieframeLine = new THREE.LineSegments(wrieframe, lineMaterial)


      // 创建一个二维形状:三角形
      function drawShape() {

        // create a basic shape
        var shape = new THREE.Shape();

        // startpoint
        shape.moveTo(0, -10);

        // straight line upwards
        shape.lineTo(00, 10);
        shape.lineTo(20, 10);
        shape.lineTo(0, -10);

        // return the shape
        return shape;

      // 创建一个法向量材质:其颜色取决于面的法向量的方向
      var meshMaterial = new THREE.MeshNormalMaterial({
        flatShading: THREE.FlatShading,
        transparent: true,
        opacity: 1

      // ExtrudeGeometry 的参数,用于指定如何拉伸二维形状
      var options = {
        amount: 2,
        bevelThickness: 2,
        bevelSize: 0.5,
        bevelSegments: 3,
        bevelEnabled: true,
        curveSegments: 12,
        steps: 1

      // 将一个二维形状按照指定参数向 Z 轴拉伸
      var extrudeGeometry = new THREE.ExtrudeGeometry(drawShape(), options)
      var mesh = new THREE.Mesh(extrudeGeometry, meshMaterial)

      mesh.position.x = 20

      // 创建一个字体加载器
      var fontLoader = new THREE.FontLoader()

      // 字体的本质就是一堆类似 SVG 的路径,因此直线占比越高越好。
      fontLoader.load('https://threejs.org/examples/fonts/helvetiker_regular.typeface.json', function (font) {
        var textOptions = {
          font: font,
          size: 18,
          height: 4,
          curveSegments: 12,
          bevelEnabled: true,
          bevelThickness: 2,
          bevelSize: 2,
          bevelSegments: 2

        // TextGeometry 的本质就是 ExtrudeGeometry,将二维字体按照指定参数向 Z 轴拉伸
        var textGeometry = new THREE.TextGeometry('AOTU.io', textOptions)
        var textMesh = new THREE.Mesh(textGeometry, meshMaterial)
        textMesh.position.set(-44, -9, -40)

🕑 One or more of the npm packages you are using needs to be built. You're the first person to ever need it! We're building it right now and your preview will start updating again when it's ready.
Loading ..................