上周需要做一个把页面左侧列表内容拖拽到右侧区域,并且绘制成关系树的功能。
看了设计图,第一反应是用canvas绘制关系线。
吭哧吭哧搞定这个功能后,发现用canvas绘图,有一个很严重的缺陷。那就是如果左侧关系特别多,需要绘制成百上千条时,而canvas画布的宽高在写dom的时候就已声明。关系很多的情况下,无法使用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画线的方法,代码没什么难点,主要就是分析线的起始坐标麻烦一些。

利用canvas绘画二级树形结构图的更多相关文章

  1. 利用Canvas进行绘制XY坐标系

    首先来一发图 绘制XY的坐标主要是利用Canvas setLeft和setBottom功能(Canvas内置坐标的功能) 1.首先WPF中的坐标系都是从左到右,从上到下的 即左上角位置(0,0)点,所 ...

  2. Canvas绘画功能(待补充)

    由于项目的前端需要用户手绘输入,所以我们利用Canvas控件做绘画面板,并且实现了许多功能,包括手绘笔画,清空画板,上传手绘图,下载手绘图,记录用户笔画,上传背景图.以后有时间都写到这篇博客中,今天晚 ...

  3. 开发Canvas 绘画应用(三):实现对照绘画

    需求分析 在我的毕设中,提出了视图引导的概念,由两部分功能组成: (1)可以对照着图片进行绘画,即将图片以半透明的方式呈现在绘图板上,然后用户可以对照着进行绘画: (2)可以直接将简笔画图片直接拖拽到 ...

  4. 开发Canvas 绘画应用(一):搭好框架

    毕业汪今年要毕业啦,毕设做的是三维模型草图检索,年前将算法移植到移动端做了一个小应用(利用nodejs搭的服务),正好也趁此机会可以将前端的 Canvas 好好学一下~~毕设差不多做完了,现将思路和代 ...

  5. 利用 canvas 破解 某拖动验证码

    利用 canvas 破解 某拖动验证码 http://my.oschina.net/u/237940/blog/337194

  6. 利用canvas实现的中点Bresenham算法

    Bresenham提出的直线生成算法的基本原理是,每次在最大位移方向上走一步,而另一个方向是走步还是不走步取决于误差项的判别,具体的实现过程大家可以去问度娘.我主要是利用canvas画布技术实现了这个 ...

  7. 利用canvas压缩图片

    现在手机拍的照片动不动就是几M,当用户上传手机里的照片时一个消耗流量大,一个上传时间长,为了解决这个问题,就需要压缩图片: 想法:利用canvas重绘图片,保持宽高比不变,具体宽高根本具体情况而定. ...

  8. 浅谈canvas绘画王者荣耀--雷达图

    背景: 一日晚上下班的我静静的靠在角落上听着歌,这时"滴!滴!"手机上传来一阵qq消息.原来我人在问王者荣耀的雷达图在页面上如何做出来的,有人回答用canvas绘画.那么问题来了, ...

  9. java利用自定义类型对树形数据类型进行排序

    前言 为什么集合在存自定义类型时需要重写equals和hashCode? 1.先说List集合 List集合在存数据时是可以重复的但是 当我们需要判断一个对象是否在集合中存在时这样就有问题了! 因为我 ...

随机推荐

  1. H5的localStorage使用总结

    一.localstorage 的优缺点 优点: 1.localStorage 的存储大小是5M,而cookie的存储大小只有4K,解决了cookie存储空间不足的问题 2.localStorage 可 ...

  2. VisualStudioAddin2016Setup.rar

    本工具是用于Visual Studio 2010 /2012 的外接程序. 功能不太多,常用代码,引用管理等. 动态图: 下载地址: VisualStudioAddin2016Setup.rar

  3. JavaScript 的DOM操作及实例

    一.Windows对象操作 (1).用代码打开窗口:window.open("第一部分","第二部分","第三部分","第四部分& ...

  4. Java IO: 其他字符流(下)

    作者: Jakob Jenkov 译者: 李璟(jlee381344197@gmail.com) 本小节会简要概括Java IO中的PushbackReader,LineNumberReader,St ...

  5. SHELL用法七(Sed语句)

    1.SHELL编程Sed语句案例实战 1)SHELL编程四剑客之二的Sed工具,主要是用于Linux系统文本文件的编辑. 打印的,也称为非交互模式编辑器(vi|vim交互模式编辑器),Sed工具的语法 ...

  6. haproxy笔记之六:负载均衡MySQL服务的配置示例

    #--------------------------------------------------------------------- # Global settings #---------- ...

  7. JAVA 获取网页源代码保存到本地文件

    package httpget; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundExce ...

  8. test 5.1 高精度小数(10分)

    请写一个程序,输入一个分数,计算出它的小数形式.无论是否可以除尽,输出最多小数点后200位. 题目内容 由于计算机内部表达方式的限制,浮点运算都有精度问题,为了得到高精度的计算结果,就需要自己设计实现 ...

  9. 变身六次失去核心的小米Note还能火吗

    奥特曼变身有时间限制,因此我们总是希望它多变几次身,从而把小怪兽打得嗷嗷叫.但对于科技产品来说,不断推出"变身版",似乎总有江河日下.大势已去之感.三星形形色色的复仇者联盟S6版, ...

  10. lsync+rsync 实时同步(ubuntu16.04系统)

    1.同步端需要安装 lsync/rsyncapt-get install lsyncd rsync2.生成ssh公钥,粘贴到目标机器里面3.创建配置文件mkdir /etc/lsyncdcat /et ...