今天又返回好好地消化了一下我们的数据容器 DataModel,这里给新手做一个典型的数据模型事件处理的例子作为参考。这个例子看起来很简单,实际上结合了数据模型中非常重要的三个事件处理的部分:属性变化事件监听、选中变化事件监听以及数据模型变化事件监听。
为了让这个例子具现化,我将这个简单的例子做了一点改动,下面我会一一解释。
例子地址:http://hightopo.com/guide/guide/core/datamodel/examples/example_datamodel.html
这是我改造之后的模样,将 dataModel 数据容器共享,通过对数据容器的增删事件的监听得到的现在的结果,并且在显示上做了一点“手脚”。下面我们从头解析这例子,你们会知道为什么我特地将这个简单的例子提出来。
首先,我们得创建场景将作为基础,整个场景我算是分为三个部分,顶部工具栏,2D 部分以及 3D 部分。顶部工具栏部分使用的纯 HTML 写的:
<button onclick="addData()">Add</button> <button onclick="removeData()">Remove</button> <button onclick="clearDataModel()">Clear</button> <span id="property" class="output"></span> <span id="model" class="output"></span> <span id="selection" class="output"></span>
因为有点击事件,所以我们直接在 button 按钮上进行,后面的 span 标签显示纯文本内容。
我们知道,HT 的所有组件都是基于一个根部 div 的,要将这个 div 部署到 html 页面上很简单,但是 HT 内部对这个 div 设置了绝对定位,所以我们在添加这个 div 进 HTML 页面中时,也要设置绝对定位中的位置,我在页面中添加了一个 div,将 HT 的部分都添加进这个 div 中:
<div id="myDiv" style="border: 1px solid red; width: 800px; height: 600px;position: absolute; "></div>
dataModel = new ht.DataModel(); g3d = new ht.graph3d.Graph3dView(dataModel); g3d.setGridVisible(true);//设置网格可见 g3d.setEye(185, 50, 470);//设置3d的眼睛位置 g3d.setCenter(200, 47, 10);//设置3d的中心位置, 这两个属性都是为了让用户看3d上的场景更舒服,更直接 g2d = new ht.graph.GraphView(dataModel); g2d.setEditable(true);//设置2d图元可编辑 g2d.fitContent(true);//将所有的图元显示到页面上 splitView = new ht.widget.SplitView(g2d, g3d, 'v', 0.3);//分割组件,装了2d和3d两个场景 splitView.addToDOM();//将分割组件添加进body中,并设置绝对定位的位置 myDiv = document.getElementById('myDiv'); myDiv.appendChild(splitView.getView());//将分割组件添加进myDiv中
接着添加节点进入 dataModel 数据模型之中,我们这里做的是机房的机柜,本来想做的是服务器,手头上暂时只有这个资源,也不赖。我封装了一个增加函数,一个删除函数,还有一个清楚函数,分别对应的是工具栏上的“Add”、“Remove”以及“Clear”三个功能:
function addData() { var data = new ht.Node(); data.setPosition(index*60, 50); data.setName('node'+index); data.setSize(40, 40); data.setImage('cabinet'); data.s({ 'image.stretch': 'centerUniform', 'shape3d': 'cabinet' }); index++; dataModel.add(data); return data; } function removeData() { if(!dataModel.sm().ld()) return; dataModel.remove(dataModel.sm().ld()); } function clearDataModel(){ dataModel.clear(); index = 0; }
其中,代码中出现的“data.setImage('cabinet')”,是我通过 ht.Default.setImage('cabinet', 'imageURL') 方式定义的,调用的时候直接 data.setImage('imageName') 即可,具体参考 HT for Web 入门手册 image 章节。
2D 的图片显示肯定和 3D 的模型显示是不一样的,2D 中我们直接用贴图就能解决,而 HT 3D 中支持 obj 格式的模型显示,就是这个部分:
HT 封装了解析 obj 格式的函数 ht.Default.loadObj 函数用来导入模型,该函数有三个参数,第一第二分别为 obj 文件的路径和 mtl 文件的路径,第三个参数为 json 格式控制参数,具体参数请参考 HT for Web OBJ 手册 loadObj 函数章节(ps:用 obj 模型会导致跨域问题,要放到服务器上运行):
ht.Default.loadObj('obj/机柜组件1.obj', 'obj/机柜组件1.mtl', { cube: true,//是否将模型缩放到单位1的尺寸范围内,默认为false center: true,//模型是否居中 prefix: 'obj/',//路径前缀,如果前面参数写了路径前缀,这个不写也可以 shape3d: 'cabinet',//指定 shape3d 名称 finishFunc: function(modelMap, array, rawS3){//调用ht.Default.parseObj解析后的返回值,若加载或解析失败则返回值为空 window.rawS3 = rawS3;//让当前模型的尺寸为原始尺寸 if(modelMap){ cabinet1 = addData();//添加两个节点到 dataModel 中 cabinet2 = addData(); } } });
现在,节点和模型都已经导入到场景中了,终于来到了我们今天的重点,事件交互部分。ht.DataModel 数据容器管理着 Data 数据的增删以及变化事件的派发,这里我们就这两种事件进行对 Data 数据的管理。
1. addDataModelChangeListener(function(e) {}, scope) 增加数据模型增删变化事件监听器,可用简写 mm(func, scope), func 为监听器函数,scope 为监听器函数域(可选),在监听器函数中的 event 有两个属性: kind 和 data,其中 kind 为事件的类型:
e.kind === 'add'
代表添加Data
对象,e.data
为被添加的对象e.kind === 'remove'
代表删除Data
对象,e.data
为被删除的对象e.kind === 'clear'
代表容器被清除
这里我们将对模型的增删事件的监听结果传给 HTML 中的 id 为 model 的 span 作为内容:
var model = document.getElementById('model'); dataModel.addDataModelChangeListener(function(e) { if(e.kind === 'add')//如果事件类型为 add 增加节点 model.innerHTML = e.data + ' added';//就将model 的内容替换为 添加的节点 added if(e.kind === 'remove') model.innerHTML = e.data + ' removed'; if(e.kind === 'clear') model.innerHTML = 'dataModel cleared' });
2. addDataPropertyChangeListener(function(e) {}, scope) 增加模型中 Data 数据属性变化事件监听器,可用简写 md(func, scope),其中 event 事件有四种属性:
-
e.data
代表属性变化的对象 -
e.property
代表变化属性的名字 -
e.newValue
代表属性的新值 -
e.oldValue
代表属性的老值 -
Data
对象在设置属性值函数内调用firePropertyChange(property, oldValue, newValue)
触发属性变化事件:-
get/set
类型属性,如setAge(98)
触发事件的e.property
为age
-
style
类型属性名前加s:
前缀以区分,如setStyle('age', 98)
触发事件的e.property
为s:age
-
attr
类型属性名前加a:
前缀以区分,如setAttr('age', 98)
触发事件的e.property
为a:age
-
这里我们将对模型中 Data 的属性变化事件的监听结果传给 HTML 中的 id 为 property 的 span 作为内容:
var model = document.getElementById('model'); dataModel.addDataPropertyChangeListener(function(e) { property.innerHTML = e.data + '\'s ' + e.property + ' has changed, the old value is ' + e.oldValue + ' and the new value is ' + e.newValue; });
3. 最后,我们对选中的节点进行增加监听器,监听选中变化事件。ht.SelectionModel管理 DataModel 模型中 Data 对象的选择状态, 每个 DataModel 对象都内置一个 SelectionModel 选择模型,控制这个 SelectionModel 即可控制所有绑定该 DataModel 的组件的对象选择状态, 这意味着共享同一 DataModel 的组件默认就具有选中联动功能。
如果希望某些组件不与其他组件选中联动,可通过调用 view.setSelectionModelShared(false), 这样该 view 将创建一个专属的 SelectionModel 实例。
综上所述有两种途径可得到 SelectionModel:
-
dataModel.getSelectionModel()
获取数据容器中组件共享的选中模型。 -
view.getSelectionModel()
获取当前组件使用的选中模型,selectionModelShared
为false
时,返回view
专用的选择模型。
addSelectionChangeListener(function(e) {}, scope)增加监听器,监听选中变化事件,简写为 ms(func, scope):
-
e.datas
包含所有选中状态变化的对象,之前选中现在取消选中,或之前没选中现在被选中的对象 -
e.kind === 'set'
代表此事件由setSelection(datas)
引发 -
e.kind === 'remove'
代表此事件由removeSelection(datas)
引发 -
e.kind === 'append'
代表此事件由appendSelection(datas)
引发 -
e.kind === 'clear'
代表此事件由clearSelection(datas)
引发
这里我们将对模型中 Data 的选中变化事件的监听结果传给 HTML 中的 id 为 selection 的 span 作为内容:
var selection = document.getElementById('selection'); dataModel.sm().addSelectionChangeListener(function(e){ if(dataModel.sm().size() === 0) selection.innerHTML = 'Nothing selected';//如果选中模型的“长度”为0,即没有选中内容 else if(dataModel.sm().size() === 1) selection.innerHTML = e.datas + ' selected'; else selection.innerHTML = dataModel.sm().size() + ' datas selected'; });
以上,所有的代码全部分析完毕!大家可以天马行空,创建出属于你自己的3维模型!
相关推荐
HTML5 Canvas是一个强大的Web图形接口,它允许开发者在网页上直接用JavaScript绘制2D和3D图形。在"使用HTML5 Canvas绘制3D房间模型和人物动画特效"这个主题中,我们将深入探讨如何利用Canvas技术构建逼真的3D环境,...
在这个“html5 canvas几何模型3D运动动画效果”项目中,我们将探讨如何利用HTML5 Canvas API构建一个引人入胜的3D模型动画。 1. **Canvas API基础** HTML5 Canvas是一个基于矢量图形的画布,通过JavaScript进行...
这个“基于html5 canvas绘制 3D城市模型动画特效源码.zip”压缩包提供了使用HTML5 Canvas创建3D城市模型动画的方法和源代码。 Canvas是一个基于矢量图形的画布,通过JavaScript进行编程操作。开发者可以利用它来...
在本案例中,我们关注的是HTML5中的Canvas元素,它允许动态生成图像,包括复杂的2D和3D图形。Canvas API提供了一系列方法和属性,使得开发者可以直接在网页上绘制图像,实现动态交互的效果。 描述中提到的“图片3D...
在这个名为“html5 canvas实现旋转的3D几何模型动画特效源码.zip”的压缩包中,我们很显然会涉及到使用HTML5 Canvas API来构建旋转的3D几何模型动画的技巧和方法。 首先,Canvas API提供了`drawImage()`、`fillRect...
HTML5 Canvas是一个强大的Web图形库,它允许开发者在网页上直接用JavaScript绘制图像,从而创建出丰富的交互式2D和3D图形。在这个名为“HTML5 Canvas五彩缤纷的3D发光水晶球动画”的项目中,我们将深入探讨如何利用...
html5 canvas文字标签云3D旋转动画特效.rar html5 canvas文字标签云3D旋转动画特效.rar html5 canvas文字标签云3D旋转动画特效.rar html5 canvas文字标签云3D旋转动画特效.rar html5 canvas文字标签云3D旋转动画特效...
WebGL通过JavaScript API与HTML5 Canvas元素结合,为开发者提供了在Web上构建沉浸式3D图形应用的能力。 1. **WebGL基础** - **上下文创建**:在HTML5页面中,通过`<canvas>`元素创建WebGL上下文,使用`getContext...
HTML5 Canvas是Web开发中的一个强大工具,它允许开发者在网页上进行动态图形绘制,创造出丰富的交互式2D和3D视觉效果。在这个特定的案例中,“html5 canvas 3D汽车模型排放尾气动画特效”是利用Canvas API构建的一个...
首先,Canvas3D是基于Web技术的,它利用HTML5的WebGL标准,使得在Qt应用中可以实现与网页浏览器中类似的3D渲染。开发者可以通过JavaScript API来操纵3D场景,创建复杂的几何形状,应用纹理,光照和动画。Canvas3D的...
本项目"基于html2canvas生成带二维码的活动海报"提供了一个纯前端解决方案,使得开发者无需后端支持也能快速实现此类功能。html2canvas是一个JavaScript库,它能够将网页的DOM(文档对象模型)渲染为图片,从而解决...
在这个特定的案例中,“HTML5 Canvas模拟3D地球旋转动画特效”利用了Canvas的强大功能来创建一个逼真的3D地球模型,并在浏览器中实现动态旋转的效果。 首先,Canvas元素是HTML5新增的特性,它是一个矩形区域,通过...
这个"html5 canvas绘制3D房间模型动画特效.zip"文件显然利用了Canvas的这一特性,创建了一个交互式的3D房间场景。下面我们将深入探讨相关知识点。 1. HTML5 Canvas API: HTML5 Canvas是一个二维绘图API,提供了...
HTML5 Canvas是Web开发中的一个强大工具,它允许开发者在网页上进行2D和3D图形绘制,提供了丰富的API来创建交互式和动态的视觉效果。在这个特定的案例中,"HTML5 Canvas 3D跳动Loading加载动画-可调节参数"是一个...
此外,学习和实践这个特效不仅可以提升HTML5 Canvas的技能,还能了解如何将2D渲染技术应用于3D视觉效果。这对于开发游戏、可视化应用或者其他互动网页元素都是很有价值的。总之,HTML5 Canvas的3D动画特效是一个结合...
HTML5 Canvas是一个强大的Web图形接口,它允许开发者在网页上直接用JavaScript绘制2D图形。Canvas元素是HTML5新增的一部分,通过JavaScript API提供了丰富的绘图功能,为网页设计师和开发者提供了一个灵活且高效的...
html5 canvas左右翻转2d动画
至此,我们就实现了基于HTML5 canvas的图片马赛克特效。用户可以通过修改`blockSize`变量来调整马赛克的模糊程度,以达到不同的视觉效果。这个特效适用于创建动态的、个性化的H5页面,尤其在隐私保护或艺术设计中...