矩阵生成随机布局

// 平均分
for(var i = 0,leni = matrix.length;i<leni;i++){
  for (var j = 0,lenj = matrix[i].length; j < lenj; j++) {
    var isHas = matrix[i][j];
    var x,y,h,w = 0;
    var _w = (width - space*(lenj+1))/lenj;
    x = (space*(j+1) + _w*j)*isHas;
    w = _w*isHas;
    var _h = (height - header_height - space*(leni+1))/leni;
    y = (header_height + space*(i+1) + _h*i)*isHas;
    h = _h*isHas;
    layout.push({
      x:x,
      w:w,
      y:y,
      h:h
    })
  }
}

指定份数

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

<head>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<style>
  .layout{
    width:1024px;
    height:768px;
    position: relative;
    box-shadow: 0 0 10px #ccc;
  }
  .layout .lay-item{
    position: absolute;
    background-color: red;
  }
</style>
<body>
  <div id="app">
    <div class="layout">
      <div class="lay-item" v-if="item.x" v-for="(item,index) in layout" :key="index" :style="{ left: item.x + 'px', width: item.w + 'px',top: item.y + 'px', height: item.h + 'px' }">{{item.pos}}</div>
    </div>
  </div>
</body>

</html>

<script>
  var width = 1024;
  var height = 768;
  var header_height = 60;
  var space = 10;
  // 分布解构
  var matrix = [
    [1,0,0,1],
    [1,0,0,1],
    [1,1,1,1]
  ];
  // 行列占的份数
  var ratios = {
    col:[1,1,1,1],
    row:[1,1,1]
  };
  ratios.rowTotal = ratios.row.reduce((a,b)=>{return a+b},0)
  ratios.colTotal = ratios.col.reduce((a,b)=>{return a+b},0)

  var layout = [];

  // 预留边缘
  width = width - 10;
  height = height - 10;

  // 预处理不规范的 ratios
  for(var i = 0,leni = matrix.length;i<leni;i++){
    if(ratios.row[i] === undefined){
      ratios.row[i] = 0;
    }
    for (var j = 0,lenj = matrix[i].length; j < lenj; j++) {
      if(ratios.col[j] === undefined){
        ratios.col[j] = 0;
      }
    }
  }

  for(var i = 0,leni = matrix.length;i<leni;i++){
    for (var j = 0,lenj = matrix[i].length; j < lenj; j++) {
      var isHas = matrix[i][j];
      var x = 0,y = 0,h = 0,w = 0;
      // 每一份大小
      var one_w = (width - space*(lenj))/ratios.colTotal;
      var _w = one_w*ratios.col[j];
      var col_x = ratios.col.filter((a,b)=>b<j).reduce((a,b)=>{return a+b},0);
      x = (space*(j+1) + one_w*col_x)*isHas;
      w = _w*isHas;
      var one_y = (height - header_height - space*leni)/ratios.rowTotal;
      var _h = one_y*ratios.row[i];
      var row_y = ratios.row.filter((a,b)=>b<i).reduce((a,b)=>{return a+b},0);
      y = (header_height + space*(i+1) + one_y*row_y)*isHas;
      h = _h*isHas;

      x!==0 && layout.push({
        pos:[i,j],
        x:x,
        w:w,
        y:y,
        h:h
      })
    }
  }
  
  var app = new Vue({
    el: '#app',
    data: {
      layout
    }
  })

</script>

 完整,按行列指定份数

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

<head>
  <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<style>
  .layout {
    width: 1024px;
    height: 768px;
    position: relative;
    box-shadow: 0 0 10px #ccc;
  }

  .layout .lay-item {
    position: absolute;
    background-color: red;
  }
</style>

<body>
  <div id="app">
    <div class="layout" :style="{ width: width + 'px',height: height + 'px'}">
      <div class="lay-item" v-if="item.x" v-for="(item,index) in layout" :key="index"
        :style="{ left: item.x + 'px', width: item.w + 'px',top: item.y + 'px', height: item.h + 'px' }">{{item.pos}}
      </div>
    </div>
  </div>
</body>

</html>

