Hello Wrold(2.5) - - Typescript

本来Hello World打算3篇写完的,但是中途又了解到还有一个WebGL库叫Babylon.js也很好用,就跑去试了下。
结果好不好用没感觉出来,倒是因为这个库推荐用Typescript来写,到是感觉这个东西太好用了,有写AS3的感觉。

于是就多了这篇,把之前写的都用Typescript重写下。

0. 本文做了什么

用VS管理项目,并用Typescript重写。

1. 搭建开发环境

为什么要用VS这个前端并不常用的IDE来写网页呢……因为我平时用C++嘛,对VS很熟,说实话之前我是用Webstorm来写的,但是总觉得那些语法提示的速度和方式都不太对啊,再加上本来Typescript也是微软的东西,就用这个吧。

不过Typescript虽然是微软的东西,但并没有做限制,你用很多工具都可以弄。

如果你不打算用VS,那你可以跳过这一节。

1.1 安装Visual Studio 2017

VS2017的安装包管理改了很多,相比之前的版本划分更细了。
如果你知道哪些要装哪些不装,那这个软件其实并没有多大。

勾选的包

安装时只要勾上ASP.NET和Web开发这一条就行了。

1.2 创建解决方案

菜单栏->文件->新建->项目
选择 其他项目类型->空白解决方案

1.3 创建threeJs项目

然后在右侧解决方案上右键,在文件资源管理器中打开文件夹
新建一个文件夹命名为threeJS

再次右键,添加->现有网站,选择刚才创建的文件夹。

1.4 添加three.js的typing文件

如果three.js没有typing文件,翻译器就不知道里面的类型,也就不能自动补全了。

再次右键,管理NuGet程序包
搜索threeJs,选择threejs.TypeScript.DefinitelyTyped安装

然后展开这个项目,你会发现下面多了three.js的typing文件。

1.5 添加three.js库文件

虽然有了typing文件已经完全可以进行编写Typescript工作了,但是没有three.js库文件哦~
从你下载的three.js官方项目里把three.jsOrbitControls.js拖进Script文件夹下。

1.6 添加资源

右键项目新建一个img文件夹
从three.js官方项目里把colors.png拖进去。

1.7 创建Hello World

右键threeJs项目,添加文件夹命名为Hello World
右键这个文件夹,添加->添加新项,选HTML页,命名默认为HomePage
再重复一次,这次选Typescript文件,命名为Proj

2. 重写

打开HomePage.html,写入

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Hello World</title>
    <style>
        html, body {
            overflow: hidden;
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }

        #canvasRender {
            width: 100%;
            height: 100%;
            touch-action: none;
        }
    </style>
    <script src="../Scripts/three.js"></script>
    <script src="../Scripts/OrbitControls.js"></script>
    <script src="Proj.js"></script>
</head>
<body>
    <canvas id="canvasRender"></canvas>
</body>
</html>

打开Proj.ts,写入

class Project {
    constructor(canvasID: string) {
        let canvas = <HTMLCanvasElement>document.getElementById(canvasID);

        const width = window.innerWidth;
        const height = window.innerHeight;

        // renderer
        {
            let webGL = false;
            try {
                let canvas = document.createElement('canvas');
                if (canvas.getContext('webgl') || canvas.getContext('experimental-webgl')) {
                    webGL = true;
                }
            }
            catch (e) {
                webGL = false;
            }

            if (webGL) {
                let renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true });
                renderer.setClearColor(new THREE.Color(0x555555));
                renderer.setSize(width, height);

                this.renderer = renderer;
            }
            else {
                let renderer = new THREE.CanvasRenderer();
                renderer.setClearColor(new THREE.Color(0x555555));
                renderer.setSize(width, height);

                this.renderer = renderer;
            }
        }

        // scene
        {
            this.scene = new THREE.Scene();
        }

        // camera
        {
            this.camera = new THREE.PerspectiveCamera(75, canvas.width / canvas.height, 0.1, 1000);
            this.camera.lookAt(new THREE.Vector3(0, 0.5, 0));
            this.camera.position.set(0, 3, 5);
            //this.camera.position = new THREE.Vector3(0, 3, 5);
            this.scene.add(this.camera);
        }

        // control
        {
            this.control = new THREE.OrbitControls(this.camera, this.renderer.domElement);
        }

        // axes
        {
            let axes = new THREE.AxisHelper(1);
            axes.position.set(-0.5, 1.5, -0.5);
            this.scene.add(axes);
        }
        // cube
        {
            let mat = new THREE.MeshBasicMaterial({ color: 0xff0000 });
            let geom = new THREE.CubeGeometry(1, 1, 1);

            let cube = new THREE.Mesh(geom, mat);
            cube.position.set(0, 0.5 + 0.01, 0);
            this.scene.add(cube);
        }

        // ground
        {
            let geom = new THREE.PlaneGeometry(100, 100);

            let tex = new THREE.TextureLoader().load('../img/colors.png');
            tex.repeat.set(10, 10);
            tex.wrapS = tex.wrapT = THREE.RepeatWrapping;

            let mat = new THREE.MeshBasicMaterial({ map: tex, side: THREE.DoubleSide });

            let ground = new THREE.Mesh(geom, mat);
            ground.rotateX(Math.PI * -0.5);
            this.scene.add(ground);
        }
    }

    doRender(): void {
        this.renderer.render(this.scene, this.camera);
    }

    resize(): void {
        this.renderer.setSize(window.innerWidth, window.innerHeight);
    }

    private renderer: THREE.Renderer;
    private scene: THREE.Scene;
    private camera: THREE.Camera;
    private control: THREE.OrbitControls;
}

let proj: Project;
function startLoop(): void {
    requestAnimationFrame(startLoop);
    proj.doRender();
}

window.addEventListener('DOMContentLoaded', () => {
    proj = new Project('canvasRender');
    startLoop();
});

window.addEventListener('resize', () => {
    if (proj) {
        proj.resize();
    }
});

3. 运行

右键threeJs项目,设为启动项目
右键HomePage.html,设为起始页

上面有个绿色三角,右边的下拉里可以选运行的浏览器

按F5可以调试,CTRL+F5不调试直接运行

每次你保存ts文件,VS都会自动生成js文件,你也可以选菜单中的生成来手动生成。

运行后你会收到一条警告消息,说THREE.AxisHelper已经改了名字了叫THREE.AxesHelper,不过typing文件好像不够新并不支持用新名字。2017.11.21

4. 已经做的改进

  1. 把代码整理到一个Project类里了
  2. 重新调整了FOV,远近平面,物体大小
  3. 创建渲染器时做了检测,如果不支持WebGLRenderer就用CanvasRenderer
  4. 不是创建一个dom元素添加到body中,而是从body中获取一个dom元素进行渲染
  5. 添加事件响应:dom加载完毕自动启动我们写的项目
  6. 添加事件响应:页面大小改变后重设渲染器渲染输出大小
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值