资讯专栏INFORMATION COLUMN

基于WebGL-ThingJS的的平面图导航(二)

noONE / 3444人阅读

摘要:前言基于架构的可视化平台平面图导航一中已经完成了面板与我们的场景的简单交互,下面我们继续完善并给页加上鼠标悬停事件让页的标签和我们场景中的一起动起来。

前言

基于WebGL架构的3D可视化平台—平面图导航(一)中已经完成了iframe面板与我们的3D场景的简单交互,下面我们继续完善并给iframe页加上鼠标悬停事件让iframe页的img标签和我们场景中的obj一起动起来。

实现

第一步,还是使用之前的场景接着上次的继续,先编写iframe页。给每一个img标签都加上onmouseover、onmouseout 事件。





Document



          

          

          

          


第二步,房间里的物体不要要让他“飞起来”,还要给他加一个“底座”。这里叫他SurveillanceCamera类,在自己编写类的时候一定要注意,想要当前类生效一定要继承THING.Thing,并且THING.factory.registerClass(‘ClassName’, ClassName);

class SurveillanceCamera extends THING.Thing {

constructor(app) {
    super(app);
    this.app = app;
    this.isFrustum = true;
    this.opacity = 1;
    this.color = 0xff00ff;
    this.vertices = [];
    this.near = 0.1;
    this.camera = null;
    this.node = new THREE.Object3D();
    this._frustum = new THREE.Frustum();
    this._projScreenMatrix = new THREE.Matrix4();

}

setup(param) {
    super.setup(param);
    this.fov = param["fov"];
    this.aspect = param["aspect"];
    this.far = param["far"];
    this.alpha = param["alpha"];
    this.lineAlpha = param["lineAlpha"];
    this.setupComplete(param);
}

setupComplete(param) {
    super.setupComplete(param);
    this.build();
}

build() {
    if (this.node.children.length > 0) {
        this.node.children = [];
    }

    if (this.camera != null) {
        this.camera = null;
    }

    var h = this.far * Math.tan(this.fov * 0.5 * 0.017453293);
    var w = this.aspect * h;

    var geometry = new THREE.Geometry();
    this.vertices = [new THREE.Vector3(0, 0, 0), new THREE.Vector3(w, -h, -this.far), new THREE.Vector3(w, h, -this.far), new THREE.Vector3(-w, h, -this.far), new THREE.Vector3(-w, -h, -this.far)];
    var faces = [new THREE.Face3(0, 1, 2), new THREE.Face3(0, 2, 3), new THREE.Face3(0, 3, 4), new THREE.Face3(0, 4, 1), new THREE.Face3(3, 4, 1), new THREE.Face3(3, 1, 2)];
    geometry.vertices = this.vertices;

    var line_mat = new THREE.LineBasicMaterial({
        color: "#b4f5f8",
        opacity: this.lineAlpha || 0.5,
    })

    var texture = THREE.ImageUtils.loadTexture("images/light2.png");
    texture.wrapS = THREE.RepeatWrapping;
    texture.wrapT = THREE.RepeatWrapping;
    var frustum_mat = new THREE.MeshBasicMaterial({
        color: "#0aa5ff",
        opacity: this.alpha || 0.5,
        transparent: true,
        side: THREE.DoubleSide,
    });
    var line_mesh = new THREE.Line(geometry, line_mat);

    var frustum_mesh = new THREE.Mesh(geometry, frustum_mat);
    geometry.faces = faces;
    this.node.add(frustum_mesh, line_mesh);

    this.camera = new THREE.PerspectiveCamera(this.fov, this.aspect, this.near, this.far);
    this.camera.position.set(this.position[0], this.position[1], this.position[2]);
    this.camera.rotation.copy(this.node.rotation);

    this.camera.updateMatrixWorld(true);
    this._updateFrustum();
}

setPosition() {
    this.camera.position.set(this.position[0], this.position[1], this.position[2]);
    this.camera.updateMatrixWorld(true);
    this._updateFrustum();
}

_updateFrustum() {
    if (this.camera) {
        this._projScreenMatrix.multiplyMatrices(this.camera.projectionMatrix, this.camera.matrixWorldInverse);
        this._frustum.setFromMatrix(this._projScreenMatrix);
    }
}

intersectsObject(object) {
    this._updateFrustum();
    return this._frustum.intersectsObject(object);
}

intersectsBox(box) {
    this._updateFrustum();
    return this._frustum.intersectsBox(box);
}

intersectsSphere(sphere) {
    this._updateFrustum();
    return this._frustum.intersectsSphere(sphere);
}

intersectsSprite(sprite) {
    this._updateFrustum();
    return this._frustum.intersectsSprite(sprite);
}

}

