基于HTML5 Canvas 实现弹出框

  用户鼠标移入时,有弹出框出现,这样的需求很常见。这在处理HTML元素实现时简单,但是如果是对 HTML5 Canvas 构成的图形进行处理,这种方法不再适用,因为 Canvas 使用的是另外一套机制,无论在 Canvas 上绘制多少图形,Canvas 都是一个整体。而图形本身实际都是 Canvas 的一部分,不可单独获取,所以也就无法直接给某个图形增加 JavaScript 事件。然而,在 HT for Web 中,这种需求很容易实现,先附上Demo:http://www.hightopo.com/demo/blog_meadow_20170605/index.html

  这个场景图是基于 HT for Web 的 JSON 文件,可能大家对怎么生成这样的 JSON 文件有疑惑,其实这里是基于这个麻雀虽小五脏俱全的“HTML5拓扑图编辑器”(http://www.hightopo.com/demo/2deditor_20151010/HT-2D-Editor.html)进行了扩展,很容易就自定义出满足我需求拓扑编辑器。不仅如此,在这个 Demo 中,定义的三种类型弹框的矢量图 ‘tips1.json’、‘tips2.json’、‘tips3.json’ 是通过这个矢量编辑器(http://www.hightopo.com/demo/vector-editor/index.html)简单绘制了下,也还蛮好用。在上述场景中,用户将鼠标移入到草地等对象时,会有弹出框显示它的详细信息。

具体实现如下:

准备工作

   引入我们的 HT(http://www.hightopo.com/):

<script src='ht.js'></script>

  

dataModel = new ht.DataModel();
graphView = new ht.graph.GraphView(dataModel);
graphView.addToDOM();

 

   HT提供了自定义的 JSON 格式的矢量描述形式,以 HT 标准定义的 JSON 矢量格式,也可以作为图片进行注册和使用, HT 的矢量方式比传统格式更节省空间,缩放不失真,戳 HT for Web 了解详细信息。这里,将三种形状的 JSON 弹出框注册成图片以便后续调用:

 

ht.Default.setImage('tips1', 'symbols/tips1.json');
ht.Default.setImage('tips2', 'symbols/tips2.json');
ht.Default.setImage('tips3', 'symbols/tips3.json');

 然后获取有交互效果的对象,其中各个对象中的属性名是给各个图元设置好的标签名: 

 

//树
var tree = {'tree1' : true,'tree2' : true,'tree3' : true
};//草地
var grass = {'grass1' : true,'grass2' : true,'grass3' : true};//山
var mountain = {'mountain': true
};

 

弹出框

    其实弹出框的本质是一个 Node,当用户鼠标移入移出时,

1、控制 Node 的隐藏和显示可以达到弹框的效果;

2、鼠标位置的改变伴随着 Node 位置的改变;

3、鼠标移入到不同的对象上时, Node 上的贴图也跟着发生变化;

4、Node 中的属性值也随着鼠标位置发生变化。

    所以,要实现弹框,首先应新建 Node,并将其的层级设置为‘higher’,在这之前还需要将场景图的 JSON 文件反序列化,并且给反序列化后的图元均设置为层级‘lower’,防止被已有的图元挡住:

ht.Default.xhrLoad('meadow.json', function(text) {const json = ht.Default.parse(text);                    if(json.title) document.title = json.title;dataModel.deserialize(json);//设置层级dataModel.each(function(data){data.setLayer('lower');});//新建nodevar node = new ht.Node();                    node.s('2d.visible',false);node.setLayer('higher');dataModel.add(node);})

  然后,对底层的 DIV 监听 mousemove 事件,判断鼠标的位置是否在上述三个对象之上,根据对象类型,调用 layout() 函数对 Node 重新布局:

 

graphView.getView().addEventListener('mousemove', function(e) {node.s('2d.visible',false);var hoverData = graphView.getDataAt(e);pos = graphView.getLogicalPoint(e);if(!hoverData) return; if(tree[hoverData.getTag()]){ layout(node, pos, 'tips1');} else if (grass[hoverData.getTag()]) {layout(node, pos, 'tips2');} else if (mountain[hoverData.getTag()]) {layout(node, pos, 'tips3');}
});

  layout()函数所做的事情,已经在前面详细的阐述,其中,弹框中属性值的更新是将 JSON 文件的的 text 属性进行数据绑定,绑定的格式很简单,只需将以前的参数值用一个带 func 属性的对象替换即可,func 的内容有一下几种类型:

1、function类型,直接调用该函数,并传入相关 Data 和 view 对象,由函数返回值决定参数值,即 func(data, view);调用。

2、string类型:

      style@***开头,则返回 data.getStyle(***)值,其中***代表 style 的属性名。

      attr@***开头,则返回 data.getAttr(***)值,其中***代表 attr 的属性名。

      field@***开头,则返回 data.***值,其中***代表 attr 的属性名。

      如果不匹配以上几种情况,则直接将 string 类型作为 data 对象的函数名调用 data***(view),返回值作为参数值。

    除了 func 属性外,还可以设置 value 属性作为默认值,如果对应的 func 取得的值为 undefined 或者 null 时,则会采用 value 属性定义的默认值,详情可见 HT for Web数据绑定手册(http://www.hightopo.com/guide/guide/core/datamodel/ht-datamodel-guide.html)。例如,在这里,'tips1.json'文件中对阳光值进行数据绑定的结果如下:

 

"text": {"func": "attr@sunshine","value": "阳光值"},

 下面贴上 layout() 函数的源代码:

function layout(node, pos, type){node.s('2d.visible',true);node.setImage(type);                   if(type == 'tips1'){node.setPosition(pos.x + node.getWidth()/2, pos.y - node.getHeight()/2);node.a({'sunshine'  :   '阳光值   :     '+ (pos.x/1000).toFixed(2),'rain'  :   '雨露值   :     '+ (pos.y/1000).toFixed(2),'love'  :   '爱心值   :    ***'});} else if(type == 'tips2'){node.setPosition(pos.x , pos.y - node.getHeight()/2);node.a({'temp'  :   '温度   :     30','humidity'  :   '湿度   :     '+Math.round(pos.x/100)+'%'});} else if(type == 'tips3'){node.setPosition(pos.x - node.getWidth()/2, pos.y - node.getHeight()/2);node.a({'hight'  :   '海拔   :    ' + Math.round(pos.y)+'米','landscapes'  :   '地貌   :    喀斯特'});}}

 

云移动

    最后,我们的 Demo 还有个云移动的动画效果,在 HT 的数据模型驱动的图形组件的设计架构下,动画可理解为将某些属性由起始值逐渐变为目标值的过程, HT 提供了ht.Default.startAnim的动画函数,ht.Default.startAnim 支持 Frame-Based 和 Time-Based 两种方式的动画:

   Frame-Based 方式用户通过指定 frames 动画帧数,以及 interval 动画帧间隔参数控制动画效果;

   Time-Based 方式用户只需要指定 duration 的动画周期的毫秒数即可,HT 将在指定的时间周期内完成动画。

    详情见 HT for Web。

    在这里我们用的是 Time-Based 方式,源码如下:

 

var cloud = dataModel.getDataByTag('cloud');
parent = dataModel.getDataByTag('mountain');
round1 = parent.getPosition().x - parent.getWidth()/2 + cloud.getWidth()/2;
round2 = parent.getPosition().x + parent.getWidth()/2 - cloud.getWidth()/2;
end = round1;//云运动动画
var animParam = {duration: 10000,finishFunc: function() { end = (end == round1) ? round2 : round1;ht.Default.startAnim(animParam);},action: function(v, t) {var p = cloud.getPosition();cloud.setPosition(p.x + (end - p.x) * v , p.y);}
};
ht.Default.startAnim(animParam);

  最后,再次放上我们的 Demo (http://www.hightopo.com/demo/blog_meadow_20170605/index.html),供大家参考。

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/541278.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript | 嵌套if的示例

Example: 例&#xff1a; In this example, we are reading salary of an employee and finding the discount and net pay based on given salary and discount rate. 在此示例中&#xff0c;我们正在读取员工的薪水&#xff0c;并根据给定的薪水和折扣率找到折扣和净工资。 …

node.js 中间件_Node.js中的Passport中间件(模块)

node.js 中间件Hi! Welcome to Node.js Authentication Series, where well study and program the passport module or middleware. 嗨&#xff01; 欢迎使用Node.js身份验证系列 &#xff0c;我们将在其中研究和编程通行证模块或中间件 。 Nowadays, an important tool in m…

android开发自动提示框,Android 多种简单的弹出框样式设置代码

简介这是一个基于AlertDialog和Dialog这两个类封装的多种弹出框样式&#xff0c;其中提供各种简单样式的弹出框使用说明。同时也可自定义弹出框。项目地址&#xff1a;http://www.easck.com/jjdxmashl/jjdxm_dialogui特性1.使用链式开发代码简洁明了2.所有的弹出框样式都在Dial…

小程序中利用Moment.js格式时间

2019独角兽企业重金招聘Python工程师标准>>> LeanCloud给的日期是ISO格式&#xff0c;比如2017-06-05T14:08:20.589Z&#xff0c;直接显示在页面上体验不好。 凡是有关日期的&#xff0c;格式化、计算&#xff0c;用moment就够了。 1.下载 http://momentjs.com/ 选m…

JEESZ分布式架构3--CentOs下安装MySQL(环境准备)

声明&#xff1a;因为运行环境是基于Linux系统的&#xff0c;在做此框架之前需要做一些前期的环境准备工作CentOs下安装MySQL网上很多实例&#xff0c;因为博客后期作为框架的原生教程&#xff0c;故这边做详细的安装记录&#xff0c;我这边已经下载好了MySQL&#xff0c;通过s…

一个函数里两个setjmp_C语言中setjmp.h的longjmp()函数

一个函数里两个setjmpWe can call this function as an advance version of goto statement but with more dynamic range. The longjump() function allows us to pass parameters to know that the control has been jumped or not. 我们可以将此函数称为goto语句的高级版本&…

android实现滑动切换图,Android:使用ViewPager实现左右滑动切换图片加点点

图片发自简书App1、引入android-support-v4.jar包&#xff0c;在主布局里加入< ?xml version"1.0" encoding"utf-8"?>< RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.…

html的柱状图去除右边纵坐标,excel如何把次坐标轴逆序

excel2010设置水平坐标轴逆序类型,但垂直坐标轴刻设置水平坐标轴逆序且垂直坐标轴轴仍位于图表左侧的步骤是&#xff1a;打开带有图表的Excel工作表&#xff1b;在图表区域的水平轴标签位置双击鼠标左键&#xff0c;打开“设置坐标轴格式”&#xff1b;勾寻逆序类别”&#xff…

jhipster项目迁移websocket

2019独角兽企业重金招聘Python工程师标准>>> 1、 在项目目录下命令行安装 两个组件 bower install sockjs-client bower install stomp-websocket 2、在index.html 中加入组件js的引用 <script src"bower_components/sockjs-client/dist/sockjs.js">…

html 图片上放置按钮,用CSS在图片上再加一个小按钮

很简单的&#xff0c;嗯&#xff0c;就是要做成这样的&#xff1a;用CSS&#xff0c;当然得用层了&#xff0c;就是在图片上再加一个层&#xff0c;用来放那个按钮&#xff0c;按钮又有两种方式可以放&#xff0c;一种是直接用图片img标签&#xff0c;一种是通过背景图片放上去…

怎么将oracle的sql文件转换成mysql的sql文件

怎么将sql文件导入PowerDesigner中的方法(将oracle的sql文件转换成mysql的sql文件)呢&#xff1f; 怎么将xx.sql文件的数据库结构导入powerdesigner 的方法呢? 现讲下。 工具/原料 PowerDesigner软件&#xff0c;oracle数据库 方法/步骤 将要导入的库的所有表的表结构(不要表数…

ios html图片相对路径,iOS 下加载本地HTML/js/css/image 等路径问题

今天在项目中遇到一个问题&#xff1a;我将H5的文件拖入项目中&#xff0c;在webView上添加H5,运行时发现H5的样式与图片等都没屏幕快照 2016-07-06 11.33.22.png有了。经过多种测试后发现&#xff1a;是路径的问题。在ios项目下添加本地HTML/js/css/image 当拖入项目时有两种选…

el-calendar 怎么设置上一年和下一年_为什么香港硕士一年的含金量那么高?

为什么香港硕士研究生只读一年但含金量更高&#xff1f;近些年来香港留学大热&#xff0c;其中一个原因就是香港的授课式硕士研究生仅需一年就可以拿到学位。对于学生来说&#xff0c;在享受到国际一流的教学资源和工作机会的同时&#xff0c;既节省时间又节约金钱&#xff0c;…

武汉市江岸区2021年高考成绩查询,2021年武汉各区一、二、三批次高中有哪些(名单)...

5月5日至9日是武汉市中考网上报名填报志愿的日子&#xff0c;填报志愿之前应提前了解本区的一批次、二批次和三批次学校的名单&#xff0c;了解其历年录取分数线&#xff0c;并选中最合适最理想的一所学校进行填写&#xff0c;下面我们来看详细名单。武汉各区一、二、三批次高中…

《Java设计模式》之桥接模式

Bridge模式的概念 Bridge 模式是构造型的设计模式之中的一个。Bridge模式基于类的最小设计原则&#xff0c;通过使用封装&#xff0c;聚合以及继承等行为来让不同的类承担不同的责任。它的主要特点是把抽象&#xff08;abstraction&#xff09;与行为实现&#xff08;implement…

cad中tk什么意思_设计中的“Neobject”什么意思?来了解一下

DesignArchitectureInteriorsFashionArtTransportTHE STUFF THAT REFINES YOU破界造物New Language?“Neobject&#xff0c;言如其字&#xff0c;从语义上&#xff0c;前缀 neo- 表示新的&#xff0c;object 则是物体&#xff0c;是客观存在&#xff0c;很中性&#xff0c;作动…

html文段源码,HTML 段落

HTML 段落HTML 可以将文档分割为若干段落。HTML 段落段落是通过 标签定义的。实例这是一个段落这是另一个段落尝试一下 注意&#xff1a;浏览器会自动地在段落的前后添加空行。( 是块级元素)不要忘记结束标签即使忘了使用结束标签&#xff0c;大多数浏览器也会正确地将 HTML 显…

c#如何实现叫号操作_微信预约排队叫号系统操作指南

“微信排队预约"功能是阿拉善盟税务局为进一步优化营商环境&#xff0c;深化“放管服”改革&#xff0c;提高纳税便利度&#xff0c;更好地服务于阿拉善经济社会发展而开发的一项便民措施。通过“微信排队预约”功能&#xff0c;纳税人可以随时随地通过微信获取办税大厅的…

计算机用户越权操作的原因,“三员系统”中常见的越权问题

原标题&#xff1a;“三员系统”中常见的越权问题一、越权访问越权访问(Broken Access Control&#xff0c;简称BAC)是Web应用程序中一种常见的漏洞&#xff0c;由于其存在范围广、危害大&#xff0c;被OWASP列为Web应用十大安全隐患的第二名。1.1越权访问的产生比如&#xff0…

富士施乐2022网络扫描设置_富士施乐(FUJI XEROX)全系列复印机产品介绍

富士施乐(FUJI XEROX)复印机全系列详解富士施乐复印机是中小型办公环境的理想机型。所有的都拥有高效生产力和强大的稳定性&#xff0c;无论您需要亮丽色彩、黑白打印、亦或是足以应对复杂文档工作流的强大功能&#xff0c;总有一款适合您。DocuCentre S2110NDocuCentre S2110N…