我创建了一个codepen,它使用 jquery ui droppable(用于拖放)、jsPlumb(用于流程图)和 Panzoom(平移和缩放)来创建流程图构建器。您可以将列表项从可拖动容器(第一列)拖动到流程图(第二列),然后使用点连接项目以创建流程图。#flowchart 是启用了平移和缩放的 Panzoom 目标。这一切都很好。
但是,我希望#flowchart div 始终跨越流程图包装的整个区域,即#flowchart 应该是支持平移、缩放并且是可放置容器的无限画布。
它应该具有与流程图构建器演示相同的效果。那里的画布是无限的,您可以在其中从右列拖放项目(问题、操作、输出)。
任何关于如何实现这一点的指针(如相关事件或多个 panzoom 元素和/或 css 更改)将不胜感激。
const BG_SRC_TGT = "#2C7BE5";
const HEX_SRC_ENDPOINT = BG_SRC_TGT;
const HEX_TGT_ENDPOINT = BG_SRC_TGT;
const HEX_ENDPOINT_HOVER = "#fd7e14";
const HEX_CONNECTOR = "#39afd1";
const HEX_CONNECTOR_HOVER = "#fd7e14";
const connectorPaintStyle = {
strokeWidth: 2,
stroke: HEX_CONNECTOR,
joinstyle: "round",
outlineStroke: "white",
outlineWidth: 1
},
connectorHoverStyle = {
strokeWidth: 3,
stroke: HEX_CONNECTOR_HOVER,
outlineWidth: 2,
outlineStroke: "white"
},
endpointHoverStyle = {
fill: HEX_ENDPOINT_HOVER,
stroke: HEX_ENDPOINT_HOVER
},
sourceEndpoint = {
endpoint: "Dot",
paintStyle: {
stroke: HEX_SRC_ENDPOINT,
fill: "transparent",
radius: 4,
strokeWidth: 3
},
isSource: true,
connector: ["Flowchart", { stub: [40, 60], gap: 8, cornerRadius: 5, alwaysRespectStubs: true }],
connectorStyle: connectorPaintStyle,
hoverPaintStyle: endpointHoverStyle,
connectorHoverStyle: connectorHoverStyle,
dragOptions: {},
overlays: [
["Label", {
location: [0.5, 1.5],
label: "Drag",
cssClass: "endpointSourceLabel",
visible: false
}]
]
},
targetEndpoint = {
endpoint: "Dot",
paintStyle: {
fill: HEX_TGT_ENDPOINT,
radius: 5
},
hoverPaintStyle: endpointHoverStyle,
maxConnections: -1,
dropOptions: { hoverClass: "hover", activeClass: "active" },
isTarget: true,
overlays: [
["Label", { location: [0.5, -0.5], label: "Drop", cssClass: "endpointTargetLabel", visible: false }]
]
};
const getUniqueId = () => Math.random().toString(36).substring(2, 8);
// Setup jquery ui draggable, droppable
$("li.list-group-item").draggable({
helper: "clone",
zIndex: 100,
scroll: false,
start: function (event, ui) {
var width = event.target.getBoundingClientRect().width;
$(ui.helper).css({
'width': Math.ceil(width)
});
}
});
$('#flowchart').droppable({
hoverClass: "drop-hover",
tolerance: "pointer",
drop: function (event, ui) {
var helper = $(ui.helper);
var fieldId = getUniqueId();
var offset = $(this).offset(),
x = event.pageX - offset.left,
y = event.pageY - offset.top;
helper.find('div.field').clone(false)
.animate({ 'min-height': '40px', width: '180px' })
.css({ position: 'absolute', left: x, top: y })
.attr('id', fieldId)
.appendTo($(this)).fadeIn('fast', function () {
var field = $("#" + fieldId);
jsPlumbInstance.draggable(field, {
containment: "parent",
scroll: true,
grid: [5, 5],
stop: function (event, ui) {
}
});
field.addClass('panzoom-exclude');
var bottomEndpoints = ["BottomCenter"];
var topEndPoints = ["TopCenter"];
addEndpoints(fieldId, bottomEndpoints, topEndPoints);
jsPlumbInstance.revalidate(fieldId);
});
}
});
const addEndpoints = (toId, sourceAnchors, targetAnchors) => {
for (var i = 0; i < sourceAnchors.length; i++) {
var sourceUUID = toId + sourceAnchors[i];
jsPlumbInstance.addEndpoint(toId, sourceEndpoint, { anchor: sourceAnchors[i], uuid: sourceUUID });
}
for (var j = 0; j < targetAnchors.length; j++) {
var targetUUID = toId + targetAnchors[j];
jsPlumbInstance.addEndpoint(toId, targetEndpoint, { anchor: targetAnchors[j], uuid: targetUUID });
}
$('.jtk-endpoint').addClass('panzoom-exclude');
}
// Setup jsPlumbInstance
var jsPlumbInstance = jsPlumb.getInstance({
DragOptions: { cursor: 'pointer', zIndex: 12000 },
ConnectionOverlays: [
["Arrow", { location: 1 }],
["Label", {
location: 0.1,
id: "label",
cssClass: "aLabel"
}]
],
Container: 'flowchart'
});
// Setup Panzoom
const elem = document.getElementById('flowchart');
const panzoom = Panzoom(elem, {
excludeClass: 'panzoom-exclude',
canvas: true
});
const parent = elem.parentElement;
parent.addEventListener('wheel', panzoom.zoomWithWheel);