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实现一个div设置多张背景图片及background-image属性实例演示
Aug 10 HTML / CSS
CSS3制作日历实现代码
Jan 21 HTML / CSS
CSS3中几个新增加的盒模型属性使用教程
Mar 01 HTML / CSS
简单掌握CSS3中resize属性的用法
Apr 01 HTML / CSS
使用CSS3制作版头动画效果
Dec 24 HTML / CSS
html5 兼容IE6结构的实现代码
May 14 HTML / CSS
html5-Canvas可以在web中绘制各种图形
Dec 26 HTML / CSS
HTML5仿微信聊天界面、微信朋友圈实例代码
Jan 29 HTML / CSS
浅谈Html5多线程开发之WebWorkers
May 02 HTML / CSS
HTML5自定义属性的问题分析
Aug 16 HTML / CSS
简洁自适应404页面HTML好看的404源码
Dec 16 HTML / CSS
浅谈CSS不规则边框的生成方案
May 25 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实现定时生成HTML网站首页实例代码
2008/11/20 PHP
PHP 危险函数全解析
2009/09/09 PHP
php制作的简单验证码识别代码
2016/01/26 PHP
PHP实现的DES加密解密封装类完整实例
2017/04/29 PHP
PHP解析url并得到url参数方法总结
2018/10/11 PHP
JavaScript判断对象是否为数组
2015/12/22 Javascript
AngularJs学习第五篇从Controller控制器谈谈$scope作用域
2016/06/08 Javascript
Js 获取、判断浏览器版本信息的简单方法
2016/08/08 Javascript
使用BootStrap建立响应式网页——通栏轮播图(carousel)
2016/12/21 Javascript
AngularJs 延时器、计时器实例代码
2017/09/16 Javascript
VUE脚手架具体使用方法
2019/05/20 Javascript
小程序中canvas的drawImage方法参数使用详解
2019/07/04 Javascript
layui table动态表头 改变表格头部 重新加载表格的方法
2019/09/21 Javascript
asyncio 的 coroutine对象 与 Future对象使用指南
2016/09/11 Python
Flask框架的学习指南之制作简单blog系统
2016/11/20 Python
python做量化投资系列之比特币初始配置
2018/01/23 Python
解决安装python库时windows error5 报错的问题
2018/10/21 Python
对于Python深浅拷贝的理解
2019/07/29 Python
Django ModelForm操作及验证方式
2020/03/30 Python
基于Python脚本实现邮件报警功能
2020/05/20 Python
利用CSS3把图片变成灰色模式的实例代码
2016/09/06 HTML / CSS
详解CSS3+JS完美实现放大镜模式
2020/12/03 HTML / CSS
HTML5使用Audio标签实现歌词同步的效果
2016/03/17 HTML / CSS
联想韩国官网:Lenovo Korea
2018/05/10 全球购物
为什么说Ruby是一种真正的面向对象程序设计语言
2012/10/30 面试题
致垒球运动员加油稿
2014/02/16 职场文书
群众路线教育实践活动思想汇报(2014特荐篇)
2014/09/16 职场文书
公司财务会计主管应聘求职信
2014/09/26 职场文书
烛光里的微笑观后感
2015/06/17 职场文书
公司岗位说明书
2015/10/08 职场文书
创业计划书之牛肉汤快餐店
2019/10/08 职场文书
MySQL时间设置注意事项的深入总结
2021/05/06 MySQL
Python Flask搭建yolov3目标检测系统详解流程
2021/11/07 Python
Python OpenCV形态学运算示例详解
2022/04/07 Python
cypress测试本地web应用
2022/06/01 Javascript
vue实现在data里引入相对路径
2022/06/05 Vue.js