html5利用canvas绘画二级树形结构图的示例


Posted in HTML / CSS onSeptember 27, 2017

上周需要做一个把页面左侧列表内容拖拽到右侧区域,并且绘制成关系树的功能。

看了设计图,第一反应是用canvas绘制关系线。

吭哧吭哧搞定这个功能后,发现用canvas绘图,有一个很严重的缺陷。那就是如果左侧关系特别多,需要绘制成百上千条时,而canvas画布的宽高在写dom的时候就已声明。关系很多的情况下,无法使用canvas。

不过还是记录一下研究成果。

下面是设计图:

html5利用canvas绘画二级树形结构图的示例

做出效果如下:

html5利用canvas绘画二级树形结构图的示例

html、css代码就不贴了。 js主要用到了拖拽、canvas绘制。

function startDrag(ev) {
    ev.dataTransfer.setData("Text",ev.target.innerText);
}

function allowDrop(ev) {
    ev.preventDefault();
}

function decideDrop(ev) {
    ev.preventDefault();
    var length = $('.main-target').length;
    if(length == 0){
        dropToMain(ev);
    }else {
        dropToRelate(ev);
    }
}

function dropToMain(ev) {
    var data=ev.dataTransfer.getData("Text");
    var _html = '<div class="main-target">' + data + '</div>';
    $('.main-target-wrap').width('auto').append(_html);
}

function dropToRelate(ev) {
    //画关系线
    drawLineOne(document.getElementById('canvasOne'), 'begin');
    drawLineOne(document.getElementById('canvasTwo'), 'end');

    //插入图片 以及图片初始化点击事件
    var _img = $('<img src="inner.png">');
    $('.imgBox').append(_img);
    _img.click(showRelationBox);
    //写入数据
    var data = ev.dataTransfer.getData('Text');
    var _html = '<div class="item-text">' + data + '</div>';
    $('.relation-text-box').append(_html);
}

以上是拖拽的方法,我也是一边看菜鸟教程,一边写出的拖拽方法。

function drawLineOne(canvas, flag) {
    var context = canvas.getContext('2d');
    var position = {};
    if(flag == "begin"){
        position = getCanvasOnePosition();
    }else {
        position = getCanvasTwoPosition();
    }
    context.beginPath();
    context.moveTo(position.beginX, position.beginY);
    context.lineTo(position.endX, position.endY);
    if(position.endX2 && position.endY2){
        context.lineTo(position.endX2, position.endY2);
    }
    context.strokeStyle = "#333";
    context.stroke();
}

/**
 * 左侧关系线
 * @returns {{beginX: *, beginY: *, endX: *, endY: *}}
 */
function getCanvasOnePosition() {
    var imgLength = $('.imgBox img').length;
    var beginX = (imgLength == 0) ? 0 : 77,
        beginY = (imgLength == 0) ? 15 : (15 + 60 * (imgLength-1)),
        endX = (imgLength == 0) ? 155 : 77,
        endY = 60*imgLength + 15;
    var position = {beginX: beginX, beginY: beginY, endX: endX, endY: endY};
    if(imgLength > 0){
        position.endX2 = 155;
        position.endY2 = endY;
    }
    return position;
}

function getCanvasTwoPosition() {
    var imgLength = $('.imgBox img').length;
    var endY = 15 + 60*imgLength
    return {beginX: 0, beginY: endY, endX: 155, endY: endY}
}

以上是canvas画线的方法,代码没什么难点,主要就是分析线的起始坐标麻烦一些。希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

