<template>
  <view id="app" :class="{ done: done }">
    <view>
      <h1>{{ title }}</h1>
      <button @click="random">
        动起来
      </button>
    </view>
    <view class="wrapper flex-all-center" ref="wrapperRef">
      <view
        class="container"
        :style="{ width: containerW + 'px', height: containerH + 'px' }"
      >
        <view
          class="item flex-all-center"
          v-for="item in showList"
          :key="item.count"
          :style="{
            left: item.left + 'px',
            top: item.top + 'px',
            height: item.height + 'px',
            width: item.width + 'px',
            background: item.color,
          }"
        >
          <view class="content">
            <view class="title">{{ item.title }}</view>
            <view class="count">{{ item.count }}</view>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>
<script>
export default {
  data() {
    return {
      containerW: 0,
      containerH: 0,
      done: false,
      title: "泡泡堂",
      list: [],
      showList: [],
      groups: [],
      colors: [
        "red",
        "green",
        "purple",
        "pink",
        "orange",
        "yellowgreen",
        "greenyellow",
      ],
      layout: [
        {
          type: "group",
          name: "group1",
          direction: "horizontal", //左右
          height: "30%",
          width: "100%",
          children: [
            {
              type: "group",
              name: "group2",
              direction: "portrait", //上下
              width: "40%",
              height: "100%",
              children: [
                {
                  type: "node",
                  index: 2,
                },
                {
                  type: "node",
                  index: 3,
                },
              ],
            },
            {
              type: "group",
              name: "group3",
              direction: "portrait", // 上下
              width: "60%",
              height: "100%",
              children: [
                {
                  type: "group",
                  name: "group4",
                  width: "100%",
                  height: "80%",
                  direction: "horizontal",
                  children: [
                    {
                      type: "node",
                      index: 1,
                    },
                    {
                      type: "node",
                      index: 0,
                    },
                  ],
                },
                {
                  type: "group",
                  name: "group5",
                  direction: "portrait", // 上下
                  width: "100%",
                  height: "20%",
                  children: [
                    {
                      type: "node",
                      index: 4,
                    },
                  ],
                },
              ],
            },
          ],
        },
        {
          type: "group",
          name: "group6",
          direction: "horizontal", //左右
          height: "30%",
          width: "100%",
          children: [
            {
              type: "group",
              name: "group7",
              width: "50%",
              height: "100%",
              direction: "portrait",
              children: [
                {
                  type: "node",
                  index: 5,
                },
                {
                  type: "node",
                  index: 7,
                },
              ],
            },
            {
              type: "group",
              name: "group8",
              width: "50%",
              height: "100%",
              direction: "horizontal",
              children: [
                {
                  type: "node",
                  index: 8,
                },
                {
                  type: "node",
                  index: 6,
                },
              ],
            },
          ],
        },
        {
          type: "group",
          name: "group9",
          width: "100%",
          height: "40%",
          direction: "horizontal",
          children: [
            {
              type: "group",
              name: "group9",
              width: "30%",
              height: "100%",
              direction: "portrait",
              children: [
                {
                  type: "node",
                  index: 9,
                },
                {
                  type: "node",
                  index: 11,
                },
                {
                  type: "node",
                  index: 10,
                },
              ],
            },
            {
              type: "group",
              name: "group9",
              width: "70%",
              height: "100%",
              direction: "portrait",
              children: [
                {
                  type: "group",
                  name: "group10",
                  width: "100%",
                  height: "30%",
                  direction: "horizontal",
                  children: [
                    {
                      type: "node",
                      index: 12,
                    },
                    {
                      type: "node",
                      index: 16,
                    },
                  ],
                },
                {
                  type: "group",
                  name: "group11",
                  width: "100%",
                  height: "70%",
                  direction: "horizontal",
                  children: [
                    {
                      type: "group",
                      name: "group11",
                      width: "50%",
                      height: "100%",
                      direction: "horizontal",
                      children: [
                        {
                          type: "node",
                          index: 17,
                        },
                      ],
                    },
                    {
                      type: "group",
                      name: "group11",
                      width: "50%",
                      height: "100%",
                      direction: "portrait",
                      children: [
                        {
                          type: "node",
                          index: 13,
                        },
                        {
                          type: "node",
                          index: 14,
                        },
                        {
                          type: "node",
                          index: 15,
                        },
                      ],
                    },
                  ],
                },
              ],
            },
          ],
        },
      ],
    };
  },

  onShow() {},
  mounted() {
    this.$nextTick(() => {
      console.log(this.$refs.wrapperRef);
      // this.containerW = this.$refs.wrapperRef.clientWidth;
      this.containerW = 230;
			// this.containerH  = '1380rpx'
      this.containerH = this.containerW * 2;
      console.log(this.containerW, this.containerH);
      this.initList();
      this.initPosition();
    });
  },
  methods: {
    percentToPx(cur, compared) {
      if (typeof cur !== "string" || !cur.includes("%")) return cur;
      return (compared * parseFloat(cur)) / 100;
    },
    getRandom(min = 1, max = 10000) {
      return Math.floor(Math.random() * (max - min) + min);
    },
    initList() {
      this.list = [];
      for (let i = 0; i < 18; i++) {
				let item = {}
        item = Object.create(null);
        item.title = `标题${i}`;
        item.color = this.colors[this.getRandom(0, this.colors.length - 1)];
        item.no = i;
        item.count = this.getRandom();
        item.width = this.containerW / 3;
        item.height = this.containerW / 3;
        this.list.push(item);
      }
    },
    initPosition() {
      this.showList = this.list.map((item, index) => {
        return {
          left: ((index % 3) * this.containerW) / 3,
          top: (Math.floor(index / 3) * this.containerW) / 3,
          ...item,
        };
      });
    },
    random() {
      const parent = {
        left: 0,
        top: 0,
        name: "group0",
        width: this.percentToPx("100%", this.containerW),
        height: this.percentToPx("100%", this.containerH),
        direction: "portrait",
        childrenLength: this.layout.length,
      };
      this.groups = [parent];
      this.getPosition(this.layout, parent);
      this.showList = this.list;
      this.done = true;
    },
    getPosition(layout, parent) {
      // 纵向的，只需要计算高度，如果只有一个元素，则高度100%
      // 横向的，只需要计算宽度，如果只有一个元素，则宽度100%
      // 如果type为node，则表明是最小单位了，则需要根据index获得数量，然后往上一层和同级别的组进行比较得出宽（横向）高（纵向）
      // 但是所有的宽高都计算完之后，还是百分比的，如何计算具体位置呢
      const list = this.list;
      layout.forEach((item, index) => {
        if (item.type === "group") {
          const current = {
            left: 0,
            top: 0,
            name: item.name,
            width: this.percentToPx(item.width, parent.width),
            height: this.percentToPx(item.height, parent.height),
            direction: item.direction,
            childrenLength: item.children.length,
          };
          const preItem = index === 0 ? null : layout[index - 1];
          // 组
          // 横纵向分布都按照设置来
          if (parent.direction === "horizontal") {
            current.left =
              index === 0
                ? parent.left
                : preItem.left + this.percentToPx(preItem.width, parent.width);
            current.top = parent.top;
          } else {
            current.left = parent.left;
            current.top =
              index === 0
                ? parent.top
                : preItem.top + this.percentToPx(preItem.height, parent.height);
          }
          item.left = current.left;
          item.top = current.top;
          this.groups.push(current);
          item.nodeTotal = 0;
          if (item.children && item.children.length > 0) {
            if (item.children[0].type === "node") {
              item.children.forEach((v) => {
                item.nodeTotal += list[v.index].count;
              });
            }
            current.nodeTotal = item.nodeTotal;
            this.getPosition(item.children, current);
          }
        } else {
          const listItem = list[item.index];
          const preItem = index === 0 ? null : list[layout[index - 1].index];
          if (parent.direction === "horizontal") {
            // 节点横向排布，计算宽度
            listItem.left =
              index === 0
                ? parent.left
                : preItem.left + this.percentToPx(preItem.width, parent.width); // TODO: 需要计算上一个元素的left + width: ;
            listItem.top = parent.top;
            listItem.width = this.percentToPx(
              (listItem.count / parent.nodeTotal) * 100 + "%",
              parent.width
            );
            listItem.height = this.percentToPx("100%", parent.height);
          } else if (parent.direction === "portrait") {
            // 节点横向排布，计算宽度
            listItem.left = parent.left;
            listItem.top =
              index === 0
                ? parent.top
                : preItem.top + this.percentToPx(preItem.height, parent.height); // TODO: 需要计算上一个元素的left + width: ;
            listItem.width = this.percentToPx("100%", parent.width);
            listItem.height = this.percentToPx(
              (listItem.count / parent.nodeTotal) * 100 + "%",
              parent.height
            );
          }
          listItem.name = `node${item.index}`;
        }
      });
    },
  },
  onLoad() {},
  onHide() {},
};
</script>

