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

const state = reactive({
  stage: null as any,
  layer: null as any,
  group: null as any,
  shape: null as any,
  boundingBox: null as any,
  box: null as any,
});

const stageSize = reactive({
  width: 1200,
  height: 800,
});

// const rectConfig1 = reactive({
//   x: 0,
//   y: 0,
//   width: 100,
//   height: 100,
//   fill: 'red',
//   draggable: true,
//   dragBoundFunc: function (pos: any) {
//     let newY = pos.y < 0 ? 0 : pos.y;
//     let newX = pos.x < 0 ? 0 : pos.x;
//     if (newX >= 1200 - 100) {
//       newX = 1200 - 100;
//     }
//     if (newY >= 800 - 100) {
//       newY = 800 - 100;
//     }

//     // if (newX <= 300 && newY > 0 && newY <= 200) {
//     //   newX = 300;
//     // }
//     return {
//       x: newX,
//       y: newY,
//     };
//   },
// });
// const rectConfig2 = reactive({
//   x: 100,
//   y: 100,
//   width: 200,
//   height: 100,
//   fill: '#204969',
//   draggable: true,
// });
// const rectConfig3 = reactive({
//   x: 200,
//   y: 200,
//   width: 100,
//   height: 200,
//   fill: '#b689b0',
// });

onMounted(() => {
  state.stage = new Konva.Stage({
    container: 'stage-container',
    width: stageSize.width,
    height: stageSize.height,
  });

  state.layer = new Konva.Layer();
  state.stage.add(state.layer);

  for (var i = 0; i < 10; i++) {
    state.layer.add(createShape());
  }

  state.layer.on('dragmove', layerDragmove);
});

function createShape() {
  state.group = new Konva.Group({
    x: Math.random() * stageSize.width,
    y: Math.random() * stageSize.height,
    draggable: true,
  });
  state.shape = new Konva.Rect({
    width: 60 + Math.random() * 30,
    height: 60 + Math.random() * 30,
    fill: 'grey',
    // rotation: 360 * Math.random(),
    name: 'fillShape',
  });
  state.group.add(state.shape);

  state.boundingBox = state.shape.getClientRect({ relativeTo: state.group });

  state.box = new Konva.Rect({
    x: state.boundingBox.x,
    y: state.boundingBox.y,
    width: state.boundingBox.width,
    height: state.boundingBox.height,
    stroke: 'black',
    strokeWidth: 10,
  });
  state.group.add(state.box);
  return state.group;
}
// 是否相交
function haveIntersection(r1: any, r2: any) {
  // r1当前循环的可视矩形区域 r2当前移动目标的可视矩形区域
  let obj: any = {
    a: false,
    b: false,
    c: false,
    d: false,
  };
  // let pos: any = {
  //   x: r2.x + r2.width,
  //   y: r2.y + r2.height,
  // };
  if (r2.x > r1.x + r1.width) {
    obj.a = true;
  }
  if (r2.x + r2.width < r1.x) {
    obj.b = true;
  }
  if (r2.y > r1.y + r1.height) {
    obj.c = true;
  }
  if (r2.y + r2.height < r1.y) {
    obj.d = true;
  }
  // console.log('obj', obj, obj.a || obj.b || obj.c || obj.d);

  return {
    value: !(obj.a || obj.b || obj.c || obj.d),
    // pos,
  };

  // return !(
  //   r2.x > r1.x + r1.width ||
  //   r2.x + r2.width < r1.x ||
  //   r2.y > r1.y + r1.height ||
  //   r2.y + r2.height < r1.y
  // );
}
function layerDragmove(e: any) {
  let target = e.target;
  let targetRect = e.target.getClientRect();
  state.layer.children.forEach(function (group: any) {
    // do not check intersection with itself
    // 不检查与自身相交
    if (group._id == target._id) {
      return;
    }
    // r1当前循环目标的可视矩形区域 r2当前移动目标的可视矩形区域
    let r1 = group.getClientRect();
    let r2 = targetRect;
    let result = haveIntersection(r1, r2);

    if (result.value) {
      // 有碰撞
      console.log('1', target);
      if (r2.x < r1.x + r1.width / 2) {
        if (r2.x + r2.width <= r1.x + r1.width / 2) {
          // 10边框宽度
          target.x(r1.x - r2.width + 10);
        } else {
          if (r1.y + r1.height / 2 >= r2.y) {
            // 10边框宽度
            target.y(r1.y - r2.height + 10);
          } else if (r1.y + r1.height / 2 < r2.y) {
            target.y(r1.y + r1.height);
          }
        }
      } else {
        target.x(r1.x + r1.width);
      }
      // target.x(100);
      // target.y(100);
      group.findOne('.fillShape').fill('red');
    } else {
      group.findOne('.fillShape').fill('grey');
    }
  });
}
</script>
<template>
  <div class="konva-main-page container-height center">
    <div class="canvas-box">
      <div id="stage-container"></div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.konva-main-page {
}
.canvas-box {
  box-sizing: border-box;
  width: 1200px;
  height: 800px;
  border: 1px solid #000;
  background: pink;
}
</style>
