前言3D场景中的表面不仅仅是水平面,空间是由无数个表面组成的,所以我们可能会在任意表面上放置物体,而空间中的表面如何确定?我们知道空间中的一个面可以由一个点和一条法线组成。这个Demo的左边是面板。将对象从面板拖到右侧的3D场景中。当然,我拖动鼠标的位置就是放置物体的点,但是这次我们的重点是如何将模型放置在斜坡上。效果图:代码生成创建场景dm=newht.DataModel();//数据模型(http://hightopo.com/guide/guide/core/datamodel/ht-datamodel-guide.html)g3d=newht.graph3d.Graph3dView(dm);//3D场景组件(http://hightopo.com/guide/guide/core/3d/ht-3d-guide.html)palette=newht.widget.Palette();//面板组件(http://hightopo.com/guide/guide/plugin/palette/ht-palette-guide.html)splitView=newht.widget.SplitView(palette,g3d,'h',0.2);//SplitComponent,第三个参数为split方法,h为左右,v为上下;第四个参数是拆分比例,大于1的值是绝对宽度,小于1的是比例splitView.addToDOM();//将这些组件的定义可以在对应的链接中查看。至于给body添加split组件的addToDOM函数,有必要说明一下(我每次都提到,这个真的很重要!)。HT组件一般嵌入在BorderPane、SplitView、TabView等容器中,而最外层的HT组件需要用户手动将getView()返回的底层div元素添加到页面的DOM元素中。这里需要注意的是,当父容器的尺寸变化时,如果父容器是BorderPane、SplitView等HT预定义的容器组件,HT容器会自动递归调用子组件的invalidate函数通知更新.但是如果父容器是原生的html元素,HT组件无法知道它需要更新,所以最外层的HT组件一般需要监听window的窗口大小变化事件,调用最外层组件的invalidate函数更新。为了方便加载最外层组件填满窗口,HT的所有组件都有addToDOM函数,实现逻辑如下,其中iv是invalidate的简写:addToDOM=function(){varself=this,view=self.getView(),//获取组件底层divstyle=view.style;document.body.appendChild(视图);//将组件的底层div添加到bodystyle.left='0';//ht默认所有组件的位置都设置为absolute绝对定位style.right='0';style.top='0';style.bottom='0';window.addEventListener('resize',function(){self.iv();},false);//窗口大小变化事件,调用刷新函数}大家可能注意到了,我在场景中添加的坡度其实是一个ht。这种感觉会更强烈。下面是这个节点的定义:node=newht.Node();node.s3(1000,1,1000);//设置节点的大小node.r3(0,0,Math.PI/4);//学习到设置节点旋转的旋转角度,这跟我们下面要设置的拖拽的位置有关系node.s('3d.movable',false);//设置节点在3d上不可移动,因为这个节点只是一个参考,建议是不允许移动dm.add(node);//将节点添加到数据容器的左侧内容以构建Palette和GraphView。它由ht.DataModel驱动并使用ht.Group显示组。HT。节点显示按钮元素。我将加载Palette面板中图元的函数封装为initPalette,定义如下:'温度','室内','监控','其他'];varnameArr=['展览设施','机柜相关','桌椅收纳','温控','室内','视频监控','其他'];//arrNode中的索引对应于nameArr中的索引for(vari=0;i
