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教程(7):CSS3嵌入字体
Apr 02 HTML / CSS
实例讲解CSS3中的box-flex弹性盒属性布局
Jun 09 HTML / CSS
基于CSS3 animation动画属性实现轮播图效果
Sep 12 HTML / CSS
Bootstrap 学习分享
Nov 12 HTML / CSS
HTML5之HTML元素扩展(上)—新增加的元素及使用概述
Jan 31 HTML / CSS
仿CSDN Blog返回页面顶部功能实现原理及代码
Jun 30 HTML / CSS
5分钟实现Canvas鼠标跟随动画背景
Nov 18 HTML / CSS
video下autoplay属性无效的解决方法(添加muted属性)
May 19 HTML / CSS
使用Html5 Stream开发实时监控系统
Jun 02 HTML / CSS
Canvas获取视频第一帧缩略图的实现
Nov 11 HTML / CSS
HTML+CSS制作心跳特效的实现
May 26 HTML / CSS
HTML基础详解(上)
Oct 16 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 编程请选择正确的文本编辑软件
2006/12/21 PHP
PHP Memcached + APC + 文件缓存封装实现代码
2010/03/11 PHP
AMFPHP php远程调用(RPC, Remote Procedure Call)工具 快速入门教程
2010/05/10 PHP
PHP中改变图片的尺寸大小的代码
2011/07/17 PHP
php IP转换整形(ip2long)的详解
2013/06/06 PHP
WordPress中使主题支持小工具以及添加插件启用函数
2015/12/22 PHP
php实现文件上传及头像预览功能
2017/01/15 PHP
Yaf框架封装的MySQL数据库操作示例
2019/03/06 PHP
接收键盘指令的脚本
2006/06/26 Javascript
jQuery学习笔记之jQuery的动画
2010/12/22 Javascript
JS 实现导航栏悬停效果(续2)
2013/09/24 Javascript
深入学习JavaScript中的Rest参数和参数默认值
2015/07/28 Javascript
jQuery解决input超多的表单提交
2015/08/10 Javascript
AngularJs中Bootstrap3 datetimepicker使用实例
2016/12/13 Javascript
ComboBox(下拉列表框)通过url加载调用远程数据的方法
2017/08/06 Javascript
ES6中字符串的使用方法扩展
2019/06/04 Javascript
ElementUI Tag组件实现多标签生成的方法示例
2019/07/08 Javascript
vue内置组件keep-alive事件动态缓存实例
2020/10/30 Javascript
[03:54]DOTA2英雄梦之声_第06期_昆卡
2014/06/23 DOTA
[07:09]2014DOTA2国际邀请赛-Newbee再次发威成功晋级决赛
2014/07/19 DOTA
[04:40]2016国际邀请赛中国区预选赛全程TOP10镜头集锦
2016/07/01 DOTA
[10:54]Team Spirit vs Navi
2018/06/07 DOTA
[52:52]完美世界DOTA2联赛PWL S3 LBZS vs access 第一场 12.10
2020/12/13 DOTA
Python中非常实用的一些功能和函数分享
2015/02/14 Python
浅谈python 导入模块和解决文件句柄找不到问题
2018/12/15 Python
提升Python程序性能的7个习惯
2019/04/14 Python
django有外键关系的两张表如何相互查找
2020/02/10 Python
python+pygame实现坦克大战小游戏的示例代码(可以自定义子弹速度)
2020/08/11 Python
英国皇家邮政海外旗舰店:Royal Mail
2018/02/21 全球购物
英国亚马逊官方网站:Amazon.co.uk
2019/08/09 全球购物
Vivo俄罗斯官方在线商店:中国智能手机品牌
2019/10/04 全球购物
大学生职业生涯规划方案
2014/01/03 职场文书
五一服装活动方案
2014/01/11 职场文书
食品厂厂长岗位职责
2014/01/30 职场文书
2015年高三年级组工作总结
2015/07/21 职场文书
长辈生日祝福语大全(72句)
2019/08/09 职场文书