流程图(HTML5拖拽)
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Document</title>
- <style type="text/css">
- #d1 {
- width: 800px;
- height: 800px;
- border: 1px solid #ccc;
- position: relative;
- background: #fafafa;
- }
- #d1>div {
- width: 130px;
- height: 30px;
- border: 1px solid #ccc;
- border-radius: 8px;
- position: absolute;
- z-index: 2;
- text-align: center;
- line-height: 30px;
- background: #fff;
- }
- #d1>svg {
- width: 100%;
- height: 100%;
- position: absolute;
- z-index: 1
- }
- .input .point {
- position: absolute;
- border: 6px solid transparent;
- border-top: 6px solid #ccc;
- top: 0px;
- left: 58px;
- }
- .input .circle {
- position: absolute;
- width: 10px;
- height: 10px;
- border: 1px solid #ccc;
- top: -7px;
- left: 60px;
- border-radius: 50%;
- background: #fff;
- }
- .output .circle {
- position: absolute;
- width: 15px;
- height: 15px;
- border: 1px solid #ccc;
- bottom: -10px;
- left: 57px;
- border-radius: 50%;
- background: #fff;
- cursor: crosshair;
- z-index: 10;
- }
- .output .circle:hover {
- background: #FC9901;
- }
- </style>
- </head>
- <body>
- <ul class="shuiguo">
- <li draggable="true" data-name="ps1">ps1</li>
- <li draggable="true" data-name="ps2">ps2</li>
- <li draggable="true" data-name="ps3">ps3</li>
- <li draggable="true" data-name="ps4">ps4</li>
- <li draggable="true" data-name="switch">switch</li>
- </ul>
- <div id="d1">
- <svg>
- </svg>
- </div>
- <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
- <script type="text/javascript">
- var dragData = [];
- //重置拖拽后流程图展示
- function reload(isend) {
- $(function() {
- var html = "";
- var g = `
- <defs>
- <marker id="markerArrow1" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
- <path d="M0,1 L0,5 L3,3 z" fill="#CCCCCC"></path>
- </marker>
- <marker id="markerArrow2" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
- <path d="M0,1 L0,5 L3,3 z" fill="#cccdff"></path>
- </marker>
- <marker id="markerArrow3" markerWidth="10" markerHeight="10" refX="3" refY="2.6" orient="auto" markerUnits="strokeWidth">
- <path fill="#f00" d="m6.75848,4.22161c-0.13193,0.12924 -0.3468,0.12924 -0.47903,0l-3.03436,-2.97252c-0.13193,-0.12953 -0.13223,-0.33974 0,-0.46927c0.13163,-0.12953 0.3465,-0.12953 0.47933,0l3.03406,2.97223c0.13193,0.13012 0.13253,0.34003 0,0.46956l0,0l0,0zm-0.00361,-2.974l-3.03406,2.97223c-0.13253,0.12983 -0.3471,0.12983 -0.47933,0c-0.13223,-0.12924 -0.13223,-0.33915 0.0003,-0.46927l3.03406,-2.97193c0.13253,-0.12953 0.3474,-0.12953 0.47903,-0.0003c0.13253,0.12953 0.13193,0.33974 0,0.46927l0,0l0,0z"/>
- </marker>
- </defs>
- `;
- if($('svg').siblings()) { //清除$('svg')范围外的所有元素
- var prev = $('svg').siblings();
- for(var i = 0; i < prev.length; i++) {
- prev[i].remove();
- }
- }
- console.log(dragData);
- for(var i = 0; i < dragData.length; i++) { //循环dragData,重置流程图所有dom节点
- if(dragData[i] != undefined) {
- var data = dragData[i];
- html +=
- `
- <div class = "${data.name}" data-drag="1" data-id = "${data.id}" data-inx = "${data.inx}" data-iny = "${data.iny}" data-label = "${data.label}" ondragstart = "insideDrag(this)" draggable = "true" style = "transform:translate(${data.x}px,${data.y}px)">
- <span class = "${data.icon}" data-id = "${data.id}"></span>
- <span data-id = "${data.id}">${data.label}</span>
- <div class = "output">
- <span class = "circle" title = "输出" onmousedown = "noDrag(this)" onmouseup = "addDrag(this)" onmouseleave = "draw(this)" onmouseenter = "noMove()" data-id = "${data.id}"></span>
- </div>
- </div>
- `
- if(data.link.length > 0) {
- for(var j = 0; j < data.link.length; j++) {
- g +=
- `
- <g id="${data.link[j].name}">
- <path style="cursor:pointer" d = "M${data.outx} ${data.outy} Q${data.link[j].mx1} ${data.link[j].my1} ${data.link[j].mx2} ${data.link[j].my2} T${data.link[j].dx} ${data.link[j].dy}" stroke = "#CCCCCC" fill = "none" stroke-width="4" marker-end="url(#markerArrow1)"/>
- </g>
- `
- }
- }
- }
- }
- $('svg').before(html);
- $('svg').html(g);
- if(isend) {
- $('svg').on('mouseenter', "path", function() {
- $(this).attr({
- "stroke": "#cccdff",
- "marker-end": "url(#markerArrow2)",
- "marker-mid": "url(#markerArrow3)"
- })
- }).on('mouseleave', "path", function() {
- $(this).attr({
- "stroke": "#cccccc",
- "marker-end": "url(#markerArrow1)",
- "marker-mid": ""
- })
- }).on('click', "path", function() {
- var $p = $(this).parent();
- var id = $p[0].id;
- for(var i = 0; i < dragData.length; i++) {
- var data = dragData[i];
- for(var j = 0; j < data.link.length; j++) {
- if(id == data.link[j].name) {
- data.link.splice(j, 1)
- }
- }
- for(var j = 0; j < data.linked.length; j++) {
- if(id == data.linked[j].name) {
- data.linked.splice(j, 1)
- }
- }
- }
- $p.remove()
- });
- } else {
- $('svg').off('mouseenter mouseleave', "path");
- }
- console.log($('svg').siblings());
- })
- }
- //reload();
- document.getElementById('d1').ondragover = function(e) {
- e.preventDefault(); //流程图展示区阻止默认事件
- }
- var dWidth = Number($('#d1').css('width').slice(0, -2)); //流程图展示区域宽度
- console.log(dWidth);
- var dHeight = Number($('#d1').css('height').slice(0, -2)); //流程图展示区域高度
- console.log(dHeight);
- var dClient = $("#d1").offset().top; //流程图展示区偏移位置top
- var dLeft = $("#d1").offset().left; //流程图展示区偏移位置left
- console.log('顶部位置', dClient);
- console.log('左边位置', dLeft);
- //模块拖进流程图后,初始化拖拽方法
- /*
- * word:模块名称
- * name:模块数据名称
- * type:拖拽事件类型,用于判断来执行不同拖拽事件,"outside":拖拽完成,"inside":开始拖拽
- * id:模块id
- */
- function drag(word, name, type, id) {
- console.log(type);
- console.log(name);
- //在可拖动元素放置在 <div> 元素中时执行事件ondrop
- document.getElementById('d1').ondrop = function(e) {
- var sTop = $(document).scrollTop(); //文档滚动条偏移量top
- var sLeft = $(document).scrollLeft(); //文档滚动条偏移量left
- console.log('e.target', e.target.dataset.id);
- var x, y;
- console.log('e.clientX', e.clientX);
- console.log('e.clientY', e.clientY);
- if((dWidth - e.clientX + dLeft + 65) - sLeft >= 132) {
- x = e.clientX - 65 - dLeft + sLeft;
- } else {
- x = dWidth - 133;
- }
- if((e.clientX - dLeft) < 65) {
- x = 1;
- }
- if((dHeight - e.clientY + dClient + 15) - sTop >= 33) {
- y = e.clientY - 15 - dClient + sTop;
- } else {
- y = dHeight - 33;
- }
- if(e.clientY - 15 - dClient + sTop < 0) {
- y = 1;
- }
- if(type == "outside") {
- console.log('放下了');
- dragData.push({
- id: dragData.length,
- label: word,
- name: name,
- x: x, //模块相对展示区域的位移x
- y: y, //模块相对展示区域的位移y
- outx: x + 68, //模块输出点位置x/贝塞尔曲线起点x
- outy: y + 30, //模块输出点位置y/贝塞尔曲线起点y
- inx: x + 65, //模块输入点位置x
- iny: y - 1, //模块输入点位置y
- link: [], //存放由该模块连接的关联线数据数组
- linked: [], //存放由其他模块连接该模块的关联线数据数组
- dx: 0,
- dy: 0,
- mx1: 0,
- my1: 0,
- mx2: 0,
- my2: 0,
- style: name,
- draw: false,
- icon: name + "Icon"
- });
- console.log(dragData);
- reload(1);
- }
- if(type == "inside") {
- console.log(word, name, type, id);
- for(var i = 0; i < dragData.length; i++) {
- if(id == dragData[i].id) {
- dragData[i].x = x;
- dragData[i].y = y;
- dragData[i].outx = dragData[i].x + 68;
- dragData[i].outy = dragData[i].y + 30;
- dragData[i].inx = dragData[i].x + 65;
- dragData[i].iny = dragData[i].y - 1;
- console.log('dragData[i].link', dragData[i].link);
- for(let j = 0; j < dragData[i].link.length; j++) {
- dragData[i].link[j].linkId = parseFloat(dragData[i].link[j].name.split("|")[1]);
- }
- for(var k = 0; k < dragData[i].linked.length; k++) {
- console.log('dragData[i].linked[k]', dragData[i].linked[k]);
- for(let j = 0; j < dragData.length; j++) {
- if(dragData[i].linked[k].linkedNum == dragData[j].id) {
- console.log('ID一样了啊');
- for(let m = 0; m < dragData[j].link.length; m++) {
- if(dragData[i].linked[k].name == dragData[j].link[m].name) {
- console.log("名字一样了啊");
- dragData[j].link[m].dx = dragData[i].inx;
- dragData[j].link[m].dy = dragData[i].iny-10;
- dragData[j].link[m].mx1 = dragData[j].outx;
- dragData[j].link[m].my1 = dragData[j].link[m].dy > dragData[j].outy ? dragData[j].outy + (dragData[j].link[m].dy - dragData[j].outy) / 3 : dragData[j].outy - (dragData[j].link[m].dy - dragData[j].outy) / 3;
- dragData[j].link[m].mx2 = dragData[j].outx + (dragData[j].link[m].dx - dragData[j].outx) / 2,
- dragData[j].link[m].my2 = dragData[j].outy + (dragData[j].link[m].dy - dragData[j].outy) / 2
- }
- }
- }
- }
- }
- if(dragData[i].link.length > 0) {
- for(var j = 0; j < dragData[i].link.length; j++) {
- dragData[i].link[j].mx1 = dragData[i].outx;
- dragData[i].link[j].my1 = dragData[i].link[j].dy > dragData[i].outy ? dragData[i].outy + (dragData[i].link[j].dy - dragData[i].outy) / 3 : dragData[i].outy - (dragData[i].link[j].dy - dragData[i].outy) / 3;
- dragData[i].link[j].mx2 = dragData[i].outx + (dragData[i].link[j].dx - dragData[i].outx) / 2,
- dragData[i].link[j].my2 = dragData[i].outy + (dragData[i].link[j].dy - dragData[i].outy) / 2
- }
- }
- }
- }
- reload(1);
- }
- }
- }
- var shuiguo = $('.shuiguo li');
- var isondrag = 0;
- console.log(shuiguo);
- for(var i = 0; i < shuiguo.length; i++) {
- console.log(shuiguo[i]);
- shuiguo[i].ondragstart = function() {
- console.log('东完了')
- drag(this.innerHTML, this.dataset.name, 'outside');
- }
- }
- function insideDrag(item) {
- console.log(item);
- if(item.getAttribute('draggable')) {
- drag(item.dataset.label, item.className, 'inside', item.dataset.id);
- }
- }
- function noDrag(item) {
- event.preventDefault();
- event.stopPropagation();
- console.log(item.parentNode.parentNode);
- var parent = item.parentNode.parentNode;
- parent.setAttribute('draggable', false);
- for(var i = 0; i < dragData.length; i++) {
- for(var d = 0; d < dragData[i].link.length; d++) {
- if(!~dragData[i].link[d].name.indexOf("|")) {
- dragData[i].link.splice(d, 1)
- }
- }
- if(parent.dataset.id == dragData[i].id) {
- dragData[i].draw = true;
- dragData[i].link.push({
- name: parent.dataset.id + parent.className,
- dx: 0,
- dy: 0,
- mx1: 0,
- my1: 0,
- mx2: 0,
- my2: 0
- });
- $('body').on('mouseup', function(e) {
- for(var j = 0; j < dragData.length; j++) {
- if(parent.dataset.id == dragData[j].id) {
- console.log('页面抬起了');
- dragData[j].draw = false;
- var $dom = $(e.target).data("drag") ? $(e.target) : $(e.target).closest("div[data-drag]");
- if($dom.length) {
- if($dom.data("drag") && $dom[0].dataset.id != dragData[j].id) { //判断是否关联另外模块,非自己
- $('svg').unbind('mousemove');
- var name = dragData[j].link[dragData[j].link.length - 1].name + "|" + $dom[0].dataset.id + $dom[0].className;
- var isontbe = 0; //判断是否存在关联
- for(let i = 0; i < dragData.length; i++) {
- if($dom[0].dataset.id == dragData[i].id) {
- for(let c = 0; c < dragData[i].linked.length; c++) {
- if(name == dragData[i].linked[c].name) {
- isontbe = 1
- }
- }
- if(!isontbe) { //不存在时候存入linked
- dragData[i].linked.push({
- name: name,
- linkedNum: parseFloat(name)
- })
- }
- }
- }
- if(!isontbe) { //不存在时候生成link数据
- dragData[j].link[dragData[j].link.length - 1].name = name;
- dragData[j].link[dragData[j].link.length - 1].dx = Number($dom[0].dataset.inx);
- dragData[j].link[dragData[j].link.length - 1].dy = Number($dom[0].dataset.iny)-10;
- } else {
- dragData[j].link.splice(dragData[j].link.length - 1, 1);
- }
- } else {
- dragData[j].link.splice(dragData[j].link.length - 1, 1);
- }
- } else {
- dragData[j].link.splice(dragData[j].link.length - 1, 1);
- }
- $('svg').unbind('mousemove');
- reload(1);
- }
- }
- $('body').unbind('mouseup');
- })
- //reload();
- }
- }
- }
- function addDrag(item) {
- var parent = item.parentNode.parentNode;
- parent.setAttribute('draggable', true);
- for(var i = 0; i < dragData.length; i++) {
- if(parent.dataset.id == dragData[i].id) {
- dragData[i].draw = false;
- console.log(dragData[i]);
- }
- }
- }
- function draw(item) {
- var parent = item.parentNode.parentNode;
- parent.setAttribute('draggable', true);
- for(var i = 0; i < dragData.length; i++) {
- if(parent.dataset.id == dragData[i].id) {
- if(dragData[i].draw == true) {
- $('svg').mousemove(function(e) {
- console.log(parent.dataset.id);
- for(var i = 0; i < dragData.length; i++) {
- if(parent.dataset.id == dragData[i].id) {
- console.log(dragData[i]);
- if(dragData[i].link[dragData[i].link.length - 1]) {
- dragData[i].link[dragData[i].link.length - 1].dx = e.offsetX;
- dragData[i].link[dragData[i].link.length - 1].dy = e.offsetY-10;
- dragData[i].link[dragData[i].link.length - 1].mx1 = dragData[i].outx;
- dragData[i].link[dragData[i].link.length - 1].my1 = dragData[i].dy > dragData[i].outy ? dragData[i].outy + (dragData[i].dy - dragData[i].outy) / 3 : dragData[i].outy - (dragData[i].dy - dragData[i].outy) / 3;
- dragData[i].link[dragData[i].link.length - 1].mx2 = dragData[i].outx + (dragData[i].dx - dragData[i].outx) / 2,
- dragData[i].link[dragData[i].link.length - 1].my2 = dragData[i].outy + (dragData[i].dy - dragData[i].outy) / 2
- }
- //////////////////////////////////////////////
- dragData[i].dx = e.offsetX;
- dragData[i].dy = e.offsetY-10;
- dragData[i].mx1 = dragData[i].outx;
- if(dragData[i].dy > dragData[i].outy) {
- dragData[i].my1 = dragData[i].outy + (dragData[i].dy - dragData[i].outy) / 3;
- } else {
- dragData[i].my1 = dragData[i].outy - (dragData[i].dy - dragData[i].outy) / 3;
- }
- dragData[i].mx2 = dragData[i].outx + (dragData[i].dx - dragData[i].outx) / 2
- dragData[i].my2 = dragData[i].outy + (dragData[i].dy - dragData[i].outy) / 2
- }
- }
- reload();
- console.log(2333);
- })
- } else {
- $('svg').unbind('mousemove');
- }
- }
- }
- }
- function noMove() {
- $('svg').unbind('mousemove');
- }
- $('svg').mouseup(function(e) {
- console.log(e.target);
- $('svg').unbind('mousemove');
- for(var i = 0; i < dragData.length; i++) {
- dragData[i].draw = false;
- }
- console.log('起来了');
- })
- </script>
- </body>
- </html>
参考了http://blog.csdn.net/zhaoxiang66/article/details/78063271
根据大神的思路加强了功能,修复了bug
流程图(HTML5拖拽)的更多相关文章
- Html5拖拽复制
拖拽是一种常见的特性,即抓取对象以后拖到另一个位置. 在 HTML5 中,拖拽是标准的一部分,任何元素都能够拖拽. Html5拖拽非常常见的一个功能,但是大部分拖拽的案例都是一个剪切的过程, 项目中需 ...
- html5拖拽
html5拖拽一 <!DOCTYPE html> <html> <head lang="en"> <meta charset=" ...
- HTML5 拖拽复制功能的实现方法
Internet Explorer 9FirefoxOpera 12ChromeSafari 5 v1.0代码部分 <!DOCTYPE html><html><head& ...
- 每天一个JavaScript实例-html5拖拽
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- HTML5拖拽功能中 dataTransfer对象详解
有了HTML5,老板再也不用担心我们的上传了,再加上有拖拽上传是不是很酷.百度一下,有关HTML5拖拽上传的文章和实例不少,都缺不了一个至关重要的东东DataTransfer.但是详细介绍的不多,尤其 ...
- 基于html5拖拽api实现列表的拖拽排序
基于html5拖拽api实现列表的拖拽排序 html代码: <ul ondrop="drop_handler(event);" ondragover="dragov ...
- html5拖拽事件 xhr2 实现文件上传 含进度条
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- html5拖拽总结
拖拽(Drag 和 drop)是 HTML5 标准的组成部分.拖拽是一种常见的特性,即抓取对象以后拖到另一个位置. Internet Explorer 9.Firefox.Opera 12.Chrom ...
- HTML5拖拽实例
最近应该会用到,借用一下......小妹儿,你又变懒了 拖拽相关属性 draggable属性是html5的全局属性,是html5支持拖放操作的方式之一,用来表示元素是否可以被拖放,draggable有 ...
随机推荐
- java8 新特性Stream流的应用
作为一个合格的程序员,如何让代码更简洁明了,提升编码速度尼. 今天跟着我一起来学习下java 8 stream 流的应用吧. 废话不多说,直入正题. 考虑以下业务场景,有四个人员信息,我们需要根据性 ...
- 使用github作为maven仓库存放发布自己的jar包依赖 实现多个项目公共部分代码的集中,避免团队中多个项目之间代码的复制粘贴
使用github作为maven仓库存放发布自己的jar包依赖 实现多个项目公共部分代码的集中,避免团队中多个项目之间代码的复制粘贴. 1.首先在本地maven位置的配置文件setting.xml(没有 ...
- mybatis 自定义缓存 cache
缓存不管哪个框架都是显得特别的重要,今天自己测试实现了mybatis自定义缓存,从而理解mybatis缓存的工作原理. 首先缓存类要实现Cache接口:具体实现如下package com.ibatis ...
- springmvc 文件上传异步处理
springmvc3提供了文件上传异步处理功能,当文件上传时,controller不需要一直等到文件上传成功后再返回视图,而是先返回到servlet容器,待异步处理的线程完成后转向指定视图! 首先要在 ...
- java 获取请求ip,服务本地ip
/** * 获取请求IP * * @param request * @return */ public static String getRequestIpAddress(HttpServletReq ...
- Redux:异步操作
最近状态不太好,学习redux的异步操作花的时间比想象的多,这里尽量清晰简要的表述一下在redux中怎么实现异步操作. 先回顾一下同步操作: 我们用redux执行同步的时候,都是先发起一个dispat ...
- Enjoy the pain about Moloch
这echo出来的啥子嘛?意思是小姐姐有自虐倾向?可若是moloch有汉化包或翻译文件,小姐姐至于这么“享受”install的过程吗? 过程都走过了,那就记录一下吧:1.找个Ubuntu镜像,阿里云镜像 ...
- Django模板之模板变量
深度查询句点符(.)在模板语言中有特殊的含义. 当模版系统遇到点("."),它将以这样的顺序查询: 字典查询(Dictionary lookup) 属性或方法查询(Attribut ...
- scroll 方法 获取滚轴距离顶部高度
$(window).scroll(function(){ var supportPageOffset = window.pageXOffset !== undefined; // 判断是否支持page ...
- HashMap的源码浅析
一.HashMap 的数据结构 Java7 及之前主要是"数组+链表",到了 Java8 之后,就变成了"数组+链表+红黑树". 二.Java7 源码浅析: 在 ...