HTML / CSS 相关文章推荐
利用CSS的Sass预处理器(框架)来制作居中效果
Mar 10 HTML / CSS
CSS3 Flexbox中flex-shrink属性的用法示例介绍
Dec 30 HTML / CSS
html5仿支付宝密码框的实现代码
Sep 06 HTML / CSS
如何让IE9以下版本(ie6/7/8)认识html5元素
Apr 01 HTML / CSS
基于HTML5 的人脸识别活体认证的实现方法
Jun 22 HTML / CSS
HTML5拖放效果的实现代码
Nov 17 HTML / CSS
Html5 video标签视频的最佳实践
Feb 26 HTML / CSS
AmazeUI 图标的示例代码
Aug 13 HTML / CSS
详解如何解决H5开发使用wx.hideMenuItems无效果不生效
Jan 20 HTML / CSS
使用HTML+Css+transform实现3D导航栏的示例代码
Mar 31 HTML / CSS
在CSS中使用when/else的方法
Jan 18 HTML / CSS
HTML静态页面获取url参数和UserAgent的实现
Aug 05 HTML / CSS
html5新增的定时器requestAnimationFrame实现进度条功能
Dec 13 #HTML / CSS
详解使用HTML5的classList属性操作CSS类
Oct 13 #HTML / CSS
HTML5网页音乐播放器的示例代码
Nov 09 #HTML / CSS
js实现移动端H5页面手指滑动刻度尺功能
Nov 16 #HTML / CSS
HTML5实现视频直播功能思路详解
Nov 16 #HTML / CSS
基于HTML5 Canvas 实现商场监控实例详解
Nov 20 #HTML / CSS
微信浏览器左上角返回按钮拦截功能
Nov 21 #HTML / CSS
You might like
解决php接收shell返回的结果中文乱码问题
2014/01/23 PHP
PHP实现将科学计数法转换为原始数字字符串的方法
2014/12/16 PHP
PHP Opcache安装和配置方法介绍
2015/05/28 PHP
thinkPHP简单调用函数与类库的方法
2017/03/15 PHP
php实现微信企业号支付个人的方法详解
2017/07/26 PHP
PJBlog插件 防刷新的在线播放器
2006/10/25 Javascript
Jquery的each里用return true或false代替break或continue
2014/05/21 Javascript
使用AngularJS来实现HTML页面嵌套的方法
2015/06/17 Javascript
JS实现仿腾讯微博无刷新删除微博效果代码
2015/10/16 Javascript
JavaScript检测原始值、引用值、属性
2016/06/20 Javascript
BootStrap+Angularjs+NgDialog实现模式对话框
2016/08/24 Javascript
HTML页面定时跳转方法解析(2种任选)
2016/12/22 Javascript
jQuery实现对象转为url参数的方法
2017/01/11 Javascript
详解如何使用 vue-cli 开发多页应用
2017/12/16 Javascript
详解操作虚拟dom模拟react视图渲染
2018/07/25 Javascript
JavaScript实现动态生成表格
2020/08/02 Javascript
[02:42]决战东方!DOTA2亚洲邀请赛重启荣耀之争
2017/03/17 DOTA
Python实现的Kmeans++算法实例
2014/04/26 Python
python多进程共享变量
2016/04/06 Python
Python3调用微信企业号API发送文本消息代码示例
2017/11/10 Python
Python之数据序列化(json、pickle、shelve)详解
2019/08/30 Python
基于python traceback实现异常的获取与处理
2019/12/13 Python
pycharm快捷键汇总
2020/02/14 Python
6种非常炫酷的CSS3按钮边框动画特效
2016/03/16 HTML / CSS
css3边框_动力节点Java学院整理
2017/07/11 HTML / CSS
利用CSS3实现文字折纸效果实例代码
2018/07/10 HTML / CSS
浅谈html5标签css3的常用样式
2016/10/20 HTML / CSS
如何将无状态会话Bean发布为WEB服务,只有无状态会话Bean可以发布为WEB服务?
2015/12/03 面试题
什么是会话Bean
2015/05/14 面试题
《小猪家的桃花树》教学反思
2014/04/11 职场文书
小学班主任培训方案
2014/06/04 职场文书
售房协议书
2014/08/19 职场文书
2015高考寄语集锦
2015/02/27 职场文书
环卫处个人工作总结
2015/03/04 职场文书
SpringBoot工程下使用OpenFeign的坑及解决
2021/07/02 Java/Android
Ubuntu18.04下QT开发Android无法连接设备问题解决实现
2022/06/01 Java/Android