mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-21 13:50:20 +08:00
WIP: switch to vue-pinch-zoom
This commit is contained in:
@@ -23,6 +23,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/atkinson-hyperlegible": "^4.5.10",
|
||||
"@braks/revue-draggable": "file:/Users/mvandenb/src/galaxy/revue-draggable/braks-revue-draggable-no-transform.tgz",
|
||||
"@coddicat/vue-pinch-scroll-zoom": "^3.3.4",
|
||||
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.2.1",
|
||||
"@fortawesome/free-brands-svg-icons": "^5.15.4",
|
||||
|
||||
@@ -23,10 +23,6 @@ export default {
|
||||
lineShift: 30,
|
||||
};
|
||||
},
|
||||
beforeDestroy() {
|
||||
console.log("Destroying connector");
|
||||
// this.terminal.destroy();
|
||||
},
|
||||
computed: {
|
||||
offsetStart() {
|
||||
return 0;
|
||||
|
||||
@@ -343,7 +343,6 @@ export default {
|
||||
}
|
||||
},
|
||||
steps(newSteps, oldSteps) {
|
||||
console.log("steps watch triggered");
|
||||
this.hasChanges = true;
|
||||
this.nodeIndex = Math.max(...Object.keys(newSteps).map((k) => parseInt(k))) + 1;
|
||||
},
|
||||
@@ -363,11 +362,9 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
onUpdateStep(stepId, step) {
|
||||
console.log("updating step");
|
||||
this.steps[stepId] = step;
|
||||
},
|
||||
onUpdateStepPosition(stepId, position) {
|
||||
console.log("updating step position");
|
||||
this.steps[stepId].position = position;
|
||||
},
|
||||
onDisconnect(nodeId, inputName) {
|
||||
@@ -634,7 +631,6 @@ export default {
|
||||
this.isCanvas = true;
|
||||
return;
|
||||
}
|
||||
console.log(this.nodeIndex);
|
||||
Vue.set(this.steps, this.nodeIndex++, {
|
||||
name: name,
|
||||
content_id: contentId,
|
||||
@@ -683,14 +679,12 @@ export default {
|
||||
},
|
||||
onActiveNode(nodeId) {
|
||||
this.activeNode = this.nodes[nodeId];
|
||||
console.log("active node");
|
||||
this.$refs["right-panel"].scrollTop = 0;
|
||||
},
|
||||
getManager() {
|
||||
return this;
|
||||
},
|
||||
getNode() {
|
||||
console.log("getting node");
|
||||
return this.activeNode;
|
||||
},
|
||||
onInsertedStateMessages(insertedStateMessages) {
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<draggable-wrapper
|
||||
ref="el"
|
||||
@updatePosition="onUpdatePosition"
|
||||
@mouseup.prevent="makeActive"
|
||||
@move.prevent="onMove"
|
||||
@mouseup="makeActive"
|
||||
@move="onMove"
|
||||
:id="idString"
|
||||
:name="name"
|
||||
:node-label="label"
|
||||
@@ -249,7 +249,6 @@ export default {
|
||||
return { top: this.step.position.top + "px", left: this.step.position.left + "px" };
|
||||
},
|
||||
defaultPosition() {
|
||||
console.log("defaultPosition fires");
|
||||
const p = document.getElementById("canvas-viewport");
|
||||
const o = document.getElementById("canvas-container");
|
||||
if (p && o) {
|
||||
@@ -272,7 +271,6 @@ export default {
|
||||
});
|
||||
},
|
||||
onStopDragging() {
|
||||
console.log("onStopDragging called");
|
||||
this.$emit("stopDragging");
|
||||
},
|
||||
onUpdatePosition(position) {
|
||||
@@ -280,10 +278,8 @@ export default {
|
||||
},
|
||||
onMouseDown(e) {
|
||||
this.mouseDown = { offsetX: e.offsetX, offsetY: e.offsetY };
|
||||
console.log("mouseDownOffset", this.mouseDown);
|
||||
},
|
||||
onChange() {
|
||||
console.log("onChange triggered");
|
||||
this.$emit("onChange");
|
||||
},
|
||||
onAddInput(input, terminal) {
|
||||
@@ -384,7 +380,6 @@ export default {
|
||||
this.highlight = false;
|
||||
},
|
||||
makeActive() {
|
||||
console.log("Clicked");
|
||||
this.$emit("onActivate", this.id);
|
||||
},
|
||||
offsetVaryPosition(offsetRange) {
|
||||
|
||||
@@ -91,11 +91,6 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
terminalPosition(position) {
|
||||
console.log({
|
||||
stepId: this.nodeId,
|
||||
inputName: this.input.name,
|
||||
position,
|
||||
});
|
||||
this.$store.commit("workflowState/setInputTerminalPosition", {
|
||||
stepId: this.nodeId,
|
||||
inputName: this.input.name,
|
||||
@@ -111,16 +106,11 @@ export default {
|
||||
onRemove() {
|
||||
this.$emit("onDisconnect", this.input.name);
|
||||
},
|
||||
mouseOver(e) {
|
||||
console.log("mousOver");
|
||||
// }
|
||||
},
|
||||
mouseOver(e) {},
|
||||
mouseLeave() {
|
||||
this.showRemove = false;
|
||||
},
|
||||
onDrop(e) {
|
||||
console.log("onDrop", e);
|
||||
},
|
||||
onDrop(e) {},
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$store.commit("workflowState/deleteInputTerminalPosition", {
|
||||
|
||||
@@ -145,7 +145,6 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
terminalPosition(position) {
|
||||
console.log("updating position", position);
|
||||
this.$store.commit("workflowState/setOutputTerminalPosition", {
|
||||
stepId: this.getNode().id,
|
||||
outputName: this.output.name,
|
||||
@@ -153,7 +152,6 @@ export default {
|
||||
});
|
||||
},
|
||||
dragPosition() {
|
||||
console.log("dragPosition", this.endX);
|
||||
if (this.isDragging) {
|
||||
this.$emit("onDragConnector", this.dragPosition);
|
||||
}
|
||||
@@ -186,21 +184,12 @@ export default {
|
||||
this.deltaY = 0;
|
||||
this.$emit("stopDragging");
|
||||
},
|
||||
inputDragStart(e) {
|
||||
console.log("inputDragStart", e);
|
||||
},
|
||||
inputDragEnter(e) {
|
||||
console.log("inputDragEnter", e);
|
||||
},
|
||||
inputDragLeave(e) {
|
||||
console.log("inputDragLeave", e);
|
||||
},
|
||||
onDrop(e) {
|
||||
console.log("onDrop", e);
|
||||
},
|
||||
inputDragStart(e) {},
|
||||
inputDragEnter(e) {},
|
||||
inputDragLeave(e) {},
|
||||
onDrop(e) {},
|
||||
onChange() {
|
||||
// this.isMultiple = this.terminal.isMappedOver();
|
||||
console.log("onChange");
|
||||
// this.$emit("onChange");
|
||||
},
|
||||
onToggle() {
|
||||
|
||||
@@ -1,60 +1,59 @@
|
||||
<template>
|
||||
<div id="workflow-canvas" class="unified-panel-body workflow-canvas">
|
||||
<ZoomControl :zoom-level="zoomLevel" @onZoom="onZoomButton" />
|
||||
<div class="canvas-viewport" @dragover.prevent @drop.prevent>
|
||||
<div id="canvas-container" ref="el">
|
||||
<Draggable style="width: 100%; height: 100%" @move="onPanContainer" :apply-scale="false">
|
||||
<SvgPanZoom
|
||||
style="width: 100%; height: 100%"
|
||||
:minZoom="0.1"
|
||||
:panEnabled="false"
|
||||
:zoomEnabled="true"
|
||||
:controlIconsEnabled="false"
|
||||
:fit="false"
|
||||
:center="false"
|
||||
:on-zoom="onZoom"
|
||||
:onUpdatedCTM="onUpdatedCTM"
|
||||
@svgpanzoom="registerSvgPanZoom">
|
||||
<svg class="canvas-svg" width="100%" height="100%" ref="svg">
|
||||
<g class="zoomable">
|
||||
<raw-connector v-if="draggingConnection" :position="draggingConnection"></raw-connector>
|
||||
<terminal-connector
|
||||
v-for="connection in connections"
|
||||
:key="connection.id"
|
||||
:connection="connection"></terminal-connector>
|
||||
</g>
|
||||
</svg>
|
||||
</SvgPanZoom>
|
||||
<div class="nodeArea" :style="style">
|
||||
<!-- this div is only necessary so that we synchronize zoom and pan to the svg coordinates -->
|
||||
<WorkflowNode
|
||||
v-for="(step, key) in steps"
|
||||
:id="key"
|
||||
:key="key"
|
||||
:name="step.name"
|
||||
:type="step.type"
|
||||
:content-id="step.content_id"
|
||||
:step="step"
|
||||
:datatypes-mapper="datatypesMapper"
|
||||
:get-manager="getManager"
|
||||
:activeNodeId="activeNodeId"
|
||||
:root-offset="position"
|
||||
@pan-by="onPan"
|
||||
@stopDragging="onStopDragging"
|
||||
@onDragConnector="onDragConnector"
|
||||
@onActivate="onActivate"
|
||||
@onRemove="onRemove"
|
||||
v-on="$listeners" />
|
||||
</div>
|
||||
</Draggable>
|
||||
</div>
|
||||
<ZoomControl
|
||||
:zoom-level="zoomLevel"
|
||||
:pan="pan"
|
||||
@onZoom="onZoomButton"
|
||||
@reset-all="onResetAll"
|
||||
@update:pan="onPan" />
|
||||
<div ref="el" class="canvas-viewport" @drop.prevent>
|
||||
<PinchScrollZoom
|
||||
id="canvas-container"
|
||||
ref="zoomControl"
|
||||
:width="position.width"
|
||||
:height="position.height"
|
||||
:within="false"
|
||||
minScale="0.1"
|
||||
maxScale="10"
|
||||
throttleDelay="16"
|
||||
wheelVelocity="0.0015"
|
||||
@dragging="onDrag"
|
||||
@scaling="onScale">
|
||||
<svg class="canvas-svg" width="100%" height="100%" ref="svg">
|
||||
<g class="zoomable">
|
||||
<raw-connector v-if="draggingConnection" :position="draggingConnection"></raw-connector>
|
||||
<terminal-connector
|
||||
v-for="connection in connections"
|
||||
:key="connection.id"
|
||||
:connection="connection"></terminal-connector>
|
||||
</g>
|
||||
</svg>
|
||||
<WorkflowNode
|
||||
v-for="(step, key) in steps"
|
||||
:id="key"
|
||||
:key="key"
|
||||
:name="step.name"
|
||||
:type="step.type"
|
||||
:content-id="step.content_id"
|
||||
:step="step"
|
||||
:datatypes-mapper="datatypesMapper"
|
||||
:get-manager="getManager"
|
||||
:activeNodeId="activeNodeId"
|
||||
:root-offset="position"
|
||||
@pan-by="onPan"
|
||||
@stopDragging="onStopDragging"
|
||||
@onDragConnector="onDragConnector"
|
||||
@onActivate="onActivate"
|
||||
@onRemove="onRemove"
|
||||
v-on="$listeners" />
|
||||
</PinchScrollZoom>
|
||||
</div>
|
||||
<Minimap
|
||||
:nodes="nodes"
|
||||
:steps="steps"
|
||||
:root-offset="position"
|
||||
:scale="zoomLevel"
|
||||
:pan="currentPan"
|
||||
:pan="pan"
|
||||
@pan-by="onPan"
|
||||
@moveTo="onMoveTo" />
|
||||
</div>
|
||||
@@ -64,11 +63,11 @@ import ZoomControl from "./ZoomControl";
|
||||
import WorkflowNode from "./Node";
|
||||
import RawConnector from "./Connector";
|
||||
import TerminalConnector from "./TerminalConnector";
|
||||
import Draggable from "./Draggable.vue";
|
||||
import Minimap from "./Minimap.vue";
|
||||
import SvgPanZoom from "vue-svg-pan-zoom";
|
||||
import { reactive, ref } from "vue";
|
||||
import { useElementBounding } from "@vueuse/core";
|
||||
import PinchScrollZoom, { PinchScrollZoomEmitData } from "@coddicat/vue-pinch-scroll-zoom";
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
@@ -77,13 +76,13 @@ export default {
|
||||
return { el, position };
|
||||
},
|
||||
components: {
|
||||
Draggable,
|
||||
RawConnector,
|
||||
SvgPanZoom,
|
||||
TerminalConnector,
|
||||
WorkflowNode,
|
||||
Minimap,
|
||||
ZoomControl,
|
||||
PinchScrollZoom,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -91,6 +90,7 @@ export default {
|
||||
draggingConnection: null,
|
||||
svgpanzoom: null,
|
||||
transform: null,
|
||||
pan: { x: 0, y: 0 },
|
||||
};
|
||||
},
|
||||
props: {
|
||||
@@ -112,11 +112,42 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onWheel(e) {
|
||||
console.log("wheel event", e);
|
||||
onPan(pan) {
|
||||
console.log("onPan", pan);
|
||||
this.pan = pan;
|
||||
this.$refs.zoomControl.setData({
|
||||
scale: this.scale,
|
||||
originX: pan.x,
|
||||
originY: pan.y,
|
||||
translateX: pan.x,
|
||||
translateY: pan.y,
|
||||
});
|
||||
},
|
||||
onResetAll() {
|
||||
this.pan = { x: 0, y: 0 };
|
||||
this.setScale(1);
|
||||
this.$refs.zoomControl.setData({
|
||||
scale: 1,
|
||||
originX: 0,
|
||||
originY: 0,
|
||||
translateX: 0,
|
||||
translateY: 0,
|
||||
});
|
||||
},
|
||||
onDrag(panData) {
|
||||
console.log("panData", panData);
|
||||
this.pan = { x: panData.x, y: panData.y };
|
||||
},
|
||||
onScale(scaleData) {
|
||||
console.log("scaleData", scaleData);
|
||||
this.pan = {
|
||||
x: scaleData.translateX * scaleData.scale,
|
||||
y: scaleData.translateY * scaleData.scale,
|
||||
};
|
||||
console.log(this.pan);
|
||||
this.setScale(scaleData.scale);
|
||||
},
|
||||
onMoveTo(moveTo) {
|
||||
console.log("moving to", moveTo);
|
||||
this.svgpanzoom.pan(moveTo);
|
||||
},
|
||||
onUpdatedCTM(CTM) {
|
||||
@@ -142,14 +173,10 @@ export default {
|
||||
registerSvgPanZoom(svgpanzoom) {
|
||||
this.svgpanzoom = svgpanzoom;
|
||||
},
|
||||
onPan(pan) {
|
||||
this.svgpanzoom.panBy(pan);
|
||||
},
|
||||
onPanContainer(e) {
|
||||
this.svgpanzoom.panBy({ x: e.data.deltaX, y: e.data.deltaY });
|
||||
},
|
||||
onActivate(nodeId) {
|
||||
console.log("onNodeId", nodeId);
|
||||
if (this.activeNodeId != nodeId) {
|
||||
this.$store.commit("workflowState/setActiveNode", nodeId);
|
||||
// this.canvasManager.drawOverview();
|
||||
@@ -163,18 +190,6 @@ export default {
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
if (this.transform) {
|
||||
return `transform: matrix(${this.transform.a}, ${this.transform.b}, ${this.transform.c}, ${this.transform.d}, ${this.transform.e}, ${this.transform.f})`;
|
||||
}
|
||||
},
|
||||
currentPan() {
|
||||
if (this.transform) {
|
||||
return { x: this.transform.e, y: this.transform.f };
|
||||
} else {
|
||||
return { x: 0, y: 0 };
|
||||
}
|
||||
},
|
||||
zoomLevel() {
|
||||
return this.$store.getters["workflowState/getScale"]();
|
||||
},
|
||||
@@ -182,7 +197,6 @@ export default {
|
||||
return this.$store.getters["workflowState/getActiveNode"]();
|
||||
},
|
||||
connections() {
|
||||
console.log("connection fired");
|
||||
const connections = [];
|
||||
Object.entries(this.steps).forEach(([stepId, step]) => {
|
||||
Object.entries(step.input_connections).forEach(([input_name, outputArray]) => {
|
||||
|
||||
@@ -29,6 +29,28 @@
|
||||
size="sm"
|
||||
aria-label="Zoom In"
|
||||
@click="onZoomIn" />
|
||||
<b-button
|
||||
v-b-tooltip.hover
|
||||
role="button"
|
||||
class="fa fa-plus"
|
||||
title="Reset all"
|
||||
size="sm"
|
||||
aria-label="Reset all"
|
||||
@click="onResetAll" />
|
||||
<label
|
||||
>panX
|
||||
<input
|
||||
type="number"
|
||||
:value="pan.x"
|
||||
@change="$emit('update:pan', { x: parseInt($event.target.value), y: pan.x })" />
|
||||
</label>
|
||||
<label
|
||||
>panY
|
||||
<input
|
||||
type="number"
|
||||
:value="pan.y"
|
||||
@change="$emit('update:pan', { x: pan.x, y: parseInt($event.target.value) })" />
|
||||
</label>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
@@ -44,6 +66,9 @@ export default {
|
||||
type: Number,
|
||||
default: 1,
|
||||
},
|
||||
pan: {
|
||||
type: Object,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -54,6 +79,7 @@ export default {
|
||||
zoomDefault: 1,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
isMin() {
|
||||
return Math.round(this.zoomLevel * 100) == Math.round(this.zoomLevels[0] * 100);
|
||||
@@ -91,6 +117,9 @@ export default {
|
||||
onZoomReset() {
|
||||
this.$emit("onZoom", this.zoomDefault);
|
||||
},
|
||||
onResetAll() {
|
||||
this.$emit("reset-all");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -109,7 +109,6 @@ class Connector {
|
||||
// Resize the svg
|
||||
const svg = d3.select(this.canvas).select("svg");
|
||||
svg.attr("class", "ribbon");
|
||||
console.log(svg);
|
||||
svg.style("width", `${canvas_width}px`);
|
||||
svg.style("height", `${canvas_height}px`);
|
||||
|
||||
@@ -174,7 +173,6 @@ class Connector {
|
||||
{ x: end_x - cp_shift, y: end_y + offset_end },
|
||||
{ x: end_x, y: end_y + offset_end },
|
||||
];
|
||||
console.log("lineData", lineData);
|
||||
const lineFunction = d3.svg
|
||||
.line()
|
||||
.x(function (d) {
|
||||
|
||||
@@ -18,12 +18,10 @@ export async function fromSimple(workflow, data, appendData = false) {
|
||||
step.uuid = null;
|
||||
}
|
||||
});
|
||||
console.log("setting workflow steps");
|
||||
workflow.steps = data.steps;
|
||||
}
|
||||
|
||||
export function toSimple(workflow) {
|
||||
console.log("to Simple");
|
||||
const steps = {};
|
||||
_rectifyOutputs(workflow);
|
||||
Object.values(workflow.nodes).forEach((node) => {
|
||||
|
||||
@@ -126,7 +126,6 @@ class Terminal extends EventEmitter {
|
||||
this.emit("change");
|
||||
}
|
||||
redraw() {
|
||||
console.log("redraw");
|
||||
this.connectors.forEach((c) => {
|
||||
c.redraw();
|
||||
});
|
||||
|
||||
@@ -1112,6 +1112,11 @@
|
||||
"@citation-js/name" "^0.4.2"
|
||||
wikidata-sdk "^8.0.0"
|
||||
|
||||
"@coddicat/vue-pinch-scroll-zoom@^3.3.4":
|
||||
version "3.3.4"
|
||||
resolved "https://registry.yarnpkg.com/@coddicat/vue-pinch-scroll-zoom/-/vue-pinch-scroll-zoom-3.3.4.tgz#48f5a2a4ac09c950799e6c2ecf62bde6c6f500c1"
|
||||
integrity sha512-qGBK7TKg5Ii39u/2JnbfoBfQVaQfuVY865KR+X1vWbtaa8LWfwS+q4HgBHlV7JV1729a9zp3c9XDKIJoBVnAmA==
|
||||
|
||||
"@colors/colors@1.5.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz"
|
||||
|
||||
Reference in New Issue
Block a user