<script>
  function floatLayout(options = {
    width: 1024,
    height: 768,
    header_height: 60,
    space: 10,
    matrix: [
      [1, 0, 1, 1],
      [1, 0, 0, 1],
      [1, 1, 1, 1]
    ],
    matrix_ratios: {
      col: [1, 1, 1, 1],
      row: [1, 1, 1]
    }
  }) {

    var width = options.width;
    var height = options.height;
    var header_height = options.header_height;
    var space = options.space;
    // 分布解构
    var matrix = options.matrix;
    // 行列占的份数
    var matrix_ratios = options.matrix_ratios;


    matrix_ratios.rowTotal = matrix_ratios.row.reduce((a, b) => { return a + b }, 0)
    matrix_ratios.colTotal = matrix_ratios.col.reduce((a, b) => { return a + b }, 0)

    if (space <= 0) {
      space = 0.00001;
    }

    var layout = [];

    // 预留边缘
    width = width - space;
    height = height - space;

    // 预处理不规范的 matrix_ratios
    for (var i = 0, leni = matrix.length; i < leni; i++) {
      if (matrix_ratios.row[i] === undefined) {
        matrix_ratios.row[i] = 0;
      }
      for (var j = 0, lenj = matrix[i].length; j < lenj; j++) {
        if (matrix_ratios.col[j] === undefined) {
          matrix_ratios.col[j] = 0;
        }
      }
    }

    for (var i = 0, leni = matrix.length; i < leni; i++) {
      for (var j = 0, lenj = matrix[i].length; j < lenj; j++) {
        var isHas = matrix[i][j];
        var x = 0, y = 0, h = 0, w = 0;
        var one_w = (width - space * (lenj)) / matrix_ratios.colTotal;
        var _w = one_w * matrix_ratios.col[j];
        var col_x = matrix_ratios.col.filter((a, b) => b < j).reduce((a, b) => { return a + b }, 0);
        x = (space * (j + 1) + one_w * col_x) * isHas;
        w = _w * isHas;
        var one_y = (height - header_height - space * leni) / matrix_ratios.rowTotal;
        var _h = one_y * matrix_ratios.row[i];
        var row_y = matrix_ratios.row.filter((a, b) => b < i).reduce((a, b) => { return a + b }, 0);
        y = (header_height + space * (i + 1) + one_y * row_y) * isHas;
        h = _h * isHas;
        x !== 0 && layout.push({
          pos: [i, j],
          x: x,
          w: w,
          y: y,
          h: h
        })
      }
    }

    return layout;

  }



  window.app = new Vue({
    el: '#app',
    data: {
      width:0,
      height:0,
      layout: []
    },
    methods: {
      init: function (opt) {
        this.width = opt.width;
        this.height = opt.height;
        this.layout = floatLayout(opt)
      }
    }
  })
  window.app.init({
    width: 1024,
    height: 768,
    header_height: 60,
    space: 10,
    matrix: [
      [1, 0, 0, 1],
      [1, 0, 0, 1],
      [1, 1, 1, 1]
    ],
    matrix_ratios: {
      col: [1, 1, 1, 1],
      row: [1, 1, 1]
    }
  })
</script>

 每个单元格都可独立设置份数

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

<head>
  <script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
</head>
<style>
  .layout {
    width: 1024px;
    height: 768px;
    position: relative;
    box-shadow: 0 0 10px #ccc;
  }

  .layout .lay-item {
    position: absolute;
    background-color: red;
  }
</style>

<body>
  <div id="app">
    <div class="layout" :style="{ width: width + 'px',height: height + 'px'}">
      <div class="lay-item" v-if="item.x" v-for="(item,index) in layout" :key="index"
        :style="{ left: item.x + 'px', width: item.w + 'px',top: item.y + 'px', height: item.h + 'px' }">{{item.pos}}
      </div>
    </div>
  </div>
</body>

</html>

