vue+css网格布局实现随机点阵,填充

该文章描述了一个使用Vue.js实现的图片上传功能,允许用户按照1x1、1x2、2x1、2x2四种格式上传图片,以填充一个3行6列的网格布局。通过二维数组来表示和管理布局状态,并用grid-area属性进行定位。当所有格子被填满时,系统会自动补充空白格子以保持布局完整。
摘要由CSDN通过智能技术生成

需求:大的容器内有18个3行6列的正方形格子,用户添加图片可以选择1x1、1x2、2x1、2x2的格式上传图片会填充到大容器内,1x1是占一个格子,1x2是一行横着占2个格子,2x1是竖着占两个格子,2x2是横竖占2格共4个格子;用户会选不同格式上传图片填充满整个3x6的容器。

如下是3x6的盒子

用户选择添加1x1的图如下会填充

 用户随机选择不同格式的添加直到填满盒子

 实现思路:定义一个二维数组,也是3x6的点阵,初始值是0,添加不同格式把数组改成1即为填充,再定义一个数组存储用户选择的不同格式点阵,并记录在3x6数组中的位置

实例代码实现:

html部分

<template>
  <div>
    <button @click="addBox('1x1')">添加1x1</button>
    <button @click="addBox('2x1')">添加2x1</button>
    <button @click="addBox('1x2')">添加1x2</button>
    <button @click="addBox('2x2')">添加2x2</button>
    <div class="grid-box">
      <div
        v-for="(item, index) in replenish()"
        :key="index"
        :class="['grid-item', {'def-box': item.layout.default}]"
        :style="{
          'grid-area': `${item.layout.star} / ${item.layout.end} / span ${item.layout.row} / span ${item.layout.column}`
        }"
      ></div>
    </div>
  </div>
</template>

以上代码是添加不同格式的按钮和3x6的容器,使用网格布局grid-item属性

grid-area:开始行的位置 / 开始列的位置 / span 行所占的格子数量 / span 列所占的格子数量

<script>
export default {
  data () {
    return {
      matrix: [
        [0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0]
      ], // 定义3行6列的二维数组
      emptyCells: [] // 定义空盒子的数组
    }
  },
  methods: {
    // 添加盒子的函数
    addBox (size) {
      const matrix = this.matrix
      let flag = false
      let layout = {}
      for (let i = 0; i < matrix.length; i++) {
        for (let j = 0; j < matrix[i].length; j++) {
          if (size === '1x1') {
            if (matrix[i][j] === 0) {
              matrix[i][j] = 1
              flag = true
              layout = { star: i + 1, end: j + 1, row: 1, column: 1 }
              break
            }
          } else if (size === '1x2') {
            if (matrix[i][j] === 0 && matrix[i][j + 1] === 0) {
              matrix[i][j] = 1
              matrix[i][j + 1] = 1
              flag = true
              layout = { star: i + 1, end: j + 1, row: 1, column: 2 }
              break
            }
          } else if (size === '2x1') {
            if (matrix[i][j] === 0 && matrix[i + 1] && matrix[i + 1][j] === 0) {
              matrix[i][j] = 1
              matrix[i + 1][j] = 1
              flag = true
              layout = { star: i + 1, end: j + 1, row: 2, column: 1 }
              break
            }
          } else if (size === '2x2') {
            if (matrix[i][j] === 0 &&
              matrix[i][j + 1] === 0 &&
              matrix[i + 1] &&
              matrix[i + 1][j] === 0 &&
              matrix[i + 1][j + 1] === 0
            ) {
              matrix[i][j] = 1
              matrix[i][j + 1] = 1
              matrix[i + 1][j] = 1
              matrix[i + 1][j + 1] = 1
              flag = true
              layout = { star: i + 1, end: j + 1, row: 2, column: 2 }
              break
            }
          }
        }
        if (flag) break
      }
      // 没有合适的空位放了
      if (!flag) {
        console.log('没有合适的位置了')
        return
      }
      // 将盒子的大小和位置添加到空盒子的数组中
      this.emptyCells.push({ size: size, layout })
      console.log('this.emptyCells:', this.emptyCells)
      console.log('this.matrix:', this.matrix)
      this.replenish()
    },
    // 补充剩余的盒子
    replenish () {
      const matrix = this.matrix
      const box = JSON.parse(JSON.stringify(this.emptyCells))
      for (let i = 0; i < matrix.length; i++) {
        for (let j = 0; j < matrix[i].length; j++) {
          if (matrix[i][j] === 0) {
            const layout = { star: i + 1, end: j + 1, row: 1, column: 1, default: true }
            box.push({ size: '1x1', layout })
          }
        }
      }
      return box
    }
  }
}
</script>

1.addBox是处理添加不同格式的盒子并且记录盒子所在的位置和行列占几个格子刚好是网格布局grid-item所需要的,

2.replenish是补充空的盒子确保这个网格一直是18个,因为网格布局的原因需要所有格子都有才会,不然会出现布局样式问题

<style scoped>
.grid-box {
  display: grid;
  grid-template-columns: auto auto auto auto auto auto;
  grid-gap: 20px;
  background-color: #2196F3;
  padding: 10px;
  box-sizing: border-box;
  width: 700px;
  height: 340px;
}

.grid-item {
  background: #ccc;
}
.def-box {
  background: #FFFFFF;
}
</style>

grid-box容器设置成网格布局,grid-template-columns定义一行6个格子,grid-gap定义格子上下左右间隔20px,宽是700px一行是6个盒子加上5个间隙20就是100,那么每个盒子宽度就是100px,高度是340px,18个盒子,一行显示6个,那就是3行,2个间隙20就是40,那么每个盒子的高度就是100px,得到3行6列的盒子都是宽*高就是100*100像素的

以上代码可以复制到vue文件中注册一个路由访问体验,有任何不对的地方和可以优化的点欢迎留言指教谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有梦想的小猪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值