# startup

[three.js](..) ⟩ [examples]() ⟩ startup

{% tabs %}
{% tab title="💈範例" %}
{% embed url="https://replit.com/@pegasusroe/threejs-startup-example" %}
{% endtab %}

{% tab title="JS" %}
* [replit](https://replit.com/@pegasusroe/threejs-startup-example), require: [director](../director "mention"), [+ext](../../../browser/dom/type/node/+ext "mention")

```javascript
import * as T from './js/threejs.js';
import {$} from "./js/Node+ext.js";

const {log} = console;

// HTML elements
const html = $('html');
const body = $('body');
const canvas = $('#canvas3D');
const info = $('#info');

// geometries
const box = T.Geometry.Box( 1, 1, 1 );

// three
const threejs = new T.ThreejsManager({

    // canvas element
    canvas: $('#canvas3D'),

    // camera settings
    camera: {
        far: 5,
    },
    
    // models
    models: {

        // light
        light: T.Light.Directional(0xFFFFFF, 1),

        // cubes
        cubes: [0x8844aa, 0x44aa88, 0xaa8844].map(color => 
            T.Mesh(box, T.Material.Mesh.Phong({color}))
        ),

        // line
        line: T.Line(
            T.Geometry.Buffer.fromPoints([
                [-3, 0, 0], [0, 3, 0], [3, 0, 0]
            ].map(c => T.Vector(...c))),
            T.Material.Line.Basic({color: 0x0000ff})
        ),
    },

    // further setup
    setup: function() {
        
        // this.camera.position.set( 0, 0, 5 );
        // this.camera.lookAt( 0, 0, 0 );
        this.camera.position.z = 2;

        // light
        this.models.light.position.set(-1, 2, 4);

        // models
        [-2, 0, 2].forEach((x,i) => {
            const model = this.models.cubes[i];
            model.position.x = x;
        });
    },

    // update function for animate loop
    update: function(t) {
        this.models.cubes.forEach((cube,i) => {
            const speed = 1 + .1 * i;
            cube.rotation.x = t * speed;
            cube.rotation.y = t * speed;
        })
    }
    
});

threejs.animate();

// event handlers

window.onresize = () => {
    info.innerHTML = `
    <p>window</p>
    <ul> 
        <li>innerWidth : ${window.innerWidth}
        <li>innerHeight: ${window.innerHeight}
    </ul>

    <p>canvas</p>
    <ul> 
        <li>clientWidth : ${canvas.clientWidth} <span>(physical size)</span>
        <li>clientHeight: ${canvas.clientHeight}
        <li>width : ${canvas.width} <span>(logical CSS size)</span>
        <li>height: ${canvas.height}
        <li>style.width : ${canvas.style.width} <span>(transformed size)</span>
        <li>style.height: ${canvas.style.height}
    </ul>`;
};

window.onresize();

// log
// -----------------------------------------------
;[
    `😃 Have a nice day!`,
    `width : ${threejs.width}`,
    `height: ${threejs.height}`,
    `aspect: ${threejs.aspect.toFixed(2)}`,
    `${threejs.renderer.domElement === canvas}`,    // true
    
].forEach(x => log(x));
```
{% endtab %}

{% tab title="HTML" %}
```html
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>three.js playground</title>
    <link href="style.css" rel="stylesheet" type="text/css" />
</head>

<body>

    <div id="info">test</div>
    
    <!-- three.js canvas -->
    <canvas id="canvas3D"></canvas>

    <!-- (1)    
    import maps not yet supported by all browsers, 
    (still unsupported in Firefox and Safari)
    polyfill `es-module-shims.js` is needed.
    -->
    <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>

    <!-- (2) import maps   -->
    <script type="importmap">
      {
        "imports": {
          "three": "https://unpkg.com/three@0.149.0/build/three.module.js",
          "three/addons/": "https://unpkg.com/three@0.149.0/examples/jsm/"
        }
      }
    </script>

    <script src="test.js" type="module"></script>
</body>

</html>
```
{% endtab %}

{% tab title="CSS" %}
```css
html, body {
    margin: 0;            /* body {margin: 5px} by default */
    height: 100%;         /* fill the window */
}

html {
    background: tomato;
}

body {
    background: #333;
}

#canvas3D {
    
    /*   100% the size of its container (body)   */
    width: 100%;
    height: 100%;

    /*      
      - canvas {display: inline} by default. 
      - inline elements can end up adding "whitespace" to what is displayed. 
      - setting `display: block` removes that issue.
    */
    display: block;
}

#info {
    position: fixed;
    top: 20px;
    left: 20px;
    color: orange;
    opacity: 0.8;
}

p {
    color: dodgerblue;
}

span {
    color: gray;
}
```
{% endtab %}
{% endtabs %}
