当前位置: 首页 > wzjs >正文

系统网站怎么做最好的推广平台是什么软件

系统网站怎么做,最好的推广平台是什么软件,品牌网站建设设计,有什么网站做热图HTML 工作流编辑器 以下是一个简单的工作流编辑器的HTML实现&#xff0c;包含基本的拖拽节点、连接线和可视化编辑功能&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewp…

HTML 工作流编辑器

以下是一个简单的工作流编辑器的HTML实现,包含基本的拖拽节点、连接线和可视化编辑功能:
在这里插入图片描述

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>工作流编辑器</title><style>body {font-family: Arial, sans-serif;margin: 0;padding: 0;overflow: hidden;background-color: #f5f5f5;}#toolbar {background-color: #333;color: white;padding: 10px;display: flex;justify-content: space-between;}#node-palette {width: 200px;background-color: #eee;height: calc(100vh - 60px);float: left;padding: 10px;overflow-y: auto;}.node-type {background-color: white;border: 1px solid #ccc;padding: 8px;margin-bottom: 10px;cursor: move;border-radius: 4px;text-align: center;}#editor-container {width: calc(100% - 220px);height: calc(100vh - 60px);float: right;position: relative;overflow: hidden;}#editor-surface {width: 2000px;height: 2000px;background-color: white;background-image: linear-gradient(#eee 1px, transparent 1px),linear-gradient(90deg, #eee 1px, transparent 1px);background-size: 20px 20px;position: relative;}.workflow-node {position: absolute;width: 120px;height: 60px;background-color: #4CAF50;color: white;border-radius: 6px;display: flex;align-items: center;justify-content: center;cursor: move;user-select: none;box-shadow: 0 2px 5px rgba(0,0,0,0.2);}.workflow-node.input {background-color: #2196F3;}.workflow-node.output {background-color: #f44336;}.workflow-node.decision {background-color: #FFC107;color: #333;}.connector {width: 12px;height: 12px;background-color: #333;border-radius: 50%;position: absolute;cursor: pointer;}.input-connector {left: -6px;top: 50%;transform: translateY(-50%);}.output-connector {right: -6px;top: 50%;transform: translateY(-50%);}.connection {position: absolute;pointer-events: none;z-index: -1;}button {padding: 8px 12px;margin: 0 5px;background-color: #4CAF50;color: white;border: none;border-radius: 4px;cursor: pointer;}button:hover {background-color: #45a049;}</style>
</head>
<body><div id="toolbar"><div><button id="save-btn">保存</button><button id="load-btn">加载</button><button id="clear-btn">清空</button></div><div><span id="status">就绪</span></div></div><div id="node-palette"><h3>节点类型</h3><div class="node-type input" draggable="true" data-type="input">输入节点</div><div class="node-type" draggable="true" data-type="process">处理节点</div><div class="node-type decision" draggable="true" data-type="decision">决策节点</div><div class="node-type output" draggable="true" data-type="output">输出节点</div></div><div id="editor-container"><div id="editor-surface"></div></div><script>document.addEventListener('DOMContentLoaded', function() {const editorSurface = document.getElementById('editor-surface');const nodePalette = document.getElementById('node-palette');const statusDisplay = document.getElementById('status');let selectedConnector = null;let nodes = [];let connections = [];// 从调色板拖拽节点nodePalette.querySelectorAll('.node-type').forEach(nodeType => {nodeType.addEventListener('dragstart', function(e) {e.dataTransfer.setData('text/plain', this.getAttribute('data-type'));});});// 在编辑面上放置节点editorSurface.addEventListener('dragover', function(e) {e.preventDefault();});editorSurface.addEventListener('drop', function(e) {e.preventDefault();const type = e.dataTransfer.getData('text/plain');if (!type) return;const rect = editorSurface.getBoundingClientRect();const x = e.clientX - rect.left;const y = e.clientY - rect.top;createNode(type, x, y);updateStatus(`已创建 ${type} 节点`);});// 创建节点function createNode(type, x, y) {const node = document.createElement('div');node.className = `workflow-node ${type}`;node.style.left = `${x}px`;node.style.top = `${y}px`;let label = '';switch(type) {case 'input': label = '输入'; break;case 'output': label = '输出'; break;case 'decision': label = '决策'; break;default: label = '处理';}node.textContent = label;// 添加连接点if (type !== 'input') {const inputConnector = document.createElement('div');inputConnector.className = 'connector input-connector';node.appendChild(inputConnector);inputConnector.addEventListener('mousedown', startConnection);}if (type !== 'output') {const outputConnector = document.createElement('div');outputConnector.className = 'connector output-connector';node.appendChild(outputConnector);outputConnector.addEventListener('mousedown', startConnection);}// 使节点可拖动makeDraggable(node);editorSurface.appendChild(node);nodes.push({element: node,x, y,type,id: Date.now().toString()});return node;}// 使节点可拖动function makeDraggable(element) {let offsetX, offsetY, isDragging = false;element.addEventListener('mousedown', function(e) {if (e.target.classList.contains('connector')) return;isDragging = true;const rect = element.getBoundingClientRect();offsetX = e.clientX - rect.left;offsetY = e.clientY - rect.top;element.style.zIndex = '10';e.preventDefault();});document.addEventListener('mousemove', function(e) {if (!isDragging) return;const rect = editorSurface.getBoundingClientRect();let x = e.clientX - rect.left - offsetX;let y = e.clientY - rect.top - offsetY;// 限制在编辑面内x = Math.max(0, Math.min(x, editorSurface.offsetWidth - element.offsetWidth));y = Math.max(0, Math.min(y, editorSurface.offsetHeight - element.offsetHeight));element.style.left = `${x}px`;element.style.top = `${y}px`;// 更新节点位置数据const node = nodes.find(n => n.element === element);if (node) {node.x = x;node.y = y;}// 更新连接线updateConnections();});document.addEventListener('mouseup', function() {isDragging = false;element.style.zIndex = '';});}// 开始创建连接function startConnection(e) {e.stopPropagation();selectedConnector = e.target;document.addEventListener('mousemove', drawTempConnection);document.addEventListener('mouseup', endConnection);}// 绘制临时连接线function drawTempConnection(e) {// 在实际应用中,这里会绘制一条临时连接线}// 结束连接创建function endConnection(e) {document.removeEventListener('mousemove', drawTempConnection);document.removeEventListener('mouseup', endConnection);if (!selectedConnector) return;const targetElement = document.elementFromPoint(e.clientX, e.clientY);if (!targetElement || !targetElement.classList.contains('connector')) {selectedConnector = null;return;}const sourceConnector = selectedConnector;const targetConnector = targetElement;// 检查是否可以连接(输入只能连输出,反之亦然)if ((sourceConnector.classList.contains('input-connector') && targetConnector.classList.contains('input-connector')) ||(sourceConnector.classList.contains('output-connector') && targetConnector.classList.contains('output-connector'))) {updateStatus("无法连接: 输入只能连接输出,输出只能连接输入");selectedConnector = null;return;}// 确定源和目标(输出->输入)let fromConnector, toConnector;if (sourceConnector.classList.contains('output-connector')) {fromConnector = sourceConnector;toConnector = targetConnector;} else {fromConnector = targetConnector;toConnector = sourceConnector;}createConnection(fromConnector, toConnector);selectedConnector = null;}// 创建永久连接function createConnection(fromConnector, toConnector) {const connection = document.createElement('div');connection.className = 'connection';editorSurface.appendChild(connection);const fromNode = fromConnector.parentElement;const toNode = toConnector.parentElement;const connectionObj = {element: connection,from: fromNode,to: toNode,fromConnector,toConnector};connections.push(connectionObj);updateConnection(connectionObj);updateStatus("已创建连接");}// 更新连接线位置function updateConnection(connection) {const fromRect = connection.from.getBoundingClientRect();const toRect = connection.to.getBoundingClientRect();const editorRect = editorSurface.getBoundingClientRect();const fromX = fromRect.left - editorRect.left + (connection.fromConnector.classList.contains('output-connector') ? fromRect.width : 0);const fromY = fromRect.top - editorRect.top + fromRect.height / 2;const toX = toRect.left - editorRect.left + (connection.toConnector.classList.contains('input-connector') ? 0 : toRect.width);const toY = toRect.top - editorRect.top + toRect.height / 2;// 简单的贝塞尔曲线连接const path = `M ${fromX} ${fromY} C ${(fromX + toX) / 2} ${fromY}, ${(fromX + toX) / 2} ${toY}, ${toX} ${toY}`;connection.element.innerHTML = `<svg width="${editorSurface.offsetWidth}" height="${editorSurface.offsetHeight}"><path d="${path}" stroke="#333" stroke-width="2" fill="none" marker-end="url(#arrowhead)" /></svg>`;}// 更新所有连接线function updateConnections() {connections.forEach(updateConnection);}// 工具栏按钮功能document.getElementById('save-btn').addEventListener('click', function() {const workflow = {nodes: nodes.map(node => ({id: node.id,type: node.type,x: node.x,y: node.y})),connections: connections.map(conn => ({from: nodes.findIndex(n => n.element === conn.from),to: nodes.findIndex(n => n.element === conn.to)}))};localStorage.setItem('workflow', JSON.stringify(workflow));updateStatus("工作流已保存");});document.getElementById('load-btn').addEventListener('click', function() {const saved = localStorage.getItem('workflow');if (!saved) {updateStatus("没有找到保存的工作流");return;}// 清空当前工作流editorSurface.innerHTML = '';nodes = [];connections = [];const workflow = JSON.parse(saved);// 重新创建节点workflow.nodes.forEach(nodeData => {const node = createNode(nodeData.type, nodeData.x, nodeData.y);const nodeObj = nodes[nodes.length - 1];nodeObj.id = nodeData.id;});// 重新创建连接workflow.connections.forEach(connData => {const fromNode = nodes[connData.from].element;const toNode = nodes[connData.to].element;const fromConnector = fromNode.querySelector('.output-connector');const toConnector = toNode.querySelector('.input-connector');if (fromConnector && toConnector) {createConnection(fromConnector, toConnector);}});updateStatus("工作流已加载");});document.getElementById('clear-btn').addEventListener('click', function() {editorSurface.innerHTML = '';nodes = [];connections = [];updateStatus("工作流已清空");});// 状态更新function updateStatus(message) {statusDisplay.textContent = message;setTimeout(() => {if (statusDisplay.textContent === message) {statusDisplay.textContent = "就绪";}}, 3000);}// 添加箭头标记定义const svgDefs = document.createElementNS('http://www.w3.org/2000/svg', 'svg');svgDefs.style.position = 'absolute';svgDefs.style.width = '0';svgDefs.style.height = '0';svgDefs.style.overflow = 'hidden';const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');const marker = document.createElementNS('http://www.w3.org/2000/svg', 'marker');marker.setAttribute('id', 'arrowhead');marker.setAttribute('markerWidth', '10');marker.setAttribute('markerHeight', '7');marker.setAttribute('refX', '9');marker.setAttribute('refY', '3.5');marker.setAttribute('orient', 'auto');const arrow = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');arrow.setAttribute('points', '0 0, 10 3.5, 0 7');arrow.setAttribute('fill', '#333');marker.appendChild(arrow);defs.appendChild(marker);svgDefs.appendChild(defs);document.body.appendChild(svgDefs);});</script>
</body>
</html>

功能说明

这个工作流编辑器包含以下功能:

  1. 节点调色板:提供不同类型的节点(输入、处理、决策、输出)
  2. 拖拽创建节点:可以从调色板拖拽节点到编辑区域
  3. 节点连接:可以通过连接点创建节点之间的连线
  4. 节点拖动:可以拖动已创建的节点
  5. 基本工具栏:包含保存、加载和清空功能
  6. 状态显示:显示当前操作状态

扩展建议

要使这个编辑器更实用,你可以考虑添加:

  1. 节点属性编辑功能
  2. 更复杂的连接线样式(带箭头、标签等)
  3. 撤销/重做功能
  4. 工作流验证
  5. 导出为JSON或其他格式
  6. 缩放和平移功能
  7. 网格对齐和吸附功能

这个示例使用了纯HTML/CSS/JavaScript实现,对于更复杂的工作流编辑器,你可能需要考虑使用专门的库如jsPlumb、GoJS或React Flow等。

http://www.dtcms.com/wzjs/470867.html

相关文章:

  • dw使用模板做网站教程全网营销外包
  • 深圳最新疫情防控动态沈阳专业seo排名优化公司
  • 网站建设算什么行业人力资源培训网
  • 如何设计服装网站规划网络广告营销案例
  • html网站的规划与建设6百度信息流广告推广
  • 重庆响应式网站网络销售有哪些
  • 阜新公司做网站网络营销外包网络推广
  • 张家港早晨网站建设竞价托管哪家便宜
  • 微信小程序上线需要多少钱汕头seo建站
  • 免费软件的源代码公开吗东莞百度快速优化排名
  • 做网站 站内搜索引擎如何进行百度推广
  • 做网站规避什么百度收录站长工具
  • 网站中的ppt链接怎么做太原自动seo
  • 宁波住房和城乡建设培训网站扬州整站seo
  • 网站建设时间表301313龙虎榜
  • 梁山网站建设哪家好营销型网站建设哪家好
  • 临平做网站企业网站优化价格
  • 北京企业建设网站成都网站设计公司
  • 自己电脑做服务器搭建网站如何创建个人网页
  • 酷家乐网站做墙裙教程百度广告销售
  • 快速搭建小程序汕头seo收费
  • 肇庆网站制作系统谷歌网站网址
  • 福田网站制作各大搜索引擎入口
  • wordpress 首页logoseo搜索引擎优化试题及答案
  • 上国外网站的host推广app大全
  • 做网站做丝袜美女的能行吗武汉百度推广外包
  • 手机网站建设域名空间做互联网项目怎么推广
  • 网站建设工作会议.企业网站推广有哪些
  • 网站没有备案信息该怎么做小说网站排名免费
  • 做网站工作怀孕2023年8月新冠疫情