索引
HT
提供了基于WebGL的3D
技术的图形组件ht.graph3d.Graph3dView
,
WebGL
基于OpenGL ES 2.0图形接口,因此WebGL
属于底层的图形API
接口,
二次开发还是有很高的门槛,HT
的Graph3dView
组件通过对WebGL
底层技术的封装,与HT
其他组件一样,
基于HT
统一的DataModel
数据模型来驱动图形显示,极大降低了3D
图形技术开发的门槛,在熟悉HT
数据模型基础上,
一般程序员只需要1
个小时的学习即可上手3D
图形开发。
WebGL
技术已被大部分最新浏览器支持,caniuse.com/webgl网站维护着最新桌面和移动浏览器对WebGL
支持情况。
通过get.webgl.org可检测访问的浏览器是否支持WebGL
。
目前Chrome
、Firefox
、Safari
和Opera
的桌面和移动终端版本都已经支持WebGL
标准,
采用iOS
系统需要iOS8
及以上版本,采用IE
浏览器须IE11
及以上版本才支持WebGL
,
不管选择哪种类型浏览器,我们建议尽量采用最新版本。
如果你一定要使用IE6
,IE7
和IE8
等老版IE浏览器,或者因采用HT for Web 3D
,而老机器无法升级到IE11
,则可以考虑安装
Google Chrome Frame插件,
在页面嵌入以下Tag
代码片段,该页面就会采用Chrome
来渲染。
<meta http-equiv="X-UA-Compatible" content="chrome=1">
使用Google Chrome Frame
还需要注意一下几点:
Google Chrome Frame
不支持直接从本地local file
方式打开页面,必须把页面部署到Web
服务器发布方式打开Google Chrome Frame
不支持64位的浏览器:Currently, 64-bit versions of IE are not supported. It's worth pointing out that 32-bit IE is the default on 64-bit Windows 7.Google Chrome Frame
不支持iframe
方式: At this point ChromeFrame only supports the meta tag detection on top level URLs.可采用嵌入OBJECT
元素的解决方案,绕开Google Chrome Frame
不支持iframe
的问题
<OBJECT ID="ChromeFrame" WIDTH=500 HEIGHT=500 CODEBASE="http://yourdomain/yourproject/"
CLASSID="CLSID:E0A900DF-9611-4446-86BD-4B1D47E7DB2A">
<PARAM NAME="src" VALUE="http://yourdomain/yourproject/">
<embed ID="ChromeFramePlugin" WIDTH=500 HEIGHT=500 NAME="ChromeFrame"
SRC="http://yourdomain/yourproject/" TYPE="application/chromeframe">
</embed>
</OBJECT>
Google Chrome Frame
将于2014
年1
月停止支持和更新,目前Google Chrome Frame
以发展到31
的版本,
这个版本已满足HT
的2D
和3D
所需的Canvas
功能,因此HT
的客户可以放心采用Google Chrome Frame
解决老IE
问题。
其他问题可参考Google Chrome Frame
的Developer Guide
和Troubleshooting
HT
的三维坐标系由x
,y
和z
三个轴线构成,x
轴正方向朝右,y
轴正方向朝上,z
轴正方向朝向屏幕外。
HT
系统的旋转采用右手螺旋法则。
Graph3dView
的3D
坐标系与GraphView
的2D
坐标系既有关联又有差异,2D
坐标系的x
轴与3D
坐标系的x
轴对应,
2D
坐标系的y
轴与3D
坐标系的z
轴对应,2D
坐标系的xy
屏幕面相当于3D
坐标系的xz
面。
例如Node#getPosition()
返回{x: 100, y: 200}
,则代表:
2D
坐标系x
轴为100
,y
轴为200
3D
坐标系x
轴为100
,z
轴为200
例如Node#getSize()
返回{width: 300, height: 400}
,则代表:
2D
坐标系x
轴上长度300
,y
轴上长度400
3D
坐标系x
轴上长度300
,z
轴上长度400
3D
坐标系的y
轴则是与2D
坐标系没有关联的新轴,ht.Node
上增加了getElevation()
和setElevation(elevation)
函数,
控制Node
图元中心位置所在3D
坐标系的y
轴位置。同时增加了getTall()
和setTall(tall)
函数,控制Node
图元在y
轴的长度。
为了避免2D
和3D
坐标系的混乱,以及设置3D
图元位置大小的方便,HT
为ht.Node
图元增加了以下新函数:
setPosition3d(x, y, z)|setPosition3d([x, y, z])
,可传入x, y, z
三个参数,或传入[x, y, z]
的数组getPosition3d()
的新函数,返回[x, y, z]
数组值,即[getPosition().x, getElevation(), getPosition().y]
setSize3d(x, y, z)|setSize3d([x, y, z])
,可传入x, y, z
三个参数,或传入[x, y, z]
的数组getSize3d()
的新函数,返回[x, y, z]
数组值,即[getWidth(), getTall(), getHeight()]
3D
中节点同样有锚点的概念,2D
锚点参考,
同样HT
为ht.Node
图元增加了以下新函数:
setAnchor3d(x, y, z)|setAnchor3d([x, y, z])
,可传入x, y, z
三个参数,或传入[x, y, z]
的数组getAnchorElevation()|setAnchorElevation(elevation)
设置获取y
轴方向锚点getAnchor3d()
的新函数,返回[x, y, z]
数组值,即[getAnchor().x, getAnchorElevation(), getAnchor().y]
ht.Node
在2D
坐标系下由getRotation()
和setRotation(rotation)
函数控制旋转,该参数对应于3D
坐标系下沿y
轴的负旋转值。
同时3D
坐标系下增加了rotationX
和rotationZ
两个分别沿着x
轴和z
轴的新旋转变量,同时增加以下新函数:
setRotationY(y)
设置沿y
轴旋转弧度,相当于setRotation(-y)
getRotationY()
获取沿y
轴旋转弧度,相当于-getRotation()
setRotation3d(x, y, z)|setRotation3d([x, y, z])
,可传入x, y, z
三个参数,或传入[x, y, z]
的数组getRotation3d()
的新函数,返回[x, y, z]
数组值,即[getRotationX(), -getRotation(), getRotationZ()]
对于旋转还有个很重要的参数rotationMode
,该参数通过getRotationMode()|setRotationMode('xzy')
进行设置,
旋转的先后顺序会影响最终效果,该参数用于指定旋转的先后顺序,默认值为xzy
,用户可通过设置以下六种参数改变旋转顺序模式:
xyz
:先进行x
轴旋转,再进行y
轴旋转,最后进行z
轴旋转。xzy
:先进行x
轴旋转,再进行z
轴旋转,最后进行y
轴旋转。yxz
:先进行y
轴旋转,再进行x
轴旋转,最后进行z
轴旋转。yzx
:先进行y
轴旋转,再进行z
轴旋转,最后进行x
轴旋转。zxy
:先进行z
轴旋转,再进行x
轴旋转,最后进行y
轴旋转。zyx
:先进行z
轴旋转,再进行y
轴旋转,最后进行x
轴旋转。3D
中可以对节点设置渲染层级,渲染层级信息是定义在全局属性中,所有的3D
场景都将公用一套渲染层级关系,HT
在Default
上提供一下方法操作渲染层级关系:
getRenderLayerInfo(layer)
根据层级名称获取层级信息setRenderLayerInfo(layer, info)
注册/修改渲染层级信息,layer
存在则修改层级信息,不存在则创建层级信息,其中info
是一个Object
对象,可定义的属性有:priority
优先等级,数值类型,值越大表示越上层ignore
是否忽略该层级的渲染,布尔类型clearDepth
是否清除深度后绘制。当A
层想要达到盖住B
层在B
之上,A
层就需要设置更高的priority
且clearDepth:true
来清除深度HT
内部预定义了两个layer
信息,分别是main
和top
,两个层级对应的priority
分别是:
main
:10000top
:10000000HT
对ht.Node
默认规整到main
层级,增加以下新函数获取和设置层级信息:
getRenderLayer()
获取节点的层级信息setRenderLayer(layer)
设置节点的渲染层级默认根据树状 hierarchy
组织从上到下渲染,便于调整父子关系就可以干预渲染顺序。
可以通过 g3d.setSortable(true)
来干预透明物体的排序,默认排序函数是根据 node
到 eye
的视线方向 z
距离从远到近渲染,通过 g3d.setSortFunc(customFunc)
来设置自定义排序函数。这个 customFunc(itemA, itemB) { ... }
其中队列的每个 item
元素成分:{ data : data, z : z, id : dataId }
注意 z
不是位置的 z
,而是相机方向的 z
HT
对常用函数有不少简写方式,例如getDataModel()|dm()
,getSelectionModel()|sm()
等,同样3D
也有不少便捷的简写函数:
setPosition3d(x, y, z)|setPosition3d([x, y, z])
可简写为p3(x, y, z)|p3([x, y, z])
getPosition3d()
可简写为p3()
setSize3d(x, y, z)|setSize3d([x, y, z])
可简写为s3(x, y, z)|s3([x, y, z])
getSize3d()
可简写为s3()
setRotation3d(x, y, z)|setRotation3d([x, y, z])
可简写为r3(x, y, z)|r3([x, y, z])
getRotation3d()
可简写为r3()
3D投影是一种将三维空间的点映射到二维平面的算法,
既3D
空间的内容投影到2D
屏幕坐标的过程,不同的投影算法会最终产生不同的屏幕内容显示效果,
HT
支持透视投影Perspective Projection
和正交投影Orthographic Projection这两种最主常用的投影算法。
Graph3dView
组件默认采用透视投影,通过Graph3dView#setOrtho(true)
可切换到正交投影。
透视投影是为了获得接近真实三维物体的视觉效果而在二维的纸或者画布平面上绘图或者渲染的一种方法,它也称为透视图。 透视使得远的对象变小,近的对象变大,平行线会出现相交等更更接近人眼观察的视觉效果。
如上图所示,透视投影最终显示到屏幕上的内容只有截头锥体( View Frustum )部分的内容,
因此Graph3dView
提供了eye
, center
, up
, far
,near
,fovy
和aspect
参数来控制截头锥体的具体范围:
getEye()|setEye([x, y, z])
,决定眼睛(或Camera
)所在位置,默认值为[0, 300, 1000]
getCenter()|setCenter([x, y, z])
,决定目标中心点(或Target
)所在位置,默认值为[0, 0, 0]
getUp()|setUp([x, y, z])
,决定摄像头正上方向,该参数一般较少改动,默认值为[0, 1, 0]
getNear()|setNear(near)
,决定近端截面位置,默认值为10
getFar()|setFar(far)
,决定远端截面位置,默认值为10000
getFovy()|setFovy(fovy)
,fovy决定垂直方向的视觉张角弧度,默认值为Math.PI/4
getAspect()|setAspect(aspect)
,决定截头锥体的宽高比,该参数默认自动根据屏幕的宽高比决定,一般不需要设置。near
和far
虽可根据实际场景任意调节,但建议在可接受的范围内,尽量让near
和far
越接近越好,
有助于避免Z-fighting的精度问题。
正交投影也叫正交视图,在这种投影方式下,不管远近物体看起来都是同样大小,屏幕成像让人感觉与人眼观察效果不一样。 正交投影在建模过程很有用,它提供了对场景更“技术”的视觉,让它易于绘制和判断比例。
正交投影具有和透视投影一样的大部分参数,但没有fovy
参数,取而代之的是orthoWidth
参数:
isOrtho()|setOrtho(ortho)
,决定是否为正交投影,默认值为false
getOrthoWidth()|setOrthoWidth(orthoWidth)
,决定宽度,即left
和right
之间的距离,默认值为2000
HT
提供了多种基础形体类型供用户建模使用,不同于传统的3D建模方式,HT
的建模核心都是基于API
的接口方式,
通过HT
预定义的图元类型和参数接口,进行设置达到三维模型的构建,以下章节将介绍预定义的3D模型类型及设置参数,
另外可参考建模手册和
OBJ手册介绍的更多自定义扩展模型方式。
六面体是由六个面形成的立方体,是HT
系统中最常被使用的基本图元类型,默认当构建一个ht.Node
对象时显示的就是一个六面体,
六个面的整体参数可以通过style
属性的all.*
控制,例如all.color
设置为red
,那么所有六个面默认颜色都会变成红色,
如果需要具体面独立设置,则可以通过left.*|right.*|top.*|bottom.*|front.*|back.*
具体面参数控制,
例如left.color
设置为red
,那么左侧面将显示为红色,如果left.color
设置为空,则HT
会采用all.color
的值。
all.light
:默认值为true
,六面是否受光线影响,受光线影响时正面看时最亮,侧面看时变暗all.visible
:默认值为true
,六面是否可见,该参数不会影响附属部件all.color
:默认值为#3498DB
,六面颜色all.image
:默认值为undefined
,六面贴图,优先级高于all.color
all.blend
:默认值为undefined
,六面染色颜色,优先级高于all.color
,如果有贴图时,则对贴图染色all.opacity
:默认值为undefined
,六面透明度,值范围0~1
,一般有透明度时需要将all.transparent
设置为true
all.reverse.flip
:默认值为false
,六面的反面是否显示正面的内容all.reverse.color
:默认值为#868686
,六面的反面颜色,即立方体内部面颜色all.reverse.cull
:默认值为false
,六面的反面是否可见,即立方体内部面是否显示,一般六面闭合立方体,可不显示以提高性能all.transparent
:默认值为false
,六面是否透明,若color|image|opacity
属性出现透明区域情况下,一般需设置为true
all.discard.selectable
:默认值为true
,代表贴图透明度低到被剔除的部分也能点击选中,可设置为false
则被剔除部分不可选中默认情况下贴图会将整个图片填充满对应的面,但很多情况下贴图需要偏移一定位置,有时地板砖需要Tile
方式平铺,有时贴图需要翻转,
甚至有时贴图的布局需要动态变化以达到流动等特效,这种情况下就需要定制UV Mapping,
通过uv
参数告诉HT
如何将图片根据需要自定义贴到面上:
all.uv.offset
:默认值为undefined
,六面贴图的uv
偏移,格式为[0.5, 0.5]
,分别为水平和垂直方向的偏移量all.uv.scale
:默认值为undefined
,六面贴图的uv
缩放,格式为[3, 2]
,分别为水平和垂直的贴图倍数all.uv
:默认值为undefined
,六面自定义uv
参数,下面为几种常见需求的自定义uv
参数供参考[0,0, 0,1, 1,1, 1,0]
90
度:[1,0, 0,0, 0,1, 1,1]
90
度:[0,1, 1,1, 1,0, 0,0]
180
度:[1,1, 1,0, 0,0, 0,1]
180
度:[1,1, 1,0, 0,0, 0,1]
(同右旋转180
度)[0,1, 0,0, 1,0, 1,1]
[1,0, 1,1, 0,1, 0,0]
HT
在GraphView
的2D
图形上,呈现各种图形是通过style
的shape
属性决定,类似的HT
在3D
上提供了shape3d
属性,
预定义了多种3D
的形体。shape3d
的默认值为undefined
,图元显示为上章节介绍的六面立体图形,当shape3d
指定值时,
则显示为shape3d
指定的形体,其余的具体参数通过shape3d.*
进行设置:
shape3d
:默认值为undefined
,为空时显示为六面立方体,其他可选值为:box
:立方体,不同于默认的六面体,立方体类型的六个面颜色和贴图只能相同,绘制性能比默认六面体高sphere
:球体,可通过shape3d.side
分成多片,结合shape3d.side.from
和shape3d.side.to
可形成半球体等cone
:锥体,可通过shape3d.side
形成三角锥、四角锥等形状torus
:圆环,可通过shape3d.side
分成多片,结合shape3d.side.from
和shape3d.side.to
可形成半圆环等cylinder
:圆柱,可通过shape3d.top.*
和shape3d.bottom.*
可控制顶面和底面的参数star
:星形体,可通过shape3d.top.*
和shape3d.bottom.*
可控制顶面和底面的参数rect
:矩形体,可通过shape3d.top.*
和shape3d.bottom.*
可控制顶面和底面的参数roundRect
:圆矩形体,可通过shape3d.top.*
和shape3d.bottom.*
可控制顶面和底面的参数triangle
:三角形体,可通过shape3d.top.*
和shape3d.bottom.*
可控制顶面和底面的参数rightTriangle
:直角三角形体,可通过shape3d.top.*
和shape3d.bottom.*
可控制顶面和底面的参数parallelogram
:平行四边形体,可通过shape3d.top.*
和shape3d.bottom.*
可控制顶面和底面的参数trapezoid
:梯形体,可通过shape3d.top.*
和shape3d.bottom.*
可控制顶面和底面的参数billboard
: 公告板,立着的面片,一般用来做UI
等2D
信息展示plane
: 地板,躺着的面片shape3d.color
:默认值为#3498DB
,3d
图形整体颜色shape3d.top.color
:默认值为undefined
,3d
图形顶面颜色shape3d.bottom.color
:默认值为undefined
,3d
图形底面颜色shape3d.from.color
:默认值为undefined
,3d
图形起始面颜色shape3d.to.color
:默认值为undefined
,3d
图形结束面颜色shape3d.image
:默认值为undefined
,3d
图形整体贴图shape3d.top.image
:默认值为undefined
,3d
图形顶面贴图shape3d.bottom.image
:默认值为undefined
,3d
图形底面贴图shape3d.from.image
:默认值为undefined
,3d
图形起始面贴图shape3d.to.image
:默认值为undefined
,3d
图形结束面贴图shape3d.light
:默认值为true
,3d
图形是否受光线影响shape3d.side
:默认值为0
,决定3d
图形显示为几边型,为0
时显示为平滑的曲面效果shape3d.side.from
:默认值为undefined
,决定3d
图形起始边位置shape3d.side.to
:默认值为undefined
,决定3d
图形结束边位置shape3d.visible
:默认值为true
,决定3d
图形是否可见,该参数不影响label
,note
和icons
等其他部分元素shape3d.from.visible
:默认值为true
,决定3d
图形起始面是否可见shape3d.to.visible
:默认值为true
,决定3d
图形结束面是否可见shape3d.top.visible
:默认值为true
,决定3d
图形顶面是否可见shape3d.bottom.visible
:默认值为true
,决定3d
图形底面是否可见shape3d.torus.radius
:默认值为0.17
,决定3d圆环形管半径shape3d.resolution
:默认值为24
,决定3d
图形精确度,和side
类似但决定不同的方向的分段,数值越大越均匀但影响性能shape3d.blend
:默认值为undefined
,决定3d
图形的染色shape3d.opacity
:默认值为undefined
,决定3d
图形的透明度,值范围0~1
shape3d.reverse.flip
:默认值为false
,决定3d
图形的反面是否显示正面的内容shape3d.reverse.color
:#868686
,决定3d
图形的反面颜色shape3d.reverse.cull
:默认值为false
,决定3d
图形的反面是否显示,隐藏背面可提高性能shape3d.transparent
:默认值为false
,决定3d
图形是否透明shape3d.uv.offset
:默认值为undefined
,决定3d
图形整体贴图的uv
偏移,格式为[0.5, 0.5]
shape3d.uv.scale
:默认值为undefined
,决定3d
图形整体贴图的uv
缩放,格式为[3, 2]
shape3d.top.uv.offset
:默认值为undefined
,决定3d
图形顶面贴图的uv
偏移,格式为[0.5, 0.5]
shape3d.top.uv.scale
:默认值为undefined
,决定3d
图形顶面贴图的uv
缩放,格式为[3, 2]
shape3d.bottom.uv.offset
:默认值为undefined
,决定3d
图形底面贴图的uv
偏移,格式为[0.5, 0.5]
shape3d.bottom.uv.scale
:默认值为undefined
,决定3d
图形底面贴图的uv
缩放,格式为[3, 2]
shape3d.from.uv.offset
:默认值为undefined
,决定3d
图形起始面贴图的uv
偏移,格式为[0.5, 0.5]
shape3d.from.uv.scale
:默认值为undefined
,决定3d
图形起始面贴图的uv
缩放,格式为[3, 2]
shape3d.to.uv.offset
:默认值为undefined
,决定3d
图形结束面贴图的uv
偏移,格式为[0.5, 0.5]
shape3d.to.uv.scale
:默认值为undefined
,决定3d
图形结束面贴图的uv
缩放,格式为[3, 2]
shape3d.discard.selectable
:默认值为true
,整体贴图透明度低到被剔除的部分也能选中,设为false
则被剔除部分不可选shape3d.top.discard.selectable
:默认值为true
,顶部贴图透明度低到被剔除的部分也能选中,设为false
则被剔除部分不可选shape3d.bottom.discard.selectable
:默认值为true
,底部贴图透明度低到被剔除的部分也能选中,设为false
则被剔除部分不可选shape3d.from.discard.selectable
:默认值为true
,起始面贴图透明度低到被剔除的部分也能选中,设为false
则被剔除部分不可选shape3d.to.discard.selectable
:默认值为true
,结束面贴图透明度低到被剔除的部分也能选中,设为false
则被剔除部分不可选公告板对应的是shape3d
为billboard
的节点,具体形状是一块立着的面片,一般用来做2D
信息展示,例如机柜的信息面板,电子屏,楼层标签等。billboard
本身也是个3D
的node
,所以shape3d
中的属性对其都有意义。
以下列举对于billboard
来说经常使用到的属性,具体如下:
shape3d
:对应公告板请设置类型为billboard
shape3d.image
:默认值为undefined
,billboard
使用的贴图,可以是一个2D
的json
图标矢量或者png
等静态图片autorotate
:默认值为false
,决定是否billboard
始终面向相机。可设为true
或x
、y
、z
,其中y
代表限定沿着y
轴转动fixSizeOnScreen
:默认值为false
,是否保持屏幕固定大小,不随着场景缩放而变化。其他格式为:-1 表示使用图标或者图片自身的大小,[100, 20]
则表示固定宽100,高20texture.cache
:默认值为false
,决定是否缓存,对于json
图标请尽量开启缓存来加速显示,对应的代价就是更新需要通过g3d.invalidateCachedTexture(node)
来显式更新texture.scale
:默认值为1
, 矢量贴图在 3D 中的大小比例,例如设置该值为2
的时候,矢量申明是 64 x 64,则生成的 3D 贴图是 128 x 128vector.dynamic
:默认值为false
,决定当前image
为json
图标时,是否利用当前节点的宽高来生成对应大小的清晰的矢量来渲染,注意需要在autorotate
为true
的时候开启注意,从性能上考量,一般情况的建议是,texture.cache
设置为true
开启缓存,vector.dynamic
设置为false
关闭贴图大小动态变化。如果想要控制公告板的显示层级,可以通过setRenderLayer方法调整。
当shape3d
样式为billboard
或者plane
时,可以通过以下属性设置Node
是否成为一面镜子:
shape3d.reflector
:模型为billboard
/plane
时,是否开启作为镜面反射,默认值为false
shape3d.reflector.color
:镜面反射的混合色,默认值为rgb(128,128,128)
shape3d.reflector.background
:背景色,默认值为null
shape3d.reflector.clip
:镜面之上需要clip
,判定单位是深度,裁切需要bias
偏差以表现更好,默认值0.003
向上稍突出以去除缝隙注意,镜面反射的功能不要在场景中大量使用,避免影响场景的整体展示性能。
HT
可以通过加载对应的typeface
字体,并指定node
的shape3d
类型为text
,来呈现3D
文字。
呈现3D
字体首先需要一个json
格式的typeface
字体,具体可使用网站facetype.js来生成,下载生成完毕的字体(json格式),并通过ht.Default.loadFontFace
来加载字体到内存中。
ht.Default.loadFontFace(url, callback)
url
为json
格式的typeface
字体的地址callback
为可选参数,如果不带callback
则为同步加载,带callback
则异步加载字体,参数为加载成功的字体名文字具体的控制参数包含有:
shape3d.text
:需要显示的文本,该属性被设置则文本最优先使用其。为空时优先使用node
的name
,再次使用node
的label
shape3d.text.amount
:默认值为0.5
,决定文字相对厚度shape3d.text.size
:默认值为1
,决定文字的放大系数,当然也可以通过(也建议通过)node
自身缩放来达成shape3d.text.fill
:默认值为true
,决定图形是否实心shape3d.text.curveSegments
:默认值为4
,决定图形的曲线采样频率,越大越精细(注意性能的平衡)shape3d.text.spacing
:默认值为1
,决定字之间的间隔大小shape3d.text.font
:字体名,注意是json
字体文件中的familyName
。为空则使用已加载字库中的第一个shape3d.text.style
:默认值为normal
,表明字体是normal
(标准)、italic
(斜体)、oblique
(倾斜)shape3d.text.weight
:默认值为normal
,表明字体是normal
(标准)、bold
(加粗)ht.Edge
在GraphView
的拓扑组件中作为连接节点的连线是重要的图元类型,同样在Graph3dView
组件中依然具备2D
连线的展示功能,
并且实现空间的三维连线效果,同时也增加了些针对3D
的连线参数,连线在三维空间呈现默认是非立体方式,
通过设置style
为cylinder
可呈现为管状的立体线效果,构建连线的常用参数说明如下:
edge.color
:连线颜色edge.width
:连线宽度edge.gradient.color
:连线渐进色,目前仅在3D
上连线的非立体方式下支持,会在连线的target
端呈现此渐进色edge.source.t3
:连线source
端偏移,[tx, ty, tz]
格式,默认为空edge.target.t3
:连线target
端偏移,[tx, ty, tz]
格式,默认为空当edge.type
为points
类型时,设置到edge.points
的拐点参数兼容2D
的{x: 100, y: 100}
的JSON
格式,
同时3D
上引入新的参数e
代表elevation
的海拔高度,因此3D
支持{x: 10, y: 20, e: 30}
的拐点参数格式,
此拐点代表在x
轴10
,y
轴30
,z
轴20
的位置点。
当style
为cylinder
时连线呈现立体管线效果,这时候控制连线显示效果的参数都在shape3d.*
上,
同时增加了repeat.uv.length
参数,该参数默认为空,如果设置了长度值,则贴图会根据连线长度自动调节连线方向上的贴图倍数。
参见形状手册的空间管线章节
参见形状手册
ht.Points
继承于ht.Node
,在Graph3dView
中,代表点云,将一大堆需要重复展示的内容聚合起来,一次性绘制,提高页面的绘制性能,针对点云节点,提供了以下接口,控制其展示效果:
setPoints(points)
设置点云节点的点位信息,参数类型为 Array
,格式为:[ x1, y1, z1, x2, y2, z2, ... xn, yn, zn ]
setPoint(index, point)
更新某个具体位置的点位信息,index
为要更新的点位下标,point
为要更新的点位信息,格式为:[ x, y, z ]
setPointsColor(colors)
设置点云节点中,点位对应的颜色信息,参数类型为 Array
setPointColor(index, color)
更新某个具体位置的点位颜色信息,index
为要更新的点位下标,color
为要更新点位的颜色值setPointsSize(sizes)
设置点云节点中,点位对应的大小信息,参数类型为 Array
setPointSize(index, size)
更新某个具体位置的点位大小信息,index
为要更新的点位下标,size
为要更新点位的大小值同时提供的相对应的样式可以全局控制点云中每个点位的大小、贴图、颜色等信息,具体样式属性如下:
points.image
点云节点上,展示的贴图,包括,rect
/ circle
/ 图片 / 矢量,该样式与 points.color
互斥,并且优先级高于 points.color
样式points.color
点云节点上,展示的颜色值,只有当未指定 points.image
样式时才生效points.size
点云节点展示的大小,这边要求点云设置的贴图大小,必须是正方形比例的贴图,如果贴图是非正方形,会被拉伸变形points.transparent
点云节点是否透明points.opacity
点云节点的透明度,取值范围 0 ~ 1alphaTest
:默认值为0.4
,当图形是不透明时(即没有设置 transparent 属性),贴图alpha
透明度低于这个值则直接不显示brightness
:默认值为undefined
,整体图形在3D
下的亮度,大于1
代表更亮,小于1
代表更暗,1
则代表不变化opacity
:默认值为undefined
,整体图形在3D
下的透明度,值范围0~1
transparent.mask
:默认值为false
,该属性能使得图元不绘制显示在界面上,但依然可以点击选中texture.cache
:默认值为false
,贴图是2D
矢量时,决定是否缓存,对于json
图标请尽量开启缓存来加速显示,对应的代价就是更新需要通过g3d.invalidateCachedTexture(node)
来显式更新2D
的label.*
文字属性对于3D
依然适用,3D
也支持内置的第二个label2.*
文字,同时增加了以下针对3D
空间摆放以及呈现特性的属性参数:
label.face
: 默认值为front
,文字在3D
下的朝向,可取值left|right|top|bottom|front|back|center
label.t3
: 默认值为undefined
,文字在3D
下的偏移,格式为[x,y,z]
label.r3
: 默认值为undefined
,文字在3D
下的旋转,格式为[rotationX,rotationY,rotationZ]
label.rotationMode
:默认值为xzy
,文字在3D
下的沿三个轴旋转先后顺序,可取值xyz|xzy|yxz|yzx|zxy|zyx
label.light
: 默认值为false
,文字在3D
下是否受光线影响label.blend
: 默认值为undefined
,文字在3D
下染色颜色label.opacity
: 默认值为undefined
,文字在3D
下的透明度,值范围0~1
label.reverse.flip
: 默认值为false
,文字在3D
下反面是否显示正面的内容label.reverse.color
: 默认值为#868686
,文字在3D
下反面的颜色label.reverse.cull
: 默认值为false
,文字在3D
下反面是否显示,隐藏背面可提高性能label.transparent
: 默认值为false
,文字在3D
下是否透明label.autorotate
: 默认值为false
,文字在3D
下是否自动朝向眼睛的方向,可设为true
或x
、y
、z
,其中y
代表限定沿着y
轴转动label.texture.scale
:默认值为2
,该值代表内存实际生成贴图的倍数,不宜设置过大否则影响性能,
参见位置手册例子2D
的note.*
标注属性对于3D
依然适用,3D
也支持内置的第二个note.*
标注,同时增加了以下针对3D
空间摆放以及呈现特性的属性参数:
note.face
:默认值为front
,标注在3D
下的朝向,可取值left|right|top|bottom|front|back|center
note.t3
:默认值为undefined
,标注在3D
下的偏移,格式为[x,y,z]
note.r3
:默认值为undefined
,标注在3D
下的旋转,格式为[rotationX,rotationY,rotationZ]
note.rotationMode
:默认值为xzy
,标注在3D
下的沿三个轴旋转先后顺序,可取值xyz|xzy|yxz|yzx|zxy|zyx
note.light
:默认值为false
,标注在3D
下是否受光线影响note.blend
:默认值为undefined
,标注在3D
下染色颜色note.opacity
:默认值为undefined
,标注在3D
下的透明度,值范围0~1
note.reverse.flip
:默认值为false
,标注在3D
下反面是否显示正面的内容note.reverse.color
:默认值为#868686
,标注在3D
下反面的颜色note.reverse.cull
:默认值为false
,标注在3D
下反面是否显示,隐藏背面可提高性能note.transparent
:默认值为false
,标注在3D
下是否透明note.autorotate
:默认值为false
,标注在3D
下是否自动朝向眼睛的方向,可设为true
或x
、y
、z
,其中y
代表限定沿着y
轴转动note.texture.scale
:默认值为2
,该值代表内存实际生成贴图的倍数,不宜设置过大否则影响性能,
参见位置手册例子icons
是HT
图元扩展上的一个非常有用的属性,利用其可以为图元增加任意多得图标附属部件。
icons
内容为style
上的icons
属性json对象,该对象的结构示例代码如下:
data.setStyle('icons', {
whateverName1: {
position: 17,
direction: 'north', // east, west, south, north
gap: 1,
names: ['icon1', 'icon2', 'icon3']
},
whateverName2: {
position: 20,
width: 16,
height: 16,
names: ['icon5']
},
whateverName3: ...
]);
icons
可分为很多组,其中whateverName*
可理解为组的名称,这个名称HT
没有显示也不用于界面呈现效果,用户可以根据自己需要进行命名管理。
直接设置icons对象会冲掉已经设置的图标的副作用,为此HT
提供了Data#addStyleIcon(name, json)
和Data#removeStyleIcon(name)
的函数,
便于控制管理图标增删,因此以上代码也可通过下面代码实现:
data.addStyleIcon('whateverName1', {
position: 17,
direction: 'north', // east, west, south, north
gap: 1,
names: ['icon1', 'icon2', 'icon3']
});
data.addStyleIcon('whateverName2', {
position: 20,
width: 16,
height: 16,
name: ['icon5']
});
从以上示例代码可发现每组图标可为单个图标如whateverName2
定义了icon5
图标,也可为多个图标的排列,
如whateverName1
的['icon1', 'icon2', 'icon3']
。而json
的其他参数为如何摆放和显示这些图标相关:
names
: 包含多个字符串的数组,每个字符串对应一张图片或矢量(通过ht.Default.setImage
注册)visible
:表示该组图片是否显示for3d
:代表该组图片仅用于Graph3dView
的组件显示,不显示于GraphView
组件direction
: 值为west
、east
、north
、south
之一,指定icons
的排列方向,默认值为east
keepOrien
: 旋转Edge
时,icons
会自动调整方向以保持最好的阅读效果(比如文字),此属性为true
表示禁止自动调整方向gap
: 指定同一组中得多个图标之间的距离width
: 指定每个icon
的宽度,默认根据注册图片时的宽度height
: 指定每个icon
的高度,默认根据注册图片时的高度face
:默认值为front
,图标在3D
下的朝向,可取值left|right|top|bottom|front|back|center
t3
:默认值为undefined
,图标在3D
下的偏移,格式为[x,y,z]
r3
:默认值为undefined
,图标在3D
下的旋转,格式为[rotationX,rotationY,rotationZ]
rotationMode
:默认值为xzy
,图标在3D
下的沿三个轴旋转先后顺序,可取值xyz|xzy|yxz|yzx|zxy|zyx
light
:如果shape3d
为空,则默认值为false
,否则默认为true
,图标在3D
下是否受光线影响blend
:默认值为undefined
,图标在3D
下染色颜色,opacity
:默认值为undefined
,图标在3D
下的透明度,值范围0~1
reverseFlip
:默认值为false
,图标在3D
下反面是否显示正面的内容reverseColor
:默认值为#868686
,图标在3D
下反面的颜色reverseCull
:默认值为false
,图标在3D
下反面是否显示,隐藏背面可提高性能transparent
:默认值为false
,图标在3D
下是否透明autorotate
:默认值为false
,图标在3D
下是否自动朝向眼睛的方向discardSelectable
:默认值为true
,代表贴图透明度低到被剔除的部分也能点击选中,可设置为false
则被剔除部分不可选中textureScale
:默认值为2
,该值代表内存实际生成贴图的倍数,不宜设置过大否则影响性能,
参见位置手册例子shape3d
:该属性指定显示为3d
模型的图标效果,如果设置了该属性则忽略names
、width
和height
属性,
参见位置手册例子position
: 指定icons
的位置,支持的枚举值对应位置如下:
34 35
1 | 2 38 3 39 4 | 5
----6-------40-----7-----41-------8----
9 | 10 42 11 43 12 | 13
| |
| 44 |
14 15 16 45 46 17 47 48 18 19 20
| 49 |
| |
21 | 22 50 23 51 24 | 25
----26------52-----27-----53------28---
29 | 30 54 31 55 32 | 33
36 37
吸附功能对于设计有层次关系的模型非常方便,例如设备面板吸附上设备机框,设备端口吸附上设备面板,这样从机框-面板-端口的层次关系吸附,
使得用户拖动整体机框时所有这个层次下的图元都会跟随移动。对于3D
的场景下,吸附的概念更进一步延伸,当机框在三维空间进行任意位置偏移
以及任意角度旋转时,所有吸附的相关图元都会正确的跟随平移,并做出相应位置对应的旋转,以达到整体设备各个图形部分保持物理相对位置一致。
Node#getHost()
和Node#setHost(node)
获取和设置吸附的图元对象Node#getAttaches()
返回目前吸附到该图元的所有对象,返回ht.List
链表对象,无吸附对象时返回空Node#isHostOn(node)
判断该图元是否吸附到指定图元对象上Node#isLoopedHostOn(node)
判断该图元是否与指定图元相互形成环状吸附,例如A
吸附B
,B
吸附C
,C
又吸附回A
,则A
,B
和C
图元相互环状吸附HT
显示3D
视图的组件为ht.graph3d.Graph3dView
,其中ht.graph3d
为和3D
组件相关的类包,Graph3dView
为呈现3D
视图的组件类。
可类比于2D
视图组件ht.graph.GraphView
,GraphView
和Graph3dView
两者可共享同一数据模型DataModel
,
在2D
和3D
的API设计上HT
保持了很多一致性。
Graph3dView
的界面DOM
结构是由最底层的DIV
元素,以及渲染层CANVAS
元素组合而成,通过getView()
可得到最底层的DIV
元素,
通过getCanvas()
可得到渲染层CANVAS
元素,HT
默认的交互事件都是添加在底层DIV
元素上,
用户做自定义交互扩展也可通过直接对getView()
返回的元素添加事件监听的方式。
颜色参数在HTML
领域是比较灵活,可为#F0F1F2
的十六进制格式,可为字符串名red
和black
等,可为rgb(255,128,32)
格式,
可为rgba(255,128,32,0.5)
包含透明度的格式。然而WebGL
的API接口对于颜色参数的格式,一般要求rgba四个参数的取值范围为0~1
的数字格式,
因此Graph3dView
组件上的颜色参数默认值为[r,g,b,a]数字数组格式,而考虑到DataModel
上的Data
数据与2D
兼容性,
HT
内部会自动对颜色参数进行转换,因此data.s('all.color','red')
与data.s('all.color',[1,0,0,1])
的方式都是一样的效果。
灯光和雾化等效果请参见灯光手册
为了提供三维空间的坐标参考,Graph3dView
预置了现实xz
面网格,x
、y
和z
三个方向轴,以及中心点位置的显示功能,
默认这些参数都是关闭不显示状态,可根据需要打开开关,并改变显示参数。
getGridSize()|setGridSize(40)
,指定网格行列数getGridGap()|setGridGap(20)
,指定网格线间距getGridColor()|setGridColor([0.4, 0.75, 0.85, 1.0])
,指定网格线颜色isGridVisible()|setGridVisible(true)
,指定是否显示网格isOriginAxisVisible()|setOriginAxisVisible(true)
,指定是否显示坐标原点[0,0,0]
轴线isCenterAxisVisible()|setCenterAxisVisible(true)
,指定是否显示目前中心点轴线getAxisXColor()|setAxisXColor([1.0, 0.0, 0.0, 1.0])
,指定x
轴线颜色getAxisYColor()|setAxisYColor([0.0, 1.0, 0.0, 1.0])
,指定y
轴线颜色getAxisZColor()|setAxisZColor([0.0, 0.0, 1.0, 1.0])
,指定z
轴线颜色3D
的交互与2D
有很大的区别,默认Graph3dView
提供的是围绕Graph3dView#getCenter()
中心点旋转的操作模式,
这种模式下进行Drag
操作时会改变Graph3dView#getEye()
的眼睛观察点位置,鼠标滚轮或触屏pinch
缩放的效果,
实质也是改变eye
位置,使其更接近或者更远离center
中心位置,最终达到视觉缩放或者走近和远离物体的效果。
drag
围绕中心旋转;按下shift
键则进行pan
方式的手抓图;滚轮进行走近和远离中心;
右键drag
时上下位置变化影响前进后退,左右位置变化影响左右平移。pinch
方式的缩放;三指头拖拽进行pan
方式平移。可以通过设置graph3dView.setRotateMaxPhi(Math.PI * 5 / 12)
来限制交互时的最大仰角,g3d.setRotateMinPhi(Math.PI * 5 / 12)
限制最小仰角,默认值Math.PI
是正上方仰视,Math.PI / 2
是平视,0
是正下方俯视:
// 设置最大仰角为 5/12 PI,即限制相机在水平面上方 15° 方向
graph3dView.setRotateMaxPhi(Math.PI * 5 / 12);
另外,还可以修改默认交互为地图场景模式,对应的交互器是MapInteractor
,该交互模式下,具体行为如下:
drag
上下移动场景翻转;左键drag
左右移动围绕中心旋转;滚轮进行走近和远离中心;
右键pan
抓图,同默认模式不一样的是抓图时不改变相机视角(上下抓图时相机的仰角);按住shift
进行右键pan
的时候同默认模式,此时相机视角可能发生变化;pan
抓图,抓图时不改变相机视角;双指绕着中心旋转则rotate
场景;双指拿捏pinch
方式的缩放;双指同上同下进行视角翻转;三指跟单指一样做pan
行为,不同的是抓图时改变相机视角;panButton
,默认right
,表示用哪个键来做pan
手抓图,改成left
则切换为左键抓图keepHorizon
,默认true
,抓图过程是否保持相机视角不变(注意,按shift
会临时切换这个值为反)minPhi
,默认0
,相机最小仰角,默认0
表示正上方maxPhi
,默认5/12 Pi
,相机最大仰角需要改成地图场景模式的话,以下代码片段供参考:
var mapInteractor = new ht.graph3d.MapInteractor(g3d);
g3d.setInteractors([ mapInteractor ]);
// 修改最大仰角为 2/5 PI,可选项
// mapInteractor.maxPhi = Math.PI * 2 / 5;
// 切换左右键习惯,用左键进行 pan 手抓图
// mapInteractor.panButton = 'left';
Graph3dView
还提供了第一人称的漫游交互模型,该模式同时改变eye
和center
的位置,
通过Graph3dView#setFirstPersonMode(true)
可切换为第一人称模式,这种模式下操作就行人或车在行进的效果:
shift
键则进行pan
方式的手抓图,即改变上下左右位置。滚轮则进行上下位置调节。drag
拖拽则进行pan
方式的手抓图,即改变上下左右位置。在第一人称模式下,还可设置Graph3dView#setMouseRoamable(true|false)
参数,该参数默认值为true
,如果设置为false
,
则鼠标左键右键都不支持前进后退的操作功能,但左键可拖拽编辑图元,右键可改变视角方向,采用这样的方式一般会结合键盘w|s|a|d
按键进行漫游操作。
HT
的交互函数一般都有是否起动画的参数anim
,该参数可为boolean
类型的简单true|false
,也可为json
对象,
当为json
对象时则代表启动动画,同时json
对象上的属性则用于控制动画相关的参数,以下示例代码片段供参考:
g3d.walk(distance, {
frames: 50,
interval: 30,
easing: function(t) {return t; },
finishFunc: function() {
forwardIndex += 1;
if (points.length - 2 > forwardIndex) {
g3d.setCenter([point2.x, 1600, point2.y]);
setTimeout(function() {
g3d.rotate(Math.PI / 2, 0, {
frames: 30,
interval: 30,
easing: function(t) {return t;},
finishFunc:function() {forward();}
});
}, 60);
} else {
var lastPoint = points[points.length - 1];
g3d.setCenter([lastPoint.x, 1400, lastPoint.y]);
setTimeout(function() {
g3d.rotate(-Math.PI / 2, 0, {
frames: 30,
interval: 30,
finishFunc: function() {
window.isAnimationRunning = false;
}
});
}, 60);
}
}
});
虽然3D
交互本质主要就是改变eye
和center
这两个位置参数,但直接操作三维坐标点还是太原始晦涩,
Graph3dView
提供了以下跟简单直观的函数操作方式:
setZoom(increment, anim)
:缩放操作,默认操作模式意味着eye
离center
的远近变化,increment
为步进的比例,
调用zoomIn(anim)
和zoomOut(anim)
,等同于调用了setZoom(1.3, anim)
和setZoom(1/1.3, anim)
。
如果在Graph3dView#isOrtho()
为true
的正交投影情况下,缩放意味着改变Graph3dView#setOrthoWidth(width)
的可视宽度范围。
pan(dx, dy, anim, firstPersonMode)
:上下左右四个方向的平移,本质为eye
和center
同时做四个方向的相同偏移量,
dx
左右偏移参数,dy
上下偏移参数,dx
和dy
一般代表屏幕移动像素,Graph3dView
自动会换算成合理的3D
空间逻辑坐标偏移量。
firstPersonMode
参数为空时则默认采用Graph3dView#isFirstPersonMode()
当前值,
如果为第一人称模式调用pan
操作,该函数会考虑Graph3dView#getBoundaries()
边界限制。
rotate(leftRight, upDown, anim, firstPersonMode)
:上下左右四个方位旋转一定角度,leftRight
水平旋转弧度,upDown
垂直旋转弧度,
firstPersonMode
参数为空时则默认采用Graph3dView#isFirstPersonMode()
当前值,该参数将影响旋转移动的参照标准,为默认非第一人称模式时,
旋转是以center
为中心进行旋转,也就是围绕中心物体旋转,当为第一人称时旋转以eye
为中心进行旋转,也就是旋转眼睛朝向方向。
walk(step, anim, firstPersonMode)
:该函数同时改变eye
和center
的位置,也就是eye
和center
在两点建立的矢量方向上同时移动相同的偏移量。
step
为偏移的矢量长度值。firstPersonMode
参数为空时则默认采用Graph3dView#isFirstPersonMode()
当前值,
如果为第一人称模式调用walk
操作,该函数会考虑Graph3dView#getBoundaries()
边界限制。
reset()
:复位函数,调用该函数将eye
、center
和up
三个变量设置为ht.Default
上对应的
graph3dViewCenter
、graph3dViewEye
和graph3dViewUp
初始默认值。
默认情况下以下参数都是开启状态,即可通过鼠标或键盘进行以下交互操作,可根据需求进行开关设置:
isRotatable()|setRotatable(true)
,控制是否可旋转isZoomable()|setZoomable(true)
,控制是否可缩放isPannable()|setPannable(true)
,控制是否可平移isWalkable()|setWalkable(true)
,控制是否可进退isResettable()|setResettable(true)
,控制是否可按空格键复位isRectSelectable()|setRectSelectable(true)
,控制是否可框选Graph3dView
预置了很多键盘操作功能
w
:前进,如果同时按下shift
键则为上移s
:后退,如果同时按下shift
键则为下移a
:左移d
:右移ctrl
或command
键:进行框选space
空格键:调用reset()
进行复位shift
键:按住shift
键盘时,默认操作变成pan
的平移效果Graph3dView
默认情况下移动图元是沿着xz
平面移动,当按住以下键时将改变移动模式:
shift
键,或者同时按下x
、y
和z
键时,则进行xyz
三维空间的移动x
和y
键时,则进行沿xy
平面的移动x
和z
键时,则进行沿xz
平面的移动y
和z
键时,则进行沿yz
平面的移动x
键时,则进行沿x
轴方向的移动y
键时,则进行沿y
轴方向的移动z
键时,则进行沿z
轴方向的移动通过键盘改变移动模式的默认实现逻辑在getMoveMode(event, data)
函数里,该函数默认实现逻辑如下,
如果最后选中的图元的style
属性3d.move.mode
指定了值,则不再考虑键盘状态而采用该设置值:
getMoveMode: function(event, data){
var movemode = data.s('3d.move.mode');
if(movemode){
return movemode;
}
var map = ht.Default.getCurrentKeyCodeMap(),
x = '88',
y = '89',
z = '90';
if(event.shiftKey || (map[x] && map[y] && map[z])) return 'xyz';
if(map[x] && map[y]) return 'xy';
if(map[x] && map[z]) return 'xz';
if(map[y] && map[z]) return 'yz';
if(map[x]) return 'x';
if(map[y]) return 'y';
if(map[z]) return 'z';
return 'xz';
},
可参考吸附章节例子中,将移动模式设置为沿xyz
三维空间移动的代码:
g3d.getMoveMode = function(event){
return 'xyz';
};
默认情况下图元在三维场景即可拖拽沿着xz
平面移动,或结合键盘实现任意空间方向移动,但结合键盘毕竟不够直观易用,
同时图元还有三个轴方向的旋转角度,三个轴方向的大小尺寸等参数需要可控,即需要修改p3
、s3
和r3
参数的编辑功能。
为此HT
提供了直观的解决方案,当Graph3dView#setEditable(true)
处于编辑状态时,最后一个选中的图元将呈现如下的,
由图元中心延伸出来的三个轴方向的标示条,每个轴方向的标示条又分为三段:
shift
键可同时同比例改变三个轴方向大小0
参见过滤器章节,控制图元是否允许移动、旋转和改变大小。
通过Graph3dView#addInteractorListener
可监听交互过程:
g3d.addInteractorListener(function(e){
console.log(e.kind);
});
其中回调事件e.kind
参数类型如下:
beginRotate
:开始旋转betweenRotate
:旋转过程endRotate
:结束旋转beginWalk
:开始行进betweenWalk
:行进过程endWalk
:结束行进beginZoom
:开始缩放betweenZoom
:缩放过程endZoom
:结束缩放beginPan
:开始平移betweenPan
:平移过程endPan
:结束平移beginPinch
:开始双指缩放betweenPinch
:双指缩放过程endPinch
:结束双指缩放toggleNote
:双击在note
上toggleNote2
:双击在note2
上clickData
:单击图元clickBackground
:单击背景doubleClickData
:双击图元doubleClickBackground
:双击背景beginEditRotation
: 开始编辑图元旋转角度betweenEditRotation
: 正在编辑图元旋转角度endEditRotation
: 结束编辑图元旋转角度beginEditSize
: 开始编辑图元大小betweenEditSize
: 正在编辑图元大小endEditSize
: 结束编辑图元大小beginMove
: 开始移动图元betweenMove
: 正在移动图元endMove
: 结束移动图元beginRectSelect
: 开始框选图元betweenRectSelect
: 正在框选图元endRectSelect
: 结束框选图元当单击或双击在图元上时,返回事件除了e.kind
外,还有e.part
参数提供了具体点击图元哪个部位的信息:
body
:图片的中心部分label
:图元文字标签label2
:图元第二个文字标签note
:图元冒泡标注label2
:图元第二个冒泡标注icons
上的key
:代表一组图标edit_tx
:编辑状态下,标示改变x
轴位置部分edit_ty
:编辑状态下,标示改变y
轴位置部分edit_tz
:编辑状态下,标示改变z
轴位置部分edit_rx
:编辑状态下,标示改变x
轴旋转部分edit_ry
:编辑状态下,标示改变y
轴旋转部分edit_rz
:编辑状态下,标示改变z
轴旋转部分edit_sx
:编辑状态下,标示改变x
轴大小部分edit_sy
:编辑状态下,标示改变y
轴大小部分edit_sz
:编辑状态下,标示改变z
轴大小部分HT
不但提供第一人称漫游交互模式,还支持漫游过程对墙面等阻挡物的碰撞检测功能。
通过碰撞检测可以限制第一人称漫游的允许范围。漫游操作一般沿着xz
平面进行,因此HT
提供了定义xz
平面上的多线,
用来描述不可超越的漫游边界。
通过Graph3dView#setBoundaries(boundaries)
可指定碰撞边界,boundaries
的格式如下:
g3d.setBoundaries([
[
p0.x, p0.y,
p1.x, p1.y,
p2.x, p2.y,
p3.x, p3.y
],
[
p4.x, p4.y,
p5.x, p5.y,
p6.x, p6.y
]
]);
以上代码设置了两条折线p0-p1-p2-p3
和p4-p5-p6
,每条折线由一个数组描述所有端点,数组的第一和第二元素表示起始点的x,z
坐标,
接下来依次是第二、第三等端点的x,z
坐标,可理解为第一个端点为MoveTo
其他图元依次进行LineTo
围成的边界。
以下示例代码用到了ht.Default.toBoundaries(data.getPoints(), data.getSegments())
的函数,
该函数可将不连续的曲线转化成微分的直线线段。代码利用GraphView#addTopPainter
,
将3D
的eye
和center
的位置方向信息实时绘制在2D
,以便直观理解当前第一人称所在位置和朝向。
Graph3dView
中被选中的图元会显示为较暗的状态,变暗系数是由图元style
的brightness
和select.brightness
属性决定,
select.brightness
属性默认值为0.7
,最终返回值大于1
变亮,小于1
变暗,等于1
或为空则不变化。
Graph3dView#getBrightness
函数控制最终图元亮度,因此也可以通过重载覆盖该函数自定义选中图元亮度,以下为默认逻辑:
getBrightness: function(data){
var brightness = data.s('brightness'),
selectBrightness = this.isSelected(data) ? data.s('select.brightness') : null;
if(brightness == null){
return selectBrightness;
}
if(selectBrightness == null){
return brightness;
}
return brightness * selectBrightness;
},
Graph3dView#getWireframe
函数用于定义图元立体线框效果,默认实现代码如下,
由实现代码可知通过控制wf.*
(wf
为wireframe
的简称)相关参数即可实现显示选中线框的效果。
getWireframe: function(data){
var visible = data.s('wf.visible');
if(visible === true || (visible === 'selected' && this.isSelected(data))){
return {
color: data.s('wf.color'),
width: data.s('wf.width'),
short: data.s('wf.short'),
mat: data.s('wf.mat')
};
}
},
wf.visible
:默认为false
代表不显示,可设置为selected
值代表选中时才显示,或true
值代表一直显示线框wf.geometry
:默认为false
代表是否显示物体几何体的线条wf.color
:线框颜色wf.short
:默认值为false
代表显示封闭的立体线框,设置为true
则显示不封闭的短线框wf.width
:线框宽度,默认值为1
,有些系统下只能显示1
的效果,不同系统能显示的最大值也都有限制wf.mat
:默认值为空,可通过ht.Default.createMatrix
构建转换矩阵,参见 Unboxing 例子默认情况所有图元都是可选中,用户可通过设置选择过滤器取消部分图元的可选中功能,
可否选中的最终控制在SelectionModel
模型的filterFunc
过滤器上,也可通过重载GraphView
的isSelectable
函数,
或调用GraphView.setSelectableFunc(func)
的封装函数控制,示例代码如下:
graph3dView.setSelectableFunc(function(data){
return data.a('selectable');
});
默认情况图元都是可见,用户可通过设置可见过滤器隐藏部分图元,示例代码如下:
graph3dView.setVisibleFunc(function(data){
return data.s('all.transparent') === true;
});
该示例代码逻辑为:只显示all.transparent
为true
的图元。
Graph3dView#isVisible
函数最终决定图元是否可见,因此也可通过直接重载覆盖该函数自定义:
graph3dView.isVisible = function(data){
return data.s('all.transparent') === true;
};
默认情况图元都是可移动,用户可通过设置移动过滤器固定部分图元,示例代码如下:
graph3dView.setMovableFunc(function(data){
return movableItem.selected;
});
该示例代码逻辑为:当movableItem
的selected
为true
时图元才允许移动。
Graph3dView#isMovable
函数最终决定图元可否移动,因此也可通过直接重载覆盖该函数自定义:
graph3dView.isMovable = function(data){
return movableItem.selected;
};
当Graph3dView#setEditable(true)
设置为可编辑的情况下,默认选中图元允许旋转,可通过如下代码禁止部分图元旋转:
graph3dView.setRotationEditableFunc(function(data){
return data instanceof ht.Shape;
});
以上代码的逻辑为:只允许ht.Shape
类型的图元可以旋转。
Graph3dView#isRotationEditable
函数最终决定图元可否旋转,因此也可通过直接重载覆盖该函数自定义:
graph3dView.isRotationEditable: function(data){
return data instanceof ht.Shape;
},
当Graph3dView#setEditable(true)
设置为可编辑的情况下,默认选中图元允许改变大小,可通过如下代码禁止部分图元旋转:
graph3dView.setSizeEditableFunc(function(data){
return data instanceof ht.Shape;
});
以上代码的逻辑为:只允许ht.Shape
类型的图元可以改变大小。
Graph3dView#isSizeEditable
函数最终决定图元可否改变大小,因此也可通过直接重载覆盖该函数自定义:
graph3dView.isSizeEditable: function(data){
return data instanceof ht.Shape;
},
除在视图组件上设置过滤器外,GraphView
和Graph3dView
的内置过滤机制也参考了以下style
属性,用户可直接改变以下style
达到对单个图元的控制效果:
2d.visible
:默认值为true
,控制图元在GraphView
上是否可见2d.selectable
:默认值为true
,控制图元在GraphView
上是否可选中2d.movable
:默认值为true
,控制图元在GraphView
上是否可移动2d.editable
:默认值为true
,控制图元在GraphView
上是否可编辑2d.move.mode
:默认值为空,控制图元移动范围,可设置为如下参数:xy
:可在xy
平面移动x
:仅沿x
轴移动y
:仅沿y
轴移动3d.visible
:默认值为true
,控制图元在Graph3dView
上是否可见3d.selectable
:默认值为true
,控制图元在Graph3dView
上是否可选中3d.movable
:默认值为true
,控制图元在Graph3dView
上是否可移动3d.editable
:默认值为true
,控制图元在Graph3dView
上是否可编辑3d.move.mode
:默认值为空,参见键盘操作,控制图元移动范围,可设置为如下参数:xyz
:可在三维空间移动xy
:仅在xy
平面移动xz
:仅在xz
平面移动yz
:仅在yz
平面移动x
:仅沿x
轴移动y
:仅沿y
轴移动z
:仅沿z
轴移动showDebugTip
:显示当前场景的 Draw Calls、顶点数、面数、线数hideDebugTip
:关闭调试信息的显示moveCamera
:移动当前相机,参数(eye, center, animation)
,其中eye
:新的相机位置,形如[100,100,50]
,如果为null
则使用当前相机的位置center
:新的目标中心点位置(相机看向的位置),形如[0,0,0]
,如果为null
则使用当前中心点位置animation
:默认false
,是否启用动画,可以设置为true
或者false
或者animation
动画对象flyTo
:相机看向具体的节点或者节点列表,参数(target, options)
,其中target
:一个节点node
或者节点列表(Array
)或者空(场景内的所有节点)options
:可选属性,格式为对象({}
),属性包括有:animation
:默认false
,是否启用动画,可以设置为true
或者false
或者animation
动画对象center
:默认undefined
,新的场景center
点,形如 [0,0,0]
(空的话,target为一个则看向node
中心,target为列表则看向根据节点列表计算出来的中心)direction
:默认undefined
,眼睛处于目标的方向(相对目标
,受到
目标自身旋转影响),例如[0,1,5]
在目标正面的斜向上(如果target
是列表则direction
采用的是worldDirection
)worldDirection
:默认undefined
,眼睛处于目标的方向(相对场景
,不受
目标旋转影响),例如[0,1,5]
在目标所在位置的斜向上distance
:默认undefined
(未定义的话则使用下面的ratio
模式计算距离),浮点类型,表示眼睛跟中心的固定距离ratio
:默认0.8
,浮点类型,表示眼睛跟中心的距离动态计算(例如 0.8 表示眼睛在上述方向上动态计算距离以将目标包围盒的8个角全部适配到屏幕80%范围内)注意,direction
跟worldDirection
如果都不配置,则使用之前相机的角度保持不变化。
3D
中可通过以下方法控制高亮效果,可以通过node
上的style
属性highlight.mode
单独控制高亮的模式。
setHighlightMode
: 设置当前高亮的模式,包括:disabled
关闭高亮,selected
选中高亮,hover
悬浮高亮,style
风格设置高亮getHighlightMode
: 获取当前高亮的模式,默认为style
setHighlightColor
: 设置当前高亮的颜色getHighlightColor
: 获取当前高亮的颜色,默认为rgba(190, 210, 250, 1)
setHighlightWidth
: 设置当前高亮的线宽getHighlightWidth
: 获取当前高亮的线宽,默认为0.8
3D
中可通过一下方法控制阴影效果:
enableShadow(shadow)
:开启阴影功能,可传入阴影的参数对象,也可以不传,可设置的属性有:quality
:质量intensity
:强度bias
:Bias
偏移radius
:柔化半径type
:柔化类型degreeX
:X
轴方向上的角度degreeZ
:Z
轴方向上的角度disableShadow()
:关闭阴影功能getShadowDegreeX()
:获取阴影在X
轴方向上的角度,默认值30
setShadowDegreeX(value)
:设置阴影在X
轴方向上的角度getShadowDegreeZ()
:获取阴影在Z
轴方向上的角度,默认值-10
setShadowDegreeZ(value)
:设置阴影在Z
轴方向上的角度getShadowIntensity()
:获取阴影强度值,默认值0.3
setShadowIntensity(value)
:设置阴影强度值getShadowQuality()
:获取生成阴影的质量,包括:low
低,medium
中,high
高,ultra
极高,默认值high
setShadowQuality(value)
:设置生成阴影的质量getShadowType()
:获取阴影柔化类型,包括:none
无,hard
硬,soft
软,默认值hard
setShadowType(value)
:设置阴影柔化类型getShadowRadius()
:获取阴影柔化半径,默认值0.1
setShadowRadius(value)
:设置阴影柔化半径getShadowBias()
:获取阴影Bias
偏移,默认值-0.005
setShadowBias(value)
:设置阴影Bias
偏移对于ht.Node
,可以通过设置Style
样式来控制阴影的产生和是否接收阴影
shadow.cast
:是否产生阴影shadow.receive
:是否接收阴影toCanvas(background)
:导出当前视图内容成一个Canvas
组件,background
为背景颜色toDataURL(background)
:导出当前视图内容为base64格式的字符串图片内容,background
为背景颜色导出例子片段:
{
label: 'Export Image',
action: function(){
var w = window.open();
w.document.open();
w.document.write("<img src='" + g3d.toDataURL(g3d.getView().style.background) + "'/>");
w.document.close();
}
}