<script>
  function floatLayout(options = {
      width: 1024,
      height: 768,
      header_height: 60,
      space: 10,
      matrix: [
        [1,0, 1],
        [1,0, 1],
        [1,1, 1]
      ],
      matrix_ratios: [
        [[0.5,1],[1,1],[0.5,1]],
        [[0.5,1],[1,1],[0.5,1]]
      ]
    }) {

    var width = options.width;
    var height = options.height;
    var header_height = options.header_height;
    var space = options.space;
    // 分布解构
    var matrix = options.matrix;
    // 行列占的份数
    var matrix_ratios = options.matrix_ratios;

    // 预处理不规范的 matrix_ratios
    for (var i = 0, leni = matrix.length; i < leni; i++) {
      for (var j = 0, lenj = matrix[i].length; j < lenj; j++) {
        if(matrix_ratios[i] === undefined){
          matrix_ratios[i] = []
        }
        if(matrix_ratios[i][j] === undefined){
          matrix_ratios[i][j] = [1,1];
        }
      }
    }

    if (space <= 0) {
      space = 0.00001;
    }

    // 预留边缘
    width = width - space;
    height = height - space;
    
    var layout = [];

    for (var i = 0, leni = matrix.length; i < leni; i++) {
      for (var j = 0, lenj = matrix[i].length; j < lenj; j++) {
        var isHas = matrix[i][j];
        var x = 0, y = 0, h = 100, w = 0;
        var colTotal = matrix_ratios[i].reduce((a, b) => { return a + b[0] }, 0)
        var one_w = (width - space * (lenj)) / colTotal;
        var col_x = matrix_ratios[i].filter((a, b) => b < j).reduce((a, b) => {return a + b[0] }, 0);
        var _w = one_w * matrix_ratios[i][j][0];
        x = (space * (j + 1) + one_w * col_x) * isHas;
        w = _w * isHas;

        var rowTotal = matrix_ratios.reduce((a,b)=>{return a+b[j][1]},0)
        var one_y = (height - header_height - space * leni) / rowTotal;
        var _h = one_y * matrix_ratios[i][j][1];
        var row_y = matrix_ratios.filter((a, b) => b < i).reduce((a, b) => { return a + b[j][1] }, 0);
        y = (header_height + space * (i + 1) + one_y * row_y) * isHas;
        h = _h * isHas;

        x !== 0 && layout.push({
          pos: [i, j],
          x: x,
          w: w,
          y: y,
          h: h
        })
      }
    }

    return layout;

  }



  window.app = new Vue({
    el: '#app',
    data: {
      width:0,
      height:0,
      layout: []
    },
    methods: {
      init: function (opt) {
        this.width = opt.width;
        this.height = opt.height;
        this.layout = floatLayout(opt)
      }
    }
  })
  window.app.init({
    width: 1024,
    height: 768,
    header_height: 60,
    space: 10,
    matrix: [
      [1,0,1]
    ],
    matrix_ratios: [
      [[1,1],[2,2],[3,1]],
    ]
  })
</script>

 添加背景

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

<head>
  <script src="sss.js"></script>
</head>
<style>
  .layout {
    width: 1024px;
    height: 768px;
    position: relative;
    box-shadow: 0 0 10px #ccc;
  }

  .layout .lay-item {
    position: absolute;
    background-color: #043769;
    padding:0;
    transition: 2s;
  }

  .bg9{

    box-sizing: border-box;

    border-image-source:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFEAAABRCAYAAACqj0o2AAACBklEQVR4nO3cwU3CUADG8Q+jgBdG8MYGTECYgiMbwCB1A45OQZyADbw5AhdFD/WANa/to63yAUL//8TkCbXWX15r0+jrjKfzVHRQN+c+gGvoNhtsJskw8v72hMfy3+sVXxisFi9SgFgow/s41hFdcCXMGGII+HnUw7m8utr55CCLiEVAEMuVIGMzMQQEMV43/CRE3KoAOFgt3prs8fnpsZONR8u0v5513s89lqS67SSp6S3eZpLc73uvk+1kM0keFEEMgdraeDpPvxHvgo/uYLV4lbhPtASiIRANgWgIREMgGgLREIiGQDQEoiEQDYFoCERDIBoC0VAlIs8Sd9U5MBMNgWgIREMgGgLREIiGQDQEoiEQDYFoCERDIBoC0RCIhkA0BKIhEA2BaAhEQyAaAtEQiIZANASiIRANgWgIREMgGgLR0L7lCyRJo6V3oZL17Dr/yIyZaKhyJg5Wi4N2vpkkB339pVQ3E1l4SPX/nc/pbOhoiG05laWaa+JfahNeFqezIStiG2ehZERsK6BkQmwzoMQ10RKIhkA0BKIhEA2BaAhEQyAaavIAoskzxfC5f1/Se2w8Wqa1q2ueciw1X8mz8ocPVvIcKrIk6qHf4IrKreIpqVe1znY38hrlAXMVEXvazUYgy4WAletsZxsAWS4KKO3/xVLakPab/CBmF0n6fdwnGvoCnO/Hzf7vxT0AAAAASUVORK5CYII=');

    border-image-slice:27 27 27 27;

    border-image-width:27px 27px 27px 27px;

    border-image-outset:10px 10px 10px 10px;

    border-image-repeat:repeat;
  }
