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伪类选择器详细介绍
Dec 24 HTML / CSS
一款纯css3实现的非常实用的鼠标悬停特效演示
Nov 05 HTML / CSS
基础的CSS3弹性盒Flexbox布局使用实例
Apr 08 HTML / CSS
利用HTML5+CSS3实现3D转换效果实例详解
May 02 HTML / CSS
html5 video标签屏蔽右键视频另存为的js代码
Nov 12 HTML / CSS
html5各种页面切换效果和模态对话框用法总结
Dec 15 HTML / CSS
HTML5制作表格样式
Nov 15 HTML / CSS
canvas如何绘制钟表的方法
Dec 13 HTML / CSS
VSCode 自定义html5模板的实现
Dec 05 HTML / CSS
html5 拖拽及用 js 实现拖拽功能的示例代码
Oct 23 HTML / CSS
使用HTML5加载音频和视频的实现代码
Nov 30 HTML / CSS
box-shadow单边阴影的实现
May 21 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工厂模式的好处
2013/06/18 PHP
thinkphp项目部署到Linux服务器上报错“模板不存在”如何解决
2016/04/27 PHP
PHP实现广度优先搜索算法(BFS,Broad First Search)详解
2017/09/16 PHP
PHP完全二叉树定义与实现方法示例
2017/10/09 PHP
JQuery中html()方法使用不当带来的陷阱
2011/04/07 Javascript
基于JavaScript 类的使用详解
2013/05/07 Javascript
js propertychange和oninput事件
2014/09/28 Javascript
jquery利用命名空间移除绑定事件的方法
2015/03/11 Javascript
Nodejs Stream 数据流使用手册
2016/04/17 NodeJs
JS制作类似选项卡切换的年历
2016/12/03 Javascript
浅谈原生JS实现jQuery的animate()动画示例
2017/03/08 Javascript
VUE Error: getaddrinfo ENOTFOUND localhost
2018/05/03 Javascript
vue中使用mxgraph的方法实例代码详解
2019/05/17 Javascript
原生Vue 实现右键菜单组件功能
2019/12/16 Javascript
微信小程序自定义yPicker组件实现省市区三级联动功能
2020/10/29 Javascript
[44:50]DOTA2上海特级锦标赛B组小组赛#2 VG VS Fnatic第二局
2016/02/26 DOTA
python实现在目录中查找指定文件的方法
2014/11/11 Python
Python处理json字符串转化为字典的简单实现
2016/07/07 Python
Python实现的选择排序算法原理与用法实例分析
2017/11/22 Python
python实现学生管理系统
2018/01/11 Python
Python实现一个服务器监听多个客户端请求
2018/04/12 Python
对Python中9种生成新对象的方法总结
2018/05/23 Python
浅谈Python2、Python3相对路径、绝对路径导入方法
2018/06/22 Python
Python3实现取图片中特定的像素替换指定的颜色示例
2019/01/24 Python
美国面料纺织品商城:Fabric.com
2017/06/28 全球购物
英国女士家居服网站:hush
2017/08/09 全球购物
The Hut英国:英国领先的豪华在线百货商店
2019/07/26 全球购物
教育系毕业生中文求职信范文
2013/10/06 职场文书
购房意向书
2014/04/01 职场文书
土建工程师岗位职责
2014/06/10 职场文书
自动化专业大学生职业生涯规划范文:爱拚才会赢
2014/09/12 职场文书
2014县政府领导班子三严三实对照检查材料思想汇报
2014/09/26 职场文书
毕业生就业推荐表导师评语
2014/12/31 职场文书
详解RedisTemplate下Redis分布式锁引发的系列问题
2021/04/27 Redis
安装Ruby和 Rails的详细步骤
2022/04/19 Ruby
Nginx如何限制IP访问只允许特定域名访问
2022/07/23 Servers