<!--
 * @FileDescription: vue-konva
 * @Author: hcy
 * @Date: 2023-03-29
-->
<script setup lang="ts">
import { reactive, onMounted } from 'vue';
import Konva from 'konva';
import type { Points } from './types';

const state = reactive({
  stage: null as any,
  shapePath: [
    {
      name: 'test1',
      color: 'pink',
      path: [
        { x: 100, y: 100 },
        { x: 200, y: 100 },
        { x: 200, y: 200 },
        { x: 0, y: 300 },
      ],
    },
  ] as any[],
});

const stageSize = reactive({
  width: 1200, // 画布宽度
  height: 800, // 画布高度
  gridGap: 100, // 网格的间距
});

onMounted(() => {
  drawGrid();
  handleData();
  initKonva();
});

function handleData() {
  const list = state.shapePath;
  for (const iter of list) {
    iter.linePath = [];
    const path: Points[] = iter.path || [];
    for (const ite of path) {
      iter.linePath.push(ite.x);
      iter.linePath.push(ite.y);
    }
  }
}

function initKonva() {
  const list = state.shapePath;
  console.log(list);

  // 创建根节点(舞台)
  state.stage = new Konva.Stage({
    container: 'stage-container',
    width: stageSize.width,
    height: stageSize.height,
  });

  // 创建图层
  const layer = new Konva.Layer({
    name: 'my-layer',
  });

  /*
   * 创建一个组，
   * 将用于组合多个简单的形状。
   * 变换组将变换所有的简单形状作为一个单位在一起
   */
  const group = new Konva.Group({
    name: 'my-group',
    draggable: true,
  });

  // 创建图形
  // points: 点坐标的平面阵列。你应该定义它们为[x1, y1, x2, y2, x3, y3]。
  const poly = new Konva.Line({
    name: 'my-poly',
    points: [100, 100, 300, 200, 500, 200, 500, 300, 400, 400, 100, 400],
    fill: '#00D2FF', // 填充颜色
    stroke: 'black', // 边框颜色
    strokeWidth: 0, // 边框宽度
    closed: true, // 是否闭合路径
  });
  // const line = new Konva.Line({
  //   name: 'my-line',
  //   x: 0,
  //   y: 0,
  //   points: [300, 100, 500, 100, 500, 200, 300, 200],
  //   stroke: 'red',
  //   closed: true,
  // });

  // 将图形添加到组
  group.add(poly);
  // group.add(line);

  // 将组添加到图层中
  layer.add(group);
  // 将图层添加到根节点上
  state.stage.add(layer);
}

/**
 * 绘制网格线
 */
function drawGrid() {
  let canvas: any = document.getElementById('canvas-grid');
  let pen = canvas.getContext('2d');

  // 绘制网格
  const step = stageSize.gridGap;
  const h = stageSize.height;
  const w = stageSize.width;
  const w_l = w / step;
  const h_l = h / step;

  // 横着的线
  for (let i = 0; i <= h_l; i++) {
    pen.beginPath();
    pen.moveTo(0, i * step);
    pen.lineTo(w, i * step);
    pen.stroke();
  }
  // 竖着的线
  for (let i = 0; i <= w_l; i++) {
    pen.beginPath();
    pen.moveTo(i * step, 0);
    pen.lineTo(i * step, h);
    pen.stroke();
  }
}

function getAbsolutePosition() {
  const layerList: any[] = state.stage.children; // 图层List
  for (const layerItem of layerList) {
    dosomethingWithLayer(layerItem);
  }
}

/**
 * Class: Layer
 * https://konvajs.org/api/Konva.Layer.html
 * 图层的构造函数。图层绑定到它们自己的canvas元素，并用于包含组或图形。
 */
function dosomethingWithLayer(layer: any) {
  // 获取图层位置
  // const position = layer.absolutePosition();

  // 设置图层位置
  // layer.absolutePosition({
  //   x: 5,
  //   y: 10,
  // });

  const groupList: any[] = layer.children; // 组List
  for (const groupItem of groupList) {
    dosomethingWithGroup(groupItem);
  }
}

/**
 * Class: Group
 * https://konvajs.org/api/Konva.Group.html
 * 组的构造函数。组用于包含图形或其它组。
 */
function dosomethingWithGroup(group: any) {
  // 获取组的位置
  // const position = group.absolutePosition();

  // const diagramList: any[] = group.children;
  const diagramList = group.getChildren();

  // const clientRect = group.getClientRect();

  for (const diagramItem of diagramList) {
    dosomethingWithDiagram(diagramItem);
  }
}

function dosomethingWithDiagram(diagram: any) {
  const attrs = diagram.getAttrs();
  console.log('attrs', attrs);
}
</script>
<template>
  <div class="konva-main-page container-height center">
    <div>
      <q-btn
        color="primary"
        label="获取坐标位置"
        @click="getAbsolutePosition"
      />
    </div>
    <div
      class="canvas-box"
      :style="{
        width: stageSize.width + 'px',
        height: stageSize.height + 'px',
      }"
    >
      <canvas
        id="canvas-grid"
        :width="stageSize.width"
        :height="stageSize.height"
        style="position: absolute"
      ></canvas>
      <div id="stage-container"></div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.canvas-box {
  box-sizing: border-box;
  border: 1px solid #000;
  position: relative;
}
</style>
