Vue

by khamer

HTML

<div id="app" :style="style">
  <input type="number" v-model.number="numColumns" class="columns">
  <input type="number" v-model.number="numRows" class="rows">
  
  <div v-for="(c,i) in columns" class="row" :style="`background-image: linear-gradient(to right, #000 1px, transparent 0), linear-gradient(to right, #acf ${c.w}em, transparent 0); background-size: ${c.w+c.g}em;`"></div>
</div>

CSS

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  border-radius: 4px;
  padding: .5em;
  position: relative;
  transition: all 0.2s;
  
  background-color: #fff;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
}


input {
  box-sizing: border-box;
  height: 15px;
  padding: 0;
  margin: 0;
  font-size: 15px;
  position: absolute;
  width: 3em;
  text-align: center;
}

input.columns {
  left: 4.5em;
}

input.rows {
  left: 0.5em;
}

input + .row {
  margin-top: 2em;
}

.row {
  height: 1em;
}

Vue

new Vue({
  el: "#app",
  data: {
  	numColumns: 18,
    numRows: 30,
  },
  computed: {
  	columns() {
    	let columns = [];
    	for (let w = 1; w < this.numColumns / 2; w++) {
      	for (let g = 0; g <= w; g++) {
        	if ( (this.numColumns+g) % (w+g) === 0) {
	        	columns.push({w, g});
  	      }
        }
      }
      return columns;
    },
  	style() {
    	return `
      	font-size: 15px;
        background-image: radial-gradient(#000 1px, transparent 0);
      	width: ${this.numColumns}em;
        height: ${this.numRows}em;
        background-position: 0 0;
      	background-size: 1em 1em;
      `
    }
  }
})