很多人都有这样的疑问,基于HTML5 Canvas实现的元素怎么和用户进行交互?在这里我们用到HT for Web(http://www.hightopo.com/guide/guide/core/beginners/ht-beginners-guide.html)写了个Demo进行示例。
场景如下所示,在该场景中双击温度和湿度下的Node,会生成输入框供用户填写内容,这之后,用户按下“Enter”键可以将输入内容传到Node中,同时删除输入框,地址::http://www.hightopo.com/demo/GraphInput/display.html
接下来我们探讨一下具体实现:
准备工作如下:
<script src='ht.js'></script>
dataModel = new ht.DataModel(); graphView = new ht.graph.GraphView(dataModel); graphView.addToDOM();
1、利用系统中定义好的矢量资源进行反序列化来实现场景图:
ht.Default.xhrLoad('TemperatureIndex.json', function(text) { var json = ht.Default.parse(text); if(json.title) document.title = json.title; dataModel.deserialize(json); }
2、双击事件
本例双击会产生输入框,在我们的HT中,GraphView默认内置了一些交互器,以实现基本的选择、单双击、缩放、平移和编辑等交互的功能,内置的交互器有:
内置的Interactor在交互过程中会派发事件,可通过GraphView#addInteractorListener进行监听,简写为mi(详情可看HT for Web 入门手册http://www.hightopo.com/guide/guide/core/beginners/ht-beginners-guide.html#ref_graphviewinteraction),在这里,我们用内置的graphView.addInteractorListener监听双击事件:
graphView.addInteractorListener(function(e){ if (e.kind !== 'doubleClickData') return; if (currentInput) removeInput(); var data = e.data; if (clickableTags[data.getTag()]){ setTimeout(function(){ createInput('input', data); }, 0); } });
3、创建输入框
在双击事件发生时,首先需要判断发生双击事件的元素是不是场景中定义的标签名‘temperature’和‘humidity’的node图元,我们用clickableTags对象来保存两个node:
var clickableTags = { 'temperature': true, 'humidity': true }
在双击的图元是‘temperature’或者‘humidity’时,调用createInput()函数生成输入框,createInput()代码如下:
function createInput(tagName,node){ if (currentInput) { removeInput(graphView, currentInput); return; } else { var element = document.createElement(tagName); graphView.getView().appendChild(element); element.bindingNode = node; ht.Default.setFocus(element); currentInput = element; layout(currentInput);//布局 return currentInput; } }
在createInput()函数中,用全局变量currentInput保存着当前生成的输入框元素,为保证再次生成输入框时,调用removeInput()清除上次生成的输入框元素,从而不影响性能。
4、布局
生成的输入框应该放在哪儿?这就是layout()函数中所做的事情。layout()函数修改生成的输入框的位置信息,让其在GraphView拓扑图组件上的位置刚好的node图元的位置相同。
function layout(element){ var rect = element.bindingNode.getRect(); var x = rect.x; var y = rect.y; element.style.position = 'absolute'; 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’为例,在点击标签名为‘temperature’的node图元时,会在其上生成一个输入框,获取该node图元的宽、高、位置信息,并分别赋值给绝对定位后输入框的宽、高、位置,这样即可让输入框刚好覆盖住node图元。
5、平移和缩放
可能细心思考的朋友也会发现,在对整个场景图进行平移和缩放时,按照上诉布局方式,输入框的位置和大小却没有跟随着node图元的位置进行改变,所以我们在布局时还需要思考到平移、缩放事件。
首先,layout函数的内容中,元素的宽、高、位置信息必须加入平移和缩放产生的结果,所以,最终layout代码如下:
function layout(element){ var rect = element.bindingNode.getRect(); var zoom = graphView.getZoom(); var tx = graphView.tx(); var ty = graphView.ty(); rect.x *= zoom; rect.y *= zoom; rect.width *= zoom; rect.height *= zoom; var x = tx + rect.x; var y = ty + rect.y; element.style.position = 'absolute'; 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'; }
其次,我们需要对平移和缩放事件添加监听,以便能在该事件发生时,再次调用layout()函数将输入框的位置进行同步,在这里,我们用内置的交互器addPropertyChangeListener(简写为mp),监听zoom、translateX、translateY属性的变化:
var changeProperties = { 'zoom': true, 'translateX': true, 'translateY':true }
graphView.mp(function(e) { if (changeProperties[e.property]) { var elements = document.getElementsByTagName('input'); for (var i = 0; i < elements.length; i++) { layout(elements[i]); } } });
6、更新node
大家在Demo中可以发现,我们按下Enter键时,输入的文字会同步到node中,其实这里做了两件事: 给node设值后删除输入框。
a、给node设值,是用一个名为setText()的函数来实现的,实现代码如下:
function setText(tagName){ var element = document.getElementsByTagName(tagName); if(!element) return; for (var i = 0; i < element.length; i++) { var value = (element[i].value) ? element[i].value : 32 ; element[i].bindingNode.s('text', value); } }
在检测输入框中值得存在性后,给node图元赋值用到我们HT的setStyle(简写为s)方法。
b、删除输入框
function removeInput(){ if(!currentInput) return; graphView.getView().removeChild(currentInput); currentInput = null; }
c、添加Enter的事件监听器
因为没有监听键盘的内置交互器,所以我们通过graphView.getView().addEventListener直接对底层的div添加监听。
graphView.getView().addEventListener('keydown', function(event){ if(ht.Default.isEnter(event)){ setText('input'); removeInput(); } else if(ht.Default.isEsc(event)){ removeInput(); } }, false);
最后,再贴上Demo地址(http://www.hightopo.com/demo/GraphInput/display.html),希望能够帮助那些需要在拓扑图中加入原生HTML的朋友,也望大家不吝赐教。
相关推荐
在这个“基于html5 canvas实现聚宝盆接金币游戏特效源码.zip”中,我们可以看到HTML5的Canvas元素被巧妙地用于构建一个有趣的接金币游戏。 Canvas是HTML5中的一个画布元素,它允许开发者通过JavaScript来绘制2D图形...
在这个“基于html5 canvas实现的动态文字特效代码”项目中,我们将探讨如何利用Canvas API来创建引人注目的文字动画效果。 Canvas API提供了一系列方法,如`fillText()`和`strokeText()`,用于在画布上绘制文本,而...
标签“动画”提示我们关注的是动态效果,而“canvas”和“html5”则强调了这个效果是基于Web技术实现的。这样的动画效果不仅美观,而且具有良好的跨平台性,可以在支持HTML5的现代浏览器中运行。 在实际项目中,...
总的来说,这个基于HTML5 Canvas的思维导图工具展示了Canvas的强大能力,它不仅能够实现图形的动态绘制,还能实现丰富的用户交互。开发者通过熟练运用JavaScript和Canvas API,为用户提供了创建和管理思维导图的有效...
这个“基于HTML5 Canvas实现的会跳舞的时间粒子动画效果源码”是一个前端项目,展示了如何利用Canvas API创建动态、交互式的粒子动画。 在HTML5 Canvas中,我们首先需要在HTML文档中定义一个`<canvas>`元素,然后...
2. **事件监听与处理**:为了实现用户输入的实时更新,需要监听键盘事件,捕获用户的输入,并将输入内容同步到Canvas上进行绘制。同时,也要处理鼠标事件,如点击、拖拽等,以便支持选择、复制、粘贴等编辑功能。 3...
这个“一个基于html5 canvas 实现的围棋棋盘,使用简单.zip”项目就是HTML5技术的一个实际应用实例,它利用HTML5的Canvas API来构建了一个功能齐全的围棋游戏界面。 Canvas是HTML5中的一个核心元素,它提供了一个二...
在这个“html5 canvas交互式数据图表插件代码”中,我们可以深入学习如何利用Canvas API来实现数据可视化。 1. HTML5 Canvas基础: HTML5 Canvas是一个基于矢量图形的画布元素,通过JavaScript API来控制绘图。...
本项目"基于html2canvas生成带二维码的活动海报"提供了一个纯前端解决方案,使得开发者无需后端支持也能快速实现此类功能。html2canvas是一个JavaScript库,它能够将网页的DOM(文档对象模型)渲染为图片,从而解决...
这个“基于HTML5 Canvas实现的图片马赛克模糊特效”就是一个利用Canvas API创建图像处理效果的例子。这个插件通过操作像素数据来实现马赛克和模糊效果,使得用户可以在网页上轻松地对图片进行视觉处理。 首先,让...
通过以上这些技术,我们可以构建出一个基于HTML5 Canvas的简单小游戏。这不仅涉及到前端开发的基本技能,还需要对游戏设计和用户体验有深入的理解。不断实践和迭代,你将能够创作出更加复杂和有趣的游戏。
这款“html5 canvas可拖放互动的照片墙插件”利用了Canvas的强大功能,创建了一个允许用户交互的动态照片展示平台。在这款插件中,用户可以自由地对照片进行操作,如拖放、缩放、旋转和添加边框,极大地提升了用户...
在博文《基于HTML5 Canvas和jQuery 的画图工具的实现》中,作者可能详细介绍了如何结合使用这两个技术来构建一个简单的画图应用。这可能包括以下步骤: 1. **初始化Canvas**:在HTML中创建一个`<canvas>`元素,并...
这个"一个基于html5 canvas的流程图demo.zip"文件很可能包含了一个使用HTML5 Canvas技术实现的流程图示例项目。下面将详细探讨HTML5 Canvas以及其在多媒体和游戏开发中的应用。 HTML5 Canvas是一个基于矢量图形的...
基于HTML5 canvas的图片马赛克特效 <canvas id="myCanvas"></canvas> <script src="js/main.js"></script> </html> ``` 接下来,我们导入`1-15021220541X35.jpg`作为要处理的图片。通常,图片会被设置为...
本项目基于HTML5的Canvas技术,实现了商品的360度全方位展示,适用于Chrome、Firefox以及IE9及以上的浏览器。 HTML5是现代网页开发的标准,它引入了许多新的API和元素,Canvas就是其中之一。Canvas是一个二维绘图上...
"HTML5基于Canvas实现超酷Loading动画特效源码"这一项目,就是利用Canvas的强大功能来创建一个吸引用户的加载动画。 Canvas是HTML5中的一个二维绘图上下文,通过JavaScript可以实现各种复杂的图形和动画。在这个...
HTML5 Canvas是一个强大的Web绘图接口,允许开发者在网页上绘制图形、动画,甚至实现复杂的交互功能。这个压缩包中的源码示例是利用HTML5 Canvas来创建一个鼠标交互式的柳絮树枝动画特效。下面我们将深入探讨这个...
【标题】中的“基于html5 canvas实现的跟随鼠标圆点粒子发散动画特效”是一个前端开发项目,它利用HTML5的Canvas元素来创建一个交互式的视觉效果。Canvas是HTML5中用于绘制图形的一个强大功能,它允许开发者通过...
本项目以"基于jquery+canvas实现的拖动插件"为主题,利用jQuery与HTML5的Canvas API,创建了一个允许用户点击并拖动图形的功能。 Canvas是HTML5引入的一个强大特性,它提供了一个二维的绘图表面,开发者可以使用...