所有分类
  • 所有分类
  • 后端开发
HTML5与WebGL:打造极致3D体验,感受身临其境的魔幻之旅

HTML5与WebGL:打造极致3D体验,感受身临其境的魔幻之旅

做的还不错,比较美观,基础的交互也都满足,接下来看看怎么实现。服务器组件类要相对复杂一点,这个类中创建了一个柜身、柜门以及机柜内部的服务器组件:场景中一些必要的元素,比如墙面,地板,门,空调以及所有的机柜的生成和排放位置,还有非常重要的交互

HTML5与WebGL技术概述

HTML5与WebGL:打造极致3D体验,感受身临其境的魔幻之旅

HTML5是现在做网页的火热技术,它有好多牛逼的功能,开发人员利用这些就能轻松做出好看的网页应用。还有WebGL,这可是在浏览器里显示3D画面的小能手,让网页变得更炫丽好玩。用上HTML5和WebGL,就能做出超棒的3D页面,带给用户沉浸式的视觉享受!

3D机房Demo设计与实现

ht.Default.def('Editor.Server', Object, {//第一个参数为类名,如果为字符串,自动注册到HT的classMap中;第二个参数为此类要继承的父类;第三个参数为方法和变量的声明
    addToDataModel: function(dm) { //将节点添加进数据容器
        dm.add(this._node);// ht 中的预定义函数,将节点通过 add 方法添加进数据容器中
    },
    setHost: function() { //设置吸附
        this._node.setHost.apply(this._node, arguments); 
    },
    s3: function() {//设置节点的大小
        this._node.s3.apply(this._node, arguments);
    },
    setElevation: function() {//控制Node图元中心位置所在3D坐标系的y轴位置
        this._node.setElevation.apply(this._node, arguments);
    }
});

这篇文章要给大家展示一个超赞的HTML5 WebGL 3D机房模拟器,它酷炫无比,操作又便捷,让你感觉仿佛身临其境!我们就来扒一扒怎么制作这个宝贝吧~

HTML5与WebGL:打造极致3D体验,感受身临其境的魔幻之旅

Editor.Server服务器组件

var S = E.Server = function(obj) {//服务器组件
    var color = obj.color, 
        frontImg = obj.frontImg;
    var node = this._node = new ht.Node();//创建节点
    node.s({//设置节点的样式 s 为 setStyle 的缩写
        'all.color': color,//设置节点六面的颜色
        'front.image': frontImg //设置节点正面的图片
    });
};

首先维护好index.html中的js路径,按照顺序打开相应的js文件就行。然后,你得知道server.js里有个名叫Editor.Server的类很重要!它是由HT的ht.Default.def函数创建出来的,能生成一个ht.Node节点还能设颜色跟贴图哟~再通过这个类,就能轻轻松松搞定服务器组件对象,用相关函数搞点设置也没问题。

Editor.Cabinet机柜类

除了服务器组件,我们还得搞个Editor.Cabinet的机柜类。它比服务器组件复杂些,里头有柜子身子和柜子门,甚至还有机柜里面的服务器配件啥的。这样一来,利用这个类就能做出来真实好看的机柜模型了,让游戏画面更酷炫

ht.Default.def('Editor.Cabinet', Object, {
    addToDataModel: function(dm) {
        dm.add(this._door);
        dm.add(this._node);
        this._serverList.forEach(function(s) { 
            s.addToDataModel(dm); 
        });
    },
    p3: function() { 
        this._node.p3.apply(this._node, arguments);//设置节点的 3d 坐标
    }
});

HT封装函数与3D场景创建

HTML5与WebGL:打造极致3D体验,感受身临其境的魔幻之旅

咱们在演示里就用了个HT封装函数搞出来了个3D场景,直接给个例子你看怎么操作。就这么点事儿,你把这个3D组件随手加到网页上就能搞定。你试试,用这个方法,你很快就能做出那种有互动感又眼球爆炸的虚拟环境!

双击事件处理与相机视角切换

