当前位置: 首页 > Web前端 > HTML5

基于HTML5Canvas实现用户交互

时间:2023-04-05 16:32:08 HTML5

很多人都有这样的疑问,基于HTML5Canvas的元素如何与用户交互?这里我们以HTforWeb(http://www.hightopo.com/guide...)写一个Demo为例。  场景如下。该场景下,双击温湿度下的节点,会生成一个输入框,供用户填写内容。之后,用户可以按下“Enter”键将输入的内容传送到Node,同时删除。输入框,地址:http://www.hightopo.com/demo/...下面说说具体实现:准备工作如下:dataModel=新的ht.DataModel();graphView=newht.graph.GraphView(dataModel);graphView.addToDOM();1。使用系统定义的向量资源反序列化实现场景图:ht.Default.xhrLoad('TemperatureIndex.json',function(text){varjson=ht.Default.parse(text);if(json.title)document.title=json.title;dataModel.deserialize(json);}2.双击事件  本例中,双击会生成一个输入框,在我们的HT中,GraphView内置了一些交互器,通过默认实现基本的选择、双击、缩放、平移、编辑等交互功能,内置交互器有:  内置的Interactor会在交互过程中派发事件,可以通过GraphView#addInteractorListener进行监听,缩写为mi(详见HTforWeb入门手册http://www.hightopo.com/guide...),这里,我们使用内置的graphView.addInteractorListener监听双击事件:graphView.addInteractorListener(function(e){if(e.kind!=='doubleClickData')return;if(currentInput)removeInput();vardata=e.data;if(clickableTags[data.getTag()]){setTimeout(function(){createInput('input',data);},0);}});3.创建一个输入框  当双击事件发生时,首先要判断双击事件发生的元素是否为定义在标签名'temperature'和'humidity'的节点图元现场。我们使用clickableTags对象来保存这两个节点:varclickableTags={'temperature':true,'humidity':true}  当双击的元素为'temperature'或'humidity'时,调用createInput()函数生成输入框。createInput()代码如下:functioncreateInput(tagName,node){if(currentInput){removeInput(graphView,currentInput);返回;}else{varelement=document.createElement(tagName);graphView.getView().appendChild(元素);element.bindingNode=节点;ht.Default.setFocus(元素);当前输入=元素;布局(当前输入);//布局返回currentInput;}}  在createInput()函数中,使用全局变量currentInput保存当前生成的输入框元素。为保证再次生成输入框,在不影响性能的情况下,调用removeInput()清除上次生成的输入框元素。4.布局  生成的输入框应该放在哪里?这是在layout()函数中完成的。layout()函数修改生成的输入框的位置信息,使其在GraphView拓扑图组件上的位置与节点图元的位置完全一致。函数布局(元素){varrect=element.bindingNode.getRect();varx=rect.x;vary=rect.y;element.style.position='绝对';element.style.width=rect.width+'px';element.style.height=rect.height+'px';element.style.top=y+'px';element.style.left=x+'px';element.style.background='#fff';element.style.color='#000';element.style.textAlign='center';}  以'temperature'为例,当点击label为'temperature'的节点元素时,会在其上生成一个输入框,获取宽,高,以及节点图元的位置信息,对绝对定位后的输入框的宽高和位置进行赋值,使输入框刚好覆盖节点图元。5.平移缩放  细心思考的朋友还会发现,在平移缩放整个场景图时,按照诉求布局方式,输入框的位置和大小并没有随着节点的位置而变化primitive,所以我们在布局的时候还需要考虑平移和缩放事件。  首先,在布局函数的内容中,平移缩放的结果中要加上元素的宽高位置信息,所以最终的布局代码如下:functionlayout(element){varrect=element.bindingNode.getRect();varzoom=graphView.getZoom();vartx=graphView.tx();varty=graphView.ty();rect.x*=缩放;rect.y*=缩放;rect.width*=缩放;rect.height*=缩放;varx=tx+rect.x;vary=ty+rect.y;element.style.position='绝对';element.style.width=rect.width+'px';元素.样式。height=rect.height+'px';element.style.top=y+'px';element.style.left=x+'px';element.style.background='#fff';element.style.color='#000';element.style.textAlign='center';}  其次,我们需要给平移和缩放事件添加监听器,这样当事件发生时,我们可以再次调用layout()函数来同步输入框的位置。这里,我们使用内置交互器addPropertyChangeListener(缩写为mp),监听zoom、translateX、translateY属性的变化:varchangeProperties={'zoom':true,'translateX':true,'translateY':true}graphView.mp(function(e){if(changeProperties[e.property]){varelements=document.getElementsByTagName('input');for(vari=0;i