</style>

<body>
  <div id="app">
    <div class="layout" :style="{ width: width + 'px',height: height + 'px'}">
      <div class="lay-item bg9" v-if="item.x" v-for="(item,index) in layout" :key="item.pos.join('-')"
        :style="{ left: item.x + 'px', width: item.w + 'px',top: item.y + 'px', height: item.h + 'px' }">{{item.pos}}
      </div>
    </div>
  </div>
</body>

</html>

<script>
  function floatLayout(options = {
      width: 1024,
      height: 768,
      header_height: 60,
      space: 10,
      matrix: [
        [1,0, 1],
        [1,0, 1],
        [1,1, 1]
      ],
      matrix_ratios: [
        [[0.5,1],[1,1],[0.5,1]],
        [[0.5,1],[1,1],[0.5,1]]
      ]
    }) {

    var width = options.width;
    var height = options.height;
    var header_height = options.header_height;
    var space = options.space;
    // 分布解构
    var matrix = options.matrix;
    // 行列占的份数
    var matrix_ratios = options.matrix_ratios;

    // 预处理不规范的 matrix_ratios
    for (var i = 0, leni = matrix.length; i < leni; i++) {
      for (var j = 0, lenj = matrix[i].length; j < lenj; j++) {
        if(matrix_ratios[i] === undefined){
          matrix_ratios[i] = []
        }
        if(matrix_ratios[i][j] === undefined){
          matrix_ratios[i][j] = [1,1];
        }
      }
    }

    if (space <= 0) {
      space = 0.00001;
    }

    // 预留边缘
    width = width - space;
    height = height - space;
    
    var layout = [];

    for (var i = 0, leni = matrix.length; i < leni; i++) {
      for (var j = 0, lenj = matrix[i].length; j < lenj; j++) {
        var isHas = matrix[i][j];
        var x = 0, y = 0, h = 100, w = 0;
        var colTotal = matrix_ratios[i].reduce((a, b) => { return a + b[0] }, 0)
        var one_w = (width - space * (lenj)) / colTotal;
        var col_x = matrix_ratios[i].filter((a, b) => b < j).reduce((a, b) => {return a + b[0] }, 0);
        var _w = one_w * matrix_ratios[i][j][0];
        x = (space * (j + 1) + one_w * col_x) * isHas;
        w = _w * isHas;

        var rowTotal = matrix_ratios.reduce((a,b)=>{return a+b[j][1]},0)
        var one_y = (height - header_height - space * leni) / rowTotal;
        var _h = one_y * matrix_ratios[i][j][1];
        var row_y = matrix_ratios.filter((a, b) => b < i).reduce((a, b) => { return a + b[j][1] }, 0);
        y = (header_height + space * (i + 1) + one_y * row_y) * isHas;
        h = _h * isHas;

        x !== 0 && layout.push({
          pos: [i, j],
          x: x,
          w: w,
          y: y,
          h: h
        })
      }
    }

    console.log(options)

    return layout;

  }



  window.app = new Vue({
    el: '#app',
    data: {
      width:0,
      height:0,
      layout: []
    },
    methods: {
      init: function (opt) {
        this.width = opt.width;
        this.height = opt.height;
        this.layout = floatLayout(opt)
        console.log(this.layout)
      }
    }
  })
  window.app.init({
    width: 1400,
    height: 900,
    header_height: 60,
    space: 30,
    matrix: [
      [1,1,1],
      [1,1,1]
    ],
    matrix_ratios: [
      [[1,1],[2,1],[3,1]],
    ]
  })