var C = E.Cabinet = function(obj) {
    var color = obj.color,
        doorFrontImg = obj.doorFrontImg,
        doorBackImg = obj.doorBackImg,
        s3 = obj.s3;
    var node = this._node = new ht.Node(); // 柜身
    node.s3(s3);//设置节点的大小 为 setSize3d
    node.a('cabinet', this);//自定义 cabinet 属性
    node.s({//设置节点的样式 为 setStyle
        'all.color': color,//设置节点六面的颜色
        'front.visible': false//设置节点前面是否可见
    });
    if (Math.random() > 0.5) {
        node.addStyleIcon('alarm', {//向节点上添加 icon 图标
            names: ['icon 温度计'],//包含多个字符串的数组,每个字符串对应一张图片或矢量(通过ht.Default.setImage注册)
            face: 'top',//默认值为front,图标在3D下的朝向,可取值left|right|top|bottom|front|back|center
            position: 17,//指定icons的位置
            autorotate: 'y',//默认值为false,图标在3D下是否自动朝向眼睛的方向
            t3: [0, 16, 0],//默认值为undefined,图标在3D下的偏移,格式为[x,y,z]
            width: 37,//指定每个icon的宽度,默认根据注册图片时的宽度
            height: 32,//指定每个icon的高度,默认根据注册图片时的高度
            textureScale: 4,//默认值为2,该值代表内存实际生成贴图的倍数,不宜设置过大否则影响性能
            visible: { func: function() { return !!E.alarmVisible; }}//表示该组图片是否显示
        });
    }
    var door = this._door = new ht.DoorWindow();//柜门
    door.setWidth(s3[0]);//置图元在3D拓扑中的x轴方向的长度
    door.setHeight(1);//设置图元在3D拓扑中的z轴长度
    door.setTall(s3[1]);//控制Node图元在y轴的长度
    door.setElevation(0);//设置图元中心在3D坐标系中的y坐标
    door.setY(s3[2] * 0.5);//设置节点在 y 轴的位置
    door.setHost(node);//设置吸附
    door.s({//设置节点样式 setStyle
        'all.color': color,//设置节点六面颜色
        'front.image': doorFrontImg,//设置节点正面图片
        'front.transparent': true,//设置节点正面是否透明
        'back.image': doorBackImg,//设置节点背面的图片
        'back.uv': [1,0, 1,1, 0,1, 0,0],//自定义节点后面uv贴图,为空采用默认值[0,0, 0,1, 1,1, 1,0]
        'dw.axis': 'right'//设置DoorWindow图元展开和关闭操作的旋转轴,可取值left|right|top|bottom|v|h
    });
    var serverList = this._serverList = []; 
    var max = 6,
        list = E.randomList(max, Math.floor(Math.random() * (max - 2)) + 2); //global.js 中声明的获取随机数的函数 
    var server, h = s3[0] / 4;
    list.forEach(function(r) {
        var server = new E.Server({ //服务器组件
            color: 'rgb(51,49,49)',
            frontImg: '服务器 组件精细'
        });
        server.s3(s3[0] - 2, h, s3[2] - 4);//设置节点大小
        server.setElevation((r - max * 0.5) * (h + 2));//设置节点中心点在 y 轴的坐标
        server.setHost(node);//设置节点的吸附
        serverList.push(server);//向 serverList 中添加 server 节点
    });
};

我们做的这个Demo,就是让你能轻松点个机柜或者其他相关物品,然后,3D画面里的摄像头就会自动跑到它们前面的那个地方去!这样子的话,你就能更自在地探索整个虚拟机房

参数设置方法封装与事件监听

var E = window.Editor = {
    leftWidth: 0,
    topHeight: 40,
    randomList: function(max, size) {
        var list = [], ran;
        while (list.length = 0) 
                continue;
            list.push(ran);
        }
        return list;
    }
};

为简便操作及提高代码弹性,我们把设定眼睛位置以及定位盯梢对象的功能打包了起来,搞定!而且,在此过程中只需要抓住HT封装的微小信号做出反应就行~这样一整套简洁明快的设计,让我们的代码看起来更易懂,逻辑也更加清晰。

页面元素加载与窗口大小变化处理

var g3d = E.main = new ht.graph3d.Graph3dView(); //3d 场景

平时用的时候,别只看功能够不够牛,还要想想网站元素怎么跟着窗口变起来?这个小DEMO就厉害了,它能监视窗口尺寸变没变形,然后通过调用Invalidate函数来刷新界面,确保你看到的东西尺寸合适咯~

HT组件嵌入与容器使用

我们可以用HT的BorderPane、SplitView和TabView等容器做开发。实际上,得把它们嵌套到HT的组件里才行。还有,当你让最外面那层HT组件装满整个窗口的时候,记得手动添加上底的那部分节点到DOM元素里去,还要留意下窗口大小变化的状况,以便及时调整更新信息。

// 设置眼睛位置
var setEye = function(eye, finish) {
    if (!eye) return;
    var e = g3d.getEye().slice(0),//获取当前 eye 的值
        dx = eye[0] - e[0],
        dy = eye[1] - e[1],
        dz = eye[2] - e[2];
    // 启动 500 毫秒的动画过度
    ht.Default.startAnim({
        duration: 500,
        easing: easing,//动画缓动函数
        finishFunc: finish || function() {}, //动画结束后调用的函数
        action: function(v, t) {//设置动画v代表通过easing(t)函数运算后的值,t代表当前动画进行的进度[0~1],一般属性变化根据v参数进行
            g3d.setEye([ //设置 3D 场景中的 eye 眼睛的值,为一个数组,分别对应 x,y,z 轴的值 
                e[0] + dx * v,
                e[1] + dy * v,
                e[2] + dz * v
            ]);
        }
    });
};

JSON文件获取与最终效果呈现

最后,要记得把3D场景完美地加到html里面去,保证网页加载的时候能顺利显示出来。同时,也可以用网络检查工具看看相应的JSON文件数据有没有加载成功,就知道你的VMF房间成功展现给大家了没!

g3d.mi(function(e) {//addInteractorListener 事件监听函数
    if (e.kind !== 'doubleClickData')  //判断事件类型为双击节点
        return;
    var data = e.data, p3;
    if (data.a('cabinet')) //机身
        p3 = data.p3();
    else {
        host = data.getHost(); //获取点击节点的吸附对象
        if (host && host.a('cabinet')) {//如果吸附对象为 cabinet
            p3 = host.p3();
        }
    }
    if (!p3) return;
    setCenter(p3); //设置 center 目标的要移向位置为 cabinet 的位置
    setEye([p3[0], 211, p3[2] + 247]); //设置 eye 眼睛要移向的位置
});

原文链接:https://www.icz.com/technicalinformation/web/javascript/2024/04/13669.html,转载请注明出处~~~
0

评论0

请先
注意:请收藏好网址www.icz.com,防止失联!站内免费资源持续上传中…!赞助我们
显示验证码
没有账号?注册  忘记密码?