Merge pull request #15754 from ElectronicBlueberry/workflow-editor-performance

[23.0] Workflow Editor Minimap Performance
This commit is contained in:
Dannon
2023-03-10 08:58:54 -05:00
committed by GitHub
@@ -1,6 +1,7 @@
<script lang="ts" setup>
import { computed, onMounted, ref, unref, watch } from "vue";
import { useAnimationFrame } from "@/composables/sensors/animationFrame";
import { useAnimationFrameThrottle } from "@/composables/throttle";
import { useWorkflowStateStore } from "@/stores/workflowEditorStateStore";
import { AxisAlignedBoundingBox, Transform } from "./modules/geometry";
import { useDraggable, type UseElementBoundingReturn } from "@vueuse/core";
@@ -22,21 +23,41 @@ const emit = defineEmits<{
const stateStore = useWorkflowStateStore();
/** bounding box following the viewport */
const viewportBounds = computed(() => {
const bounds = new AxisAlignedBoundingBox();
bounds.x = -props.viewportPan.x / props.viewportScale;
bounds.y = -props.viewportPan.y / props.viewportScale;
bounds.width = unref(props.viewportBounds.width) / props.viewportScale;
bounds.height = unref(props.viewportBounds.height) / props.viewportScale;
return bounds;
});
/** reference to the main canvas element */
const canvas: Ref<HTMLCanvasElement | null> = ref(null);
let redraw = false;
// it is important these throttles are defined before useAnimationFrame,
// so that they are executed first in the frame loop
const { throttle: viewportThrottle } = useAnimationFrameThrottle();
const { throttle: dragThrottle } = useAnimationFrameThrottle();
/** bounding box following the viewport */
const viewportBounds = ref(new AxisAlignedBoundingBox());
watch(
() => ({
x: props.viewportPan.x,
y: props.viewportPan.y,
scale: props.viewportScale,
width: unref(props.viewportBounds.width),
height: unref(props.viewportBounds.height),
}),
({ x, y, scale, width, height }) => {
redraw = true;
viewportThrottle(() => {
const bounds = viewportBounds.value;
bounds.x = -x / scale;
bounds.y = -y / scale;
bounds.width = width / scale;
bounds.height = height / scale;
viewportBounds.value = bounds;
});
}
);
/** bounding box encompassing all nodes in the workflow */
const aabb = new AxisAlignedBoundingBox();
let aabbChanged = false;
@@ -67,8 +88,7 @@ function recalculateAABB() {
}
}
// redraw if any of these props change
watch(viewportBounds, () => (redraw = true));
// redraw if any steps change
watch(
props.steps,
() => {
@@ -244,18 +264,20 @@ useDraggable(canvas, {
}
},
onMove: (position, event) => {
if (!dragViewport || Object.values(props.steps).length === 0) {
return;
}
dragThrottle(() => {
if (!dragViewport || Object.values(props.steps).length === 0) {
return;
}
// minimap coordinates to global coordinates, without translation
const [x, y] = canvasTransform
.resetTranslation()
.inverse()
.scale([scaleFactor.value, scaleFactor.value])
.apply([-event.movementX, -event.movementY]);
// minimap coordinates to global coordinates, without translation
const [x, y] = canvasTransform
.resetTranslation()
.inverse()
.scale([scaleFactor.value, scaleFactor.value])
.apply([-event.movementX, -event.movementY]);
emit("panBy", { x, y });
emit("panBy", { x, y });
});
},
onEnd(position, event) {
// minimap coordinates to global coordinates