mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-18 05:58:07 +01:00
109 lines
2.6 KiB
Vue
109 lines
2.6 KiB
Vue
<template>
|
|
<Transition appear name="fade">
|
|
<div
|
|
:style="{
|
|
'--cell': `${width / cols}px`,
|
|
'--rows': rows - 1
|
|
}"
|
|
>
|
|
<div
|
|
ref="el"
|
|
class="absolute inset-0 grid justify-center auto-rows-[--cell] -space-y-px"
|
|
>
|
|
<div v-for="(row, rowIndex) in grid" :key="rowIndex" class="grid grid-flow-col auto-cols-[--cell] flex-1 -space-x-px">
|
|
<div
|
|
v-for="(cell, cellIndex) in row"
|
|
:key="cellIndex"
|
|
class="relative border border-primary-200/50 dark:border-primary-900/25"
|
|
>
|
|
<div class="absolute inset-0 bg-primary-500/10 hover:bg-primary-500/20 dark:bg-primary-400/5 dark:hover:bg-primary-400/10 opacity-0 transition-opacity will-change-[opacity] duration-1000" :class="[cell && 'opacity-100 cursor-pointer']" @click="cell && removeCell(rowIndex, cellIndex)" />
|
|
</div>
|
|
</div>
|
|
|
|
<div class="absolute top-[calc((var(--cell)*var(--rows))+1px)] inset-x-0 h-[calc(var(--cell)*2)] bg-gradient-to-t from-white dark:from-gray-900 pointer-events-none" />
|
|
</div>
|
|
</div>
|
|
</Transition>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { useElementSize } from '@vueuse/core'
|
|
|
|
const el = ref(null)
|
|
const grid = ref([])
|
|
const rows = ref(0)
|
|
const cols = ref(0)
|
|
|
|
const { width, height } = useElementSize(el)
|
|
|
|
function createGrid () {
|
|
grid.value = []
|
|
|
|
for (let i = 0; i <= rows.value; i++) {
|
|
grid.value.push(new Array(cols.value).fill(null))
|
|
}
|
|
}
|
|
|
|
function createNewCell () {
|
|
const x = Math.floor(Math.random() * cols.value)
|
|
|
|
grid.value[0][x] = true
|
|
}
|
|
|
|
function moveCellsDown () {
|
|
for (let row = rows.value - 1; row >= 0; row--) {
|
|
for (let col = 0; col < cols.value; col++) {
|
|
if (grid.value[row][col] !== null && grid.value[row + 1][col] === null) {
|
|
grid.value[row + 1][col] = grid.value[row][col]
|
|
grid.value[row][col] = null
|
|
}
|
|
}
|
|
}
|
|
|
|
setTimeout(() => {
|
|
if (grid.value[rows.value].every(cell => cell !== null)) {
|
|
for (let col = 0; col < cols.value; col++) {
|
|
grid.value[rows.value][col] = null
|
|
}
|
|
}
|
|
}, 500)
|
|
}
|
|
|
|
function removeCell (row, col) {
|
|
grid.value[row][col] = null
|
|
}
|
|
|
|
function calcGrid () {
|
|
const base = Math.ceil(width.value / 60)
|
|
const cell = width.value / base
|
|
|
|
rows.value = Math.ceil(height.value / cell)
|
|
cols.value = width.value / cell
|
|
|
|
createGrid()
|
|
}
|
|
|
|
watch(width, calcGrid)
|
|
|
|
onMounted(() => {
|
|
setTimeout(calcGrid, 50)
|
|
|
|
setInterval(() => {
|
|
moveCellsDown()
|
|
createNewCell()
|
|
}, 1000)
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.fade-enter-active,
|
|
.fade-leave-active {
|
|
transition: opacity 0.5s ease;
|
|
}
|
|
|
|
.fade-enter-from,
|
|
.fade-leave-to {
|
|
opacity: 0;
|
|
}
|
|
</style>
|