</script>

 优化缝隙处理

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

<head>
  <script src="sss.js"></script>
</head>
<style>
  .layout {
    width: 1024px;
    height: 768px;
    position: relative;
    box-shadow: 0 0 10px #ccc;
  }

  .layout .lay-item {
    position: absolute;
    background-color: #043769;
    padding: 0;
    transition: 2s;
    color:#fff;
  }

  .bg9 {

    box-sizing: border-box;

    border-image-source: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFEAAABRCAYAAACqj0o2AAACBklEQVR4nO3cwU3CUADG8Q+jgBdG8MYGTECYgiMbwCB1A45OQZyADbw5AhdFD/WANa/to63yAUL//8TkCbXWX15r0+jrjKfzVHRQN+c+gGvoNhtsJskw8v72hMfy3+sVXxisFi9SgFgow/s41hFdcCXMGGII+HnUw7m8utr55CCLiEVAEMuVIGMzMQQEMV43/CRE3KoAOFgt3prs8fnpsZONR8u0v5513s89lqS67SSp6S3eZpLc73uvk+1kM0keFEEMgdraeDpPvxHvgo/uYLV4lbhPtASiIRANgWgIREMgGgLREIiGQDQEoiEQDYFoCERDIBoC0VAlIs8Sd9U5MBMNgWgIREMgGgLREIiGQDQEoiEQDYFoCERDIBoC0RCIhkA0BKIhEA2BaAhEQyAaAtEQiIZANASiIRANgWgIREMgGgLR0L7lCyRJo6V3oZL17Dr/yIyZaKhyJg5Wi4N2vpkkB339pVQ3E1l4SPX/nc/pbOhoiG05laWaa+JfahNeFqezIStiG2ehZERsK6BkQmwzoMQ10RKIhkA0BKIhEA2BaAhEQyAaavIAoskzxfC5f1/Se2w8Wqa1q2ueciw1X8mz8ocPVvIcKrIk6qHf4IrKreIpqVe1znY38hrlAXMVEXvazUYgy4WAletsZxsAWS4KKO3/xVLakPab/CBmF0n6fdwnGvoCnO/Hzf7vxT0AAAAASUVORK5CYII=');

    border-image-slice: 27 27 27 27;

    border-image-width: 27px 27px 27px 27px;

    border-image-outset: 10px 10px 10px 10px;

    border-image-repeat: repeat;
  }
</style>

<body>
  <div id="app">
    <div class="layout" :style="{ width: width + 'px',height: height + 'px'}">
      <div class="lay-item bg9" v-if="item.w>30 && item.h>30" v-for="(item,index) in layout" :key="item.pos.join('-')"
        :style="{ left: item.x + 'px', width: item.w + 'px',top: item.y + 'px', height: item.h + 'px' }">{{item.pos}}
      </div>
    </div>
  </div>
</body>

</html>

