合并宫格,并且判断所选的是否为矩形(js,vue,grid,html,css)

353 阅读1分钟

合并宫格,并且判断所选的是否为矩形

背景

需要做一个多宫格合并的功能,并且判断是否为矩形,不是矩形不能合并,并且提示。

实现逻辑步骤

1.动态生成 N 宫格;
2.点击单元格选中;
3.判断选中宫格合并是否为常规矩形;
4.合并;

注意

因为是基于vue写的(比较方便),要到官网或者github下载相应的依赖 vue.min.js,才可以正常启动代码。如果有可用的CDN也可替换

效果

1654506982(1).png

1654507026(1).png

代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>合并单元格</title>
    <script src="./vue.min.js"></script>
    <style>
        .grid-box {
            width: 500px;
            height: 500px;
            display: grid;
            grid-auto-flow: column dense;

        }

        .grid-box-item {
            border: 2px solid black;
            cursor: pointer;
        }

        .choosed {
            border-color: red;
        }
    </style>
</head>

<body>
    <div id="app">
        <div class="grid-box" id="box">
            <div class="grid-box-item" v-for="(item, index) in gridList" :key="index" ref=""
                @click="handleCellClick(item)" :style="{ ...item.style }" :class="{ choosed: item.choosed }"></div>
        </div>
        <button @click="merge">merge</button>
    </div>
</body>
<script>
    new Vue({
        el: '#app', //element
        data() {
            return {
                gridList: [],
                choosedList: [],
                row: 3,
                column: 3,
            };
        },
        mounted() {
            this.createTable();
        },
        methods: {
            debounce(fn, wait) {
                if (timeout !== null) clearTimeout(timeout);
                timeout = setTimeout(fn, wait);
            },
            createTable() {
                this.gridList = [];
                let id = 1;
                for (let i = 1; i <= this.row; i++) {
                    for (let j = 1; j <= this.column; j++) {
                        let item = {
                            id,
                            choosed: false,
                            gridColumnStart: j,
                            gridColumnEnd: j + 1,
                            gridRowStart: i,
                            gridRowEnd: i + 1,
                            cellNum: 1,
                        };

                        item.style = {};
                        item.style.gridArea = item.style.gridColumn =
                            item.gridRowStart +
                            " / " +
                            item.gridColumnStart +
                            " / " +
                            item.gridRowEnd +
                            " / " +
                            item.gridColumnEnd;

                        this.gridList.push(item);

                        id = id + 1;
                    }
                }

                let box = document.getElementById("box");
                box.style.gridTemplateColumns = this.column;
                box.style.gridTemplateRows = this.row;
            },
            merge() {
                let colStart, colEnd, rowStart, rowEnd;
                let selectedCellCout = 0;
                let result;

                for (let item of this.choosedList) {
                    selectedCellCout = selectedCellCout + item.cellNum;
                    if (item.gridColumnStart < colStart || !colStart) {
                        colStart = item.gridColumnStart;
                    }
                    if (item.gridRowStart < rowStart || !rowStart) {
                        rowStart = item.gridRowStart;
                    }
                    if (item.gridColumnEnd > colEnd || !colEnd) {
                        colEnd = item.gridColumnEnd;
                    }
                    if (item.gridRowEnd > rowEnd || !rowEnd) {
                        rowEnd = item.gridRowEnd;
                    }
                }
                console.log(this.choosedList);
                console.log(selectedCellCout);
                console.log((rowEnd - rowStart) * (colEnd - colStart));
                if (selectedCellCout != (rowEnd - rowStart) * (colEnd - colStart)) {
                    console.log("not a square");
                    return false;
                }

                result = this.choosedList.shift();
                result.style.gridArea =
                    rowStart + " / " + colStart + " / " + rowEnd + " / " + colEnd;

                result.gridColumnStart = colStart;
                result.gridColumnEnd = colEnd;
                result.gridRowStart = rowStart;
                result.gridRowEnd = rowEnd;
                result.cellNum = result.cellNum + this.choosedList.length;

                this.gridList = this.gridList.filter((item) => {
                    let index = this.choosedList.findIndex((el) => {
                        return el.id == item.id;
                    });
                    return index == -1;
                });

                this.choosedList = [result];
            },

            handleCellClick(item) {
                if (!item.choosed) {
                    item.choosed = true;
                    this.choosedList.push(item);
                } else {
                    let index = this.choosedList.findIndex((el) => {
                        return el.id == item.id;
                    });
                    if (index > -1) {
                        item.choosed = false;
                        this.choosedList.splice(index, 1);
                    }
                }
            },
        },
    })
</script>


</html>