<style lang="scss" scoped>
* {
  margin: 0;
  padding: 0;
}

.wrapper {
  margin: 0 auto;
  width: 90%;
}

.container {
  position: relative;
}

.item {
  position: absolute;
  top: 0;
  left: 0;
  transform: scale(0.8);
  transform-origin: center;
  border-radius: 16px;
  text-align: center;
  transition: 400ms linear;
  border: 1px solid pink;
  background-color: yellow;
  box-sizing: border-box;
}

.group-item {
  position: absolute;
  border-radius: 8px;
  text-align: center;
  border: 1px solid pink;
  background-color: rgba(0, 128, 0, 0.4);
  box-sizing: border-box;
  font-size: 20px;
}

.item .content {
  position: absolute;
  bottom: 4px;
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  text-align: bottom;
}

.item .title,
.item .count {
  font-weight: bold;
  line-height: 1em;
}

.item .title {
  font-size: 16px;
  flex: 1;
  text-align: left;
}

.item .count {
  font-size: 12px;
  padding-right: 12px;
  text-align: right;
}

.item .count::before {
  content: "票";
  position: absolute;
  font-size: 12px;
  transform: scale(0.8);
  transform-origin: center 80%;
  color: #666;
  right: 0;
  bottom: 0;
}

.done .item {
  transform: scale(1);
}

.flex-all-center {
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