<script>
  function floatLayout(options = {
    width: 1024,
    height: 768,
    header_height: 60,
    space: 10,
    matrix: [
      [1, 0, 1],
      [1, 0, 1],
      [1, 1, 1]
    ],
    matrix_ratios: [
      [[0.5, 1], [1, 1], [0.5, 1]],
      [[0.5, 1], [1, 1], [0.5, 1]]
    ]
  }) {

    var width = options.width;
    var height = options.height;
    var header_height = options.header_height;
    var space = options.space;
    // 分布解构
    var matrix = options.matrix;
    // 行列占的份数
    var matrix_ratios = options.matrix_ratios;

    // 预处理不规范的 matrix_ratios
    for (var i = 0, leni = matrix.length; i < leni; i++) {
      for (var j = 0, lenj = matrix[i].length; j < lenj; j++) {
        if (matrix_ratios[i] === undefined) {
          matrix_ratios[i] = []
        }
        if (matrix_ratios[i][j] === undefined) {
          matrix_ratios[i][j] = [1, 1];
        }
      }
    }

    if (space <= 0) {
      space = 0.00001;
    }

    // 预留边缘
    width = width - space;
    height = height - space;

    var layout = [];

    // 不存在坐标偏移处理
    var offsetX = 0;
    var offsetY = new Array();
    for (var i = 0, leni = matrix.length; i < leni; i++) {
      for (var j = 0, lenj = matrix[i].length; j < lenj; j++) {
        var isHas = matrix[i][j];
        var x = 0, y = 0, h = 100, w = 0;
        var colTotal = matrix_ratios[i].reduce((a, b) => { return a + b[0] }, 0)
        var one_w = (width - space * (lenj)) / colTotal;
        var col_x = matrix_ratios[i].filter((a, b) => b < j).reduce((a, b) => { return a + b[0] }, 0);
        var _w = one_w * matrix_ratios[i][j][0];
        x = (space * (j + 1) + one_w * col_x) * isHas;
        w = _w * isHas;
        if (matrix_ratios[i][j][0] === 0) {
          offsetX += space;
        } else {
          w = w + offsetX;
          x = x - offsetX;
          offsetX = 0;
        }
        if (j === lenj - 1) {
          layout[layout.length - 1].w += offsetX;
          offsetX = 0; // 初始化横偏移量
        }

        var rowTotal = matrix_ratios.reduce((a, b) => { return a + b[j][1] }, 0)
        var one_y = (height - header_height - space * leni) / rowTotal;
        var _h = one_y * matrix_ratios[i][j][1];
        var row_y = matrix_ratios.filter((a, b) => b < i).reduce((a, b) => { return a + b[j][1] }, 0);
        y = (header_height + space * (i + 1) + one_y * row_y) * isHas;
        h = _h * isHas;

        offsetY[j] = offsetY[j] || 0;
        if (matrix_ratios[i][j][1] === 0) {
          offsetY[j] += space;
        } else {
          h = h + offsetY[j];
          y = y - offsetY[j];
          offsetY[j] = 0;
        }
        if (i === leni - 1) {
          for (var s = layout.length - 1; s >= 0; s--) {
            if (layout[s].pos[1] === j) {
              layout[s].h += offsetY[j];
              offsetY[j] = 0;
              break;
            }
          }
        }


        if (w > space && h > space) {
          layout.push({
            pos: [i, j],
            x: x,
            w: w,
            y: y,
            h: h
          })
        }

      }
    }

    console.log(options)

    return layout;

  }



  window.app = new Vue({
    el: '#app',
    data: {
      width: 0,
      height: 0,
      layout: []
    },
    methods: {
      init: function (opt) {
        this.width = opt.width;
        this.height = opt.height;
        this.layout = floatLayout(opt)
        console.log(this.layout)
      }
    }
  })
  window.app.init({
    width: 1024,
    height: 768,
    header_height: 60,
    space: 30,
    matrix: [
      [1, 1, 1],
      [1, 0, 1],
      [1, 0, 1]
    ],
    matrix_ratios: [
      [[1, 1], [1, 1]],
      [[1, 1], [1, 1]],
      [[1, 1], [1, 1]]
    ]
  })
</script>

 

重新改逻辑,布局固定,通过比例控制显示大小,比例为0不显示

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

<head>
  <script src="sss.js"></script>
</head>
<style>
  .layout {
    width: 1024px;
    height: 768px;
    position: relative;
    box-shadow: 0 0 10px #ccc;
  }

  .layout .lay-item {
    position: absolute;
    background-color: #023142;
    background-size: 100% 100%;
    padding: 0;
    transition: 2s;
    color: #fff;
  }
</style>

<body>
  <div id="app">
    <div class="layout" :style="{ width: width + 'px',height: height + 'px'}">
      <div class="lay-item" v-if="item.w>30 && item.h>30" v-for="(item,index) in layout" :key="item.pos.join('-')"
        :style="{ left: item.x + 'px', width: item.w + 'px',top: item.y + 'px', height: item.h + 'px' }">{{item.pos}}
      </div>
    </div>
  </div>
</body>

</html>

