transformModel.vue 4.21 KB
<!--
 * @Date: 2025-03-10 16:52:35
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2025-03-19 00:57:55
 * @FilePath: /logic-flow2/src/views/api/transformModel.vue
 * @Description: 拖拽面板
-->
<template>
  <div class="container">
    <div ref="container" class="flow-container"></div>
    <div class="control-panel">
      <button @click="zoomIn">放大</button>
      <button @click="zoomOut">缩小</button>
      <button @click="moveLeft">左移</button>
      <button @click="moveRight">右移</button>
      <button @click="centerView">居中</button>
    </div>
  </div>
</template>

<script setup>
import LogicFlow from "@logicflow/core";

const container = ref(null);
let lf = null;

// 缩放画布
const zoomIn = () => {
  const { transformModel } = lf.graphModel;
  const currentZoom = transformModel.ZOOM;
  transformModel.zoom(currentZoom + 0.1);
};

const zoomOut = () => {
  const { transformModel } = lf.graphModel;
  const currentZoom = transformModel.ZOOM;
  transformModel.zoom(currentZoom - 0.1);
};

// 平移画布
const moveLeft = () => {
  const { transformModel } = lf.graphModel;
  const [x, y] = transformModel.getTranslate();
  transformModel.translate(x - 50, y);
};

const moveRight = () => {
  const { transformModel } = lf.graphModel;
  const [x, y] = transformModel.getTranslate();
  transformModel.translate(x + 50, y);
};

// 居中显示
const centerView = () => {
  const { transformModel } = lf;
  // 直接从 lf 实例获取节点

  const nodes = lf.graphModel.nodes;
  if (nodes.length === 0) return;

  // 计算所有节点的边界框
  const bounds = nodes.reduce((acc, node) => {
    const { x, y } = node;
    acc.minX = Math.min(acc.minX, x);
    acc.maxX = Math.max(acc.maxX, x);
    acc.minY = Math.min(acc.minY, y);
    acc.maxY = Math.max(acc.maxY, y);
    return acc;
  }, { minX: Infinity, maxX: -Infinity, minY: Infinity, maxY: -Infinity });

  // 计算中心点和范围
  const centerX = (bounds.minX + bounds.maxX) / 2;
  const centerY = (bounds.minY + bounds.maxY) / 2;
  const width = bounds.maxX - bounds.minX + 200; // 添加边距
  const height = bounds.maxY - bounds.minY + 100;

  // 居中显示
  transformModel.focusOn(centerX, centerY, width, height);
};

onMounted(() => {
  lf = new LogicFlow({
    container: container.value,
    grid: true,
  });

  // 监听点击画布功能
  lf.on("canvas:click", (e) => {
    console.log("Canvas clicked at:", e.x, e.y);
  });

  lf.on('node:click', (e) => {
    console.log(e);
    // 示例:HTML坐标转换为画布坐标
    console.warn(e);


    const htmlPoint = { x: 100, y: 100 };
    const { transformModel } = lf.graphModel;
    const canvasPoint = transformModel.HtmlPointToCanvasPoint(htmlPoint);
    console.log("Canvas coordinates:", canvasPoint);
  });

  lf.render({
    nodes: [
      { id: "node1", type: "rect", x: 200, y: 100 },
      { id: "node2", type: "circle", x: 400, y: 100 },
    ],
    edges: [{ id: "edge1", sourceNodeId: "node1", targetNodeId: "node2" }],
  });

  // 初始化时居中显示
  setTimeout(() => {
    const { transformModel } = lf;
    // 这里也需要修改
    const nodes = lf.graphModel.nodes;
    if (nodes.length === 0) return;

    const bounds = nodes.reduce((acc, node) => {
      const { x, y } = node;
      acc.minX = Math.min(acc.minX, x);
      acc.maxX = Math.max(acc.maxX, x);
      acc.minY = Math.min(acc.minY, y);
      acc.maxY = Math.max(acc.maxY, y);
      return acc;
    }, { minX: Infinity, maxX: -Infinity, minY: Infinity, maxY: -Infinity });

    const centerX = (bounds.minX + bounds.maxX) / 2;
    const centerY = (bounds.minY + bounds.maxY) / 2;
    const width = bounds.maxX - bounds.minX + 200;
    const height = bounds.maxY - bounds.minY + 100;

    // transformModel.focusOn(centerX, centerY, width, height);
  }, 0);


});
</script>

<style scoped>
.container {
  width: 100vw;
  height: 100vh;
  display: flex;
  flex-direction: column;
}

.flow-container {
  flex: 1;
  width: 100%;
  height: 100%;
}

.control-panel {
  position: fixed;
  top: 20px;
  left: 20px;
  display: flex;
  gap: 10px;
}

button {
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  background-color: #4a90e2;
  color: white;
  cursor: pointer;
}

button:hover {
  background-color: #357abd;
}
</style>