mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Switch to composables for Minimap.vue
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div ref="overview" class="workflow-overview" :style="style" aria-hidden="true">
|
||||
<div class="workflow-overview-body">
|
||||
<svg width="100%" height="100%" :viewBox="viewBox" @click="onClick">
|
||||
<svg width="100%" height="100%" :viewBox="viewBox">
|
||||
<MinimapNode
|
||||
class="mini-node"
|
||||
:node="node"
|
||||
@@ -9,11 +9,15 @@
|
||||
v-for="node of Object.values(nodes)"
|
||||
:key="node.id" />
|
||||
<rect
|
||||
class="mini-node"
|
||||
class="viewport"
|
||||
ref="rect"
|
||||
:x="visible.x"
|
||||
:y="visible.y"
|
||||
:width="visible.width"
|
||||
:height="visible.height"
|
||||
stroke-width="1%"
|
||||
rx="1%"
|
||||
fill="white"
|
||||
fill-opacity="0.5" />
|
||||
</svg>
|
||||
</div>
|
||||
@@ -22,14 +26,89 @@
|
||||
<script>
|
||||
import MinimapNode from "./MinimapNode.vue";
|
||||
import Draggable from "./Draggable.vue";
|
||||
import { reactive, ref } from "vue";
|
||||
import { computed, reactive, ref, watchEffect } from "vue";
|
||||
import { useDraggable } from "@vueuse/core";
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
setup(props, { emit }) {
|
||||
const overview = ref(null);
|
||||
const overviewPosition = reactive(useDraggable(overview, { preventDefault: true }));
|
||||
return { overview, overviewPosition };
|
||||
const overviewPosition = reactive(useDraggable(overview, { preventDefault: true, exact: true }));
|
||||
const size = ref(parseInt(localStorage.getItem("overview-size")) || 150);
|
||||
const visible = computed(() => {
|
||||
const x = props.pan.x / -props.scale;
|
||||
const y = props.pan.y / -props.scale;
|
||||
const width = props.rootOffset.width / props.scale;
|
||||
const height = props.rootOffset.bottom / props.scale;
|
||||
const rval = { x, y, width, height };
|
||||
return rval;
|
||||
});
|
||||
const bounds = computed(() => {
|
||||
let left = props.pan.x * -1;
|
||||
let right = props.rootOffset.width;
|
||||
let top = props.pan.y * -1;
|
||||
let bottom = props.rootOffset.bottom;
|
||||
let p;
|
||||
Object.values(props.steps).forEach((step) => {
|
||||
const node = props.nodes[step.id];
|
||||
p = node.position;
|
||||
left = Math.min(left, step.position.left);
|
||||
right = Math.max(right, p.right);
|
||||
top = Math.min(top, step.position.top);
|
||||
bottom = Math.max(bottom, p.bottom);
|
||||
});
|
||||
|
||||
return {
|
||||
left: left / props.scale,
|
||||
right: right / props.scale,
|
||||
top: top / props.scale,
|
||||
bottom: bottom / props.scale,
|
||||
};
|
||||
});
|
||||
const scaleFactorX = computed(() => {
|
||||
return (bounds.value.right - bounds.value.left) / size.value;
|
||||
});
|
||||
const scaleFactorY = computed(() => {
|
||||
return (bounds.value.bottom - bounds.value.top) / size.value;
|
||||
});
|
||||
const rect = ref(null);
|
||||
let startX = null;
|
||||
let startY = null;
|
||||
const rectPosition = reactive(
|
||||
useDraggable(rect, {
|
||||
preventDefault: true,
|
||||
onStart: (position, event) => {
|
||||
event.stopPropagation();
|
||||
startX = event.clientX;
|
||||
startY = event.clientY;
|
||||
},
|
||||
onMove: (position, event) => {
|
||||
const offsetX = event.clientX - startX;
|
||||
const offsetY = event.clientY - startY;
|
||||
console.log("panX", props.pan.x - offsetX * scaleFactorX.value);
|
||||
console.log("panY", props.pan.y - offsetY * scaleFactorY.value);
|
||||
emit("pan-by", { x: -offsetX * scaleFactorX.value, y: -offsetY * scaleFactorY.value });
|
||||
startX = event.clientX;
|
||||
startY = event.clientY;
|
||||
},
|
||||
// onEnd: (position, event) => {
|
||||
// startX = null;
|
||||
// startY = null;
|
||||
// },
|
||||
})
|
||||
);
|
||||
return {
|
||||
overview,
|
||||
overviewPosition,
|
||||
rect,
|
||||
rectPosition,
|
||||
size,
|
||||
visible,
|
||||
bounds,
|
||||
scaleFactorX,
|
||||
scaleFactorY,
|
||||
startX,
|
||||
startY,
|
||||
};
|
||||
},
|
||||
components: {
|
||||
Draggable,
|
||||
@@ -37,7 +116,6 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
size: 150,
|
||||
maxSize: 300,
|
||||
minSize: 50,
|
||||
};
|
||||
@@ -73,9 +151,6 @@ export default {
|
||||
type: Object,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.size = parseInt(localStorage.getItem("overview-size")) || this.size;
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
if (this.overviewPosition.x) {
|
||||
@@ -95,44 +170,23 @@ export default {
|
||||
}
|
||||
return { width: `${this.size}px`, height: `${this.size}px` };
|
||||
},
|
||||
visible() {
|
||||
// translate current rootOffset rectangle into scaled and panned space
|
||||
const x = this.pan.x / -this.scale;
|
||||
const y = this.pan.y / -this.scale;
|
||||
const width = this.rootOffset.width / this.scale;
|
||||
const height = this.rootOffset.bottom / this.scale;
|
||||
const rval = { x, y, width, height };
|
||||
return rval;
|
||||
},
|
||||
bounds() {
|
||||
let left = this.pan.x * -1;
|
||||
let right = this.rootOffset.width;
|
||||
let top = this.pan.y * -1;
|
||||
let bottom = this.rootOffset.bottom;
|
||||
let p;
|
||||
Object.values(this.steps).forEach((step) => {
|
||||
const node = this.nodes[step.id];
|
||||
p = node.position;
|
||||
left = Math.min(left, step.position.left);
|
||||
right = Math.max(right, p.right);
|
||||
top = Math.min(top, step.position.top);
|
||||
bottom = Math.max(bottom, p.bottom);
|
||||
});
|
||||
|
||||
return {
|
||||
left: left / this.scale,
|
||||
right: right / this.scale,
|
||||
top: top / this.scale,
|
||||
bottom: bottom / this.scale,
|
||||
};
|
||||
},
|
||||
viewBox() {
|
||||
return `${this.bounds.left} ${this.bounds.top} ${this.bounds.right} ${this.bounds.bottom}`;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onClick(e) {
|
||||
console.log("got click", e);
|
||||
console.log("panX", this.pan.x - offsetX * this.scaleFactorX);
|
||||
console.log("panY", this.pan.y - offsetY * this.scaleFactorY);
|
||||
// console.log("got click", e);
|
||||
// const scaledOffsetX = e.offsetX * this.scaleFactorX;
|
||||
// const scaledOffsetY = e.offsetY * this.scaleFactorY;
|
||||
// console.log("scaled offset", scaledOffsetX, scaledOffsetY);
|
||||
// const x = scaledOffsetX - this.rootOffset.width / 2;
|
||||
// const y = scaledOffsetY - this.rootOffset.height / 2;
|
||||
// console.log("adjusted offset", x, y);
|
||||
console.log("panX", props.pan.x - offsetX * scaleFactorX.value);
|
||||
this.$emit("moveTo", { x: -x, y: -y });
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<draggable-wrapper
|
||||
ref="el"
|
||||
@updatePosition="onUpdatePosition"
|
||||
@mouseup="makeActive"
|
||||
@move="onMove"
|
||||
@mouseup.prevent="makeActive"
|
||||
@move.prevent="onMove"
|
||||
:id="idString"
|
||||
:name="name"
|
||||
:node-label="label"
|
||||
|
||||
@@ -49,7 +49,14 @@
|
||||
</Draggable>
|
||||
</div>
|
||||
</div>
|
||||
<Minimap :nodes="nodes" :steps="steps" :root-offset="position" :scale="zoomLevel" :pan="currentPan" />
|
||||
<Minimap
|
||||
:nodes="nodes"
|
||||
:steps="steps"
|
||||
:root-offset="position"
|
||||
:scale="zoomLevel"
|
||||
:pan="currentPan"
|
||||
@pan-by="onPan"
|
||||
@moveTo="onMoveTo" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
@@ -105,6 +112,13 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onWheel(e) {
|
||||
console.log("wheel event", e);
|
||||
},
|
||||
onMoveTo(moveTo) {
|
||||
console.log("moving to", moveTo);
|
||||
this.svgpanzoom.pan(moveTo);
|
||||
},
|
||||
onUpdatedCTM(CTM) {
|
||||
this.transform = CTM;
|
||||
},
|
||||
@@ -157,6 +171,8 @@ export default {
|
||||
currentPan() {
|
||||
if (this.transform) {
|
||||
return { x: this.transform.e, y: this.transform.f };
|
||||
} else {
|
||||
return { x: 0, y: 0 };
|
||||
}
|
||||
},
|
||||
zoomLevel() {
|
||||
|
||||
@@ -204,6 +204,9 @@
|
||||
// this is $primary-brand / #25537b
|
||||
filter: invert(26%) sepia(75%) saturate(489%) hue-rotate(166deg) brightness(90%) contrast(89%);
|
||||
}
|
||||
.viewport {
|
||||
stroke: #25537b
|
||||
}
|
||||
}
|
||||
#input-choices-menu {
|
||||
color: black;
|
||||
|
||||
Reference in New Issue
Block a user