JSFiddle - React, Tailwind, and code Playground
by Sam Wray
HTML
<script src="https://unpkg.com/vue"></script>
<div id="app">
<div id="grid">
<div v-for="x, xi in grid" class="col">
<transition-group name="list" tag="span">
<div
v-for="y, yi in x"
class="block"
:style="`background-color: ${y.color}`"
@click="blockClicked(xi, yi, y.color)"
:key=" y.id"
></div>
</transition-group>
</div>
</div>
</div>
SCSS
@font-stack: Helvetica,
sans-serif;
@primary-color: #999;
html,
body {
width: 100%;
height: 100%;
}
body {
font: 10pt @font-stack;
color: @primary-color;
margin: 0;
padding: 0;
}
#grid,
#app {
width: 100%;
height: 100%;
background: grey;
font-size: 0;
}
.col {
background: grey;
float: left;
width: 10%;
height: 100%;
}
.block {
width: 100%;
height: 10%;
background: red;
transition: all;
display: inline-block
}
.active {
-webkit-box-shadow: inset 0 0 10px #000000;
}
.list-move {
transition: transform 400ms cubic-bezier(0.68, 0.05, 1, 0.93);
}
JavaScript
const COLORS = ['red', 'green', 'blue', 'yellow'];
const MAX_X = 10;
const MAX_Y = 10;
const deadColor = 'transparent';
class Block {
constructor(x, y, id) {
this.id = Date.now() + id;
this.x = x;
this.y = y;
this.color = COLORS[
Math.floor(Math.random() * COLORS.length)
];
}
}
new Vue({
el: '#app',
data: {
grid: [],
},
created() {
for (let x = 0; x < MAX_X; x++) {
let col = [];
for (let y = 0; y < MAX_Y; y++) {
col.push(new Block(x, y, '' + x + y));
}
this.grid.push(col);
}
},
methods: {
blockClicked(x, y, color) {
const {
grid
} = this;
const block = grid[x][y];
if (block.color === deadColor) return;
this.checkBlocks(color, x, y);
block.color = deadColor;
for (let x = 0; x < MAX_X; x++) {
const toSplice = [];
for (let y = 0; y < MAX_Y; y++) {
const block = grid[x][y];
if (block.color === deadColor) {
toSplice.push(y);
}
}
if (toSplice.length) {
const deadBlocks = [];
for (let i = toSplice.length - 1; i >= 0; i--) {
const y = toSplice[i];
deadBlocks.push(
grid[x].splice(y, 1)[0]
);
}
grid[x] = deadBlocks.concat(grid[x]);
}
}
},
getAdjacents(x, y) {
// return [top, right, bottom, left]
return [
[x - 1, y],
[x, y + 1],
[x + 1, y],
[x, y - 1]
];
},
matchAdjacentColors(adjacents, color, x, y) {
// return [top, right, bottom, left]
return adjacents.map((point) => {
const x = point[0];
const y = point[1];
if (x > MAX_X - 1 || y > MAX_Y - 1 || x < 0 || y < 0) {
return -1;
}
const block = this.grid[x][y];
return...