THING.factory.registerClass("SurveillanceCamera", SurveillanceCamera);

第三步,鼠标悬浮事件和鼠标离开事件,这里我们使用了之前创建的SurveillanceCamera类为obj加上了一个“底座”。

//鼠标悬浮事件
function onMouseOver(targetObj,viewPoint) {

if (currentModule != null)
    return;
overModule = app.query(targetObj)[0];
overModule.style.boundingBox = true;
overModule.moveTo({
    "offset": [0, 6, 0],
    "time": 80,
});
sCamera = app.create({
    type: "SurveillanceCamera",
    name: "SurveillanceCamera_",
    position:app.query(viewPoint)[0].position,
    fov: 65,
    aspect: 1.3,
    far: 6,
});
sCamera.angleX = 90;
sCamera.style.opacity = 0.1;

}
//鼠标离开事件
function onMouseOut(targetObj) {

if (currentModule != null)
    return;
if (sCamera) {
    sCamera.destroy();
    sCamera = null;
}
outModule = overModule;
outModule.style.boundingBox = false;
outModule.stopMoving();
outModule.position = [0, 0, 0];
outModule = null;

}

演示地址:EXAMPLE

总结

利用iframe与ThingJS进行交互完成了平面图导航功能,通过自制的HTML界面,嵌入ThingJS的面板中,形成一个可自定义的导航界面,通过偏移实现相应的视觉效果。

制作一个视锥,达到投放影像的效果,这里运用面向对象的方式是为了,能够更快捷的创建视锥,起到复用的作用。

在制作过程中,将物体悬浮的过程时出现了问题,发现如果快速的操作鼠标,物体不会达到预期的视觉效果,例如,鼠标快速的在两个导航图之间切换时,对应的两个物体会不断的上升,尽管将上升与还原的速度加快,也依然无法解决问题。最后解决的办法是:新添加一个变量,将上一次悬浮的物体记录下来,就是文中的 outModule,通过对 outModule 多带带操作来解决影响问题。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100949.html

相关文章

  • 基于WebGL架构的3D可视化平台—面图导航(一)

    摘要:接下来我们就用平面导航图来解决这一问题。第二部分我会给页加上鼠标悬停事件让页的标签和我们场景中的一起动起来完整代码加载场景代码场景地址场景相关面板相关平面图导航事件相关点击事件返回事件 前言 利用CampusBuilder来搭建自己的虚拟世界过程有这样一个问题:如何快速聚焦到虚拟场景的某一位置。当然我们可以创建几个按钮对应查找我们需要去的位置(参照物)并聚焦,但是按钮并不是很炫酷也不能...

    Labradors 评论0 收藏0
  • CSS3打造3D导航

    摘要:分析代码如下标签里包裹一个盒子里包裹两个,为效果的前后面做准备。分析外观定位代码如下效果首先创造环境,保留空间在的时候,我们让旋转,正面面对我们的元素向上翻转,下面有元素翻转上来,并且在翻转时有一个凸出来的效果。 效果预览 showImg(https://segmentfault.com/img/bVqF6k);分析:可以看出hover的时候是有前后两个面的翻转,并且有一个凸出效果。 ...

    mochixuan 评论0 收藏0
  • 绕圆弧动画的向量解决方式

    摘要:方向向量与向量的向量积的方向与这两个向量所在平面垂直,且遵守右手定则。向量解决方案三方案一的问题在于,向量到向量之间的线性插值是直线均匀的,但是不是角度均匀的。 记得几年前,我的一个同事J需要做一个动画功能,大概的需求是实现球面上一个点到另外一个点的动画。当时他遇到了难度,在研究了一个上午无果的情况下,咨询了我。我就告诉他说,你先尝试一个简化的版本,就是实现圆环上一个点到另外一个点的动...

    ybak 评论0 收藏0
  • 创建华丽 UI 的 7条规则 第一部分 (2019年更新)

    摘要:未点击的按钮顶部的亮度略高于底部。我认为扁平化是未来的一种趋势。这种限制是有好处的,这有助于简化思想。同样可以采取更深的一步。顶部的导航条有更多的空间。文字搜索音乐占了整个导航条高度的。 showImg(https://segmentfault.com/img/bVbn06c?w=1000&h=451); 想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你! 简介 首先...

    anyway 评论0 收藏0

发表评论

0条评论

noONE

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<