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 相关文章推荐
一款纯css3实现的tab选项卡的实列教程
Dec 11 HTML / CSS
使用CSS3的::selection改变选中文本颜色的方法
Sep 29 HTML / CSS
详解CSS3中强大的filter(滤镜)属性
Jun 29 HTML / CSS
详解HTML5新增标签
Nov 27 HTML / CSS
HTML5实现表单自动验证功能实例代码
Jan 11 HTML / CSS
html5文字阴影效果text-shadow使用示例
Jul 25 HTML / CSS
很酷的HTML5电子书翻页动画特效
Feb 25 HTML / CSS
html5 http的轮询和Websocket原理
Oct 19 HTML / CSS
Html5 页面适配iPhoneX(就是那么简单)
Sep 05 HTML / CSS
HTML5自定义视频播放器源码
Jan 06 HTML / CSS
uniapp+Html5端实现PC端适配
Jul 15 HTML / CSS
Html5 new XMLHttpRequest()监听附件上传进度
Jan 14 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绘图中显示不出图片的原因及解决
2014/03/05 PHP
php动态读取数据清除最右边距的方法
2017/04/12 PHP
PHP FileSystem 文件系统常用api整理总结
2019/07/12 PHP
使用Jquery获取带特殊符号的ID 标签的方法
2014/04/30 Javascript
jquery简单图片切换显示效果实现方法
2015/01/14 Javascript
如何实现移动端浏览器不显示 pc 端的广告
2015/10/15 Javascript
javascript实现的网站访问量统计代码
2015/12/20 Javascript
基于javascript编写简单日历
2016/05/02 Javascript
老司机带你解读jQuery插件开发流程
2016/05/16 Javascript
Node.js  事件循环详解及实例
2017/08/06 Javascript
ES6中Array.copyWithin()函数的用法实例详解
2017/09/16 Javascript
vue注册组件的几种方式总结
2018/03/08 Javascript
js中int和string数据类型互相转化实例
2019/01/16 Javascript
JavaScript刷新页面的几种方法总结
2019/03/28 Javascript
关于Layui Table隐藏列问题
2019/09/16 Javascript
vue 项目引入echarts 添加点击事件操作
2020/09/09 Javascript
vue-video-player视频播放器使用配置详解
2020/10/23 Javascript
Django中更新多个对象数据与删除对象的方法
2015/07/17 Python
利用Python中unittest实现简单的单元测试实例详解
2017/01/09 Python
基于Python的关键字监控及告警
2017/07/06 Python
python利用urllib实现爬取京东网站商品图片的爬虫实例
2017/08/24 Python
Python读取properties配置文件操作示例
2018/03/29 Python
set在python里的含义和用法
2019/06/24 Python
python 实现的发送邮件模板【普通邮件、带附件、带图片邮件】
2019/07/06 Python
33个Python爬虫项目实战(推荐)
2019/07/08 Python
Python math库 ln(x)运算的实现及原理
2019/07/17 Python
Python函数参数类型及排序原理总结
2019/12/19 Python
Tensorflow训练模型越来越慢的2种解决方案
2020/02/07 Python
Python之关于类变量的两种赋值区别详解
2020/03/12 Python
应届生文秘专业个人自荐信格式
2013/09/21 职场文书
电子信息专业学生自荐信
2013/11/09 职场文书
文明寄语大全
2014/04/11 职场文书
2015年外联部工作总结
2015/04/03 职场文书
外出培训学习心得体会
2016/01/18 职场文书
2016年学校安全教育月活动总结
2016/04/06 职场文书
Redis数据结构之链表与字典的使用
2021/05/11 Redis