<script>
  function floatLayout(options = {
    width: 1024,
    height: 768,
    header_height: 60,
    space: 10,
    matrix: [
      [1, 0, 1],
      [1, 0, 1]
    ],
    matrix_ratios: [
      [[0.5, 1], [1, 1], [0.5, 1]],
      [[0.5, 1], [1, 1], [0.5, 1]]
    ]
  }) {
    var width = options.width;
    var height = options.height;
    var header_height = options.header_height;
    var space = options.space;
    var matrix = options.matrix;
    var matrix_ratios = options.matrix_ratios;
    for (var i = 0, leni = matrix.length; i < leni; i++) {
      for (var j = 0, lenj = matrix[i].length; j < lenj; j++) {
        if (matrix_ratios[i] === undefined) {
          matrix_ratios[i] = []
        }
        if (matrix_ratios[i][j] === undefined) {
          matrix_ratios[i][j] = [1, 1];
        }
        matrix[i][j] = matrix[i][j] === 0 ? 0 : 1;
      }
    }
    if (space <= 0) {
      space = 0.00001;
    }
    // 预留边缘
    width = width - space;
    height = height - space;
    var layout = [];
    // 头部
    layout.push({
      pos: [-1, -1],
      x: 0,
      w: width + space,
      y: 0,
      h: header_height
    })
    // 不存在坐标偏移处理
    var offsetX = 0;
    var offsetY = new Array();
    for (var i = 0, leni = matrix.length; i < leni; i++) {
      for (var j = 0, lenj = matrix[i].length; j < lenj; j++) {
        var isHas = matrix[i][j];
        var x = 0, y = 0, h = 100, w = 0;
        // 获取总的列数
        var colTotal = matrix_ratios[i].reduce((a, b) => { return a + b[0] }, 0)
        // 每一列实际的格子占比
        var col_ratio = colTotal / lenj;
        // 平均列宽
        var one_w = (width - space * lenj) / colTotal;
        // 当前实际有效格子的份数
        var col_m = matrix_ratios[i][j][0];
        // 计算当前宽度
        var _w = one_w * col_m + (col_m / col_ratio - 1) * space;
        // 当前位置的列起始格子数
        var col_x = matrix_ratios[i].filter((a, b) => b < j).reduce((a, b) => { return a + b[0] }, 0);
        var _x = one_w * col_x + space + space * col_x / col_ratio;
        x = _x * isHas;
        w = _w * isHas;
        var rowTotal = matrix_ratios.reduce((a, b) => { return a + b[j][1] }, 0)
        var row_ratio = rowTotal / leni;
        var one_y = (height - header_height - space * leni) / rowTotal;
        var row_m = matrix_ratios[i][j][1];
        var _h = one_y * row_m + (row_m / row_ratio - 1) * space;
        var row_y = matrix_ratios.filter((a, b) => b < i).reduce((a, b) => { return a + b[j][1] }, 0);
        var _y = header_height + one_y * row_y + space + space * row_y / row_ratio;
        h = _h * isHas;
        y = _y * isHas;
        if (w > space && h > space) {
          layout.push({
            pos: [i, j],
            x: x,
            w: w,
            y: y,
            h: h
          })
        }
      }
    }
    return layout;
  }



  window.app = new Vue({
    el: '#app',
    data: {
      width: 0,
      height: 0,
      layout: []
    },
    methods: {
      init: function (opt) {
        this.width = opt.width;
        this.height = opt.height;
        this.layout = floatLayout(opt)
        console.log(this.layout)
      }
    }
  })
  window.app.init({
    width: 1440,
    height: 768,
    header_height: 60,
    space: 10,
    matrix: [
      [1, 0, 0, 1],
      [1, 0, 0, 1],
      [1, 1, 1, 1]
    ],

    matrix_ratios: [
      [[1, 1], [1, 1], [1, 1], [1, 1]],
      [[1, 1], [1, 1], [1, 1], [1, 1]],
      [[1, 1], [1, 1], [1, 1], [1, 1]]
    ]

  })

</script>

 

posted @ 2023-07-07 09:52  木章  阅读(30)  评论(0)    收藏  举报