Anonymous
Как мне плавно оживить падающие элементы после удаления предметов из сетки CSS?
Сообщение
Anonymous » 05 авг 2025, 12:23
Я строю игровой автомат, где символы (DOV) выкладываются в столбцах внутри гибкого контейнера. Когда будет обнаружен матч, я удаляю соответствующие элементы из DOM, а затем новые падают сверху. Тем не менее, поскольку удаление элементов вызывает рефвоу, переход не применяется, и элементы просто сдвигаются вниз, чтобы заполнить пустые пространства, которые были оставлены удаленными элементами. А затем после того, как эти недавно сгенерированные заполняют все, что осталось с хорошим переходом. Заставьте символы падать с гладкой анимацией, когда я удаляю символы под ним? PrettyPrint-Override ">
Код: Выделить всё
const symbols = ["🍒", "🍋", "🍇", "🔔"];
const columns = document.querySelectorAll(".col");
const spinButton = document.querySelector("#spin-button");
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const getRandomSymbol = () => {
const randomIndex = Math.floor(Math.random() * symbols.length);
return symbols[randomIndex];
};
const generateColumns = () => {
[...columns].forEach((col) => {
while (col.children.length < 4) {
const symbol = getRandomSymbol();
const symbolElement = document.createElement("div");
symbolElement.textContent = symbol;
symbolElement.dataset.symbolType = symbol;
symbolElement.classList.add("symbol", "above-reel", "falling");
setTimeout(() => {
symbolElement.style.transform = "translateY(0%)";
}, 300);
col.appendChild(symbolElement);
}
});
};
const startSpin = async () => {
let currentSymbols = document.querySelectorAll(".symbol");
currentSymbols.forEach((symbol) => {
symbol.remove();
});
generateColumns();
await wait(400);
checkWins();
};
const checkWins = async () => {
let winningSymbols = [];
symbols.forEach((symbol) => {
// Check for each symbol
let consecutiveCount = 0;
for (let col = 0; col < columns.length; col++) {
// Check if each column has the symbol
const columnSymbols = [...columns[col].children].map(
(s) => s.dataset.symbolType
);
if (columnSymbols.includes(symbol)) {
consecutiveCount++;
} else {
break; // Stop checking if a column does not have the symbol
}
}
if (consecutiveCount >= 3) {
let lastColIndex = consecutiveCount - 1; // Get the last column index where the symbol was found
winningSymbols.push([symbol, lastColIndex]); // if there are 3 or more consecutive columns with the same symbol store the winning symbol
}
});
if (winningSymbols.length !== 0) {
await wait(1000);
tumble(winningSymbols);
} else {
console.log("gg");
}
};
const tumble = async (winningSymbols) => {
const allMatches = [];
for (let i = 0; i < winningSymbols.length; i++) {
for (let j = 0; j < winningSymbols[i][1] + 1; j++) {
const matches = columns[j].querySelectorAll(
`div[data-symbol-type="${winningSymbols[i][0]}"]`
);
allMatches.push(...matches);
}
}
allMatches.map(async (match) => {
match.classList.add("removing");
await wait(850);
match.remove();
});
await wait(200);
generateColumns();
await wait(350); // wait for symbols to drop down before checking
checkWins();
};
spinButton.addEventListener("click", () => {
startSpin();
});< /code>
body {
font-family: Arial, sans-serif;
background: radial-gradient(circle, #000000, #250136);
color: white;
text-align: center;
padding: 20px;
}
.slots-container {
display: flex;
justify-content: center;
gap: 10px;
padding: 20px;
background: #222;
border-radius: 10px;
}
.col {
display: flex;
flex-direction: column-reverse;
overflow-y: hidden;
gap: 5px;
min-height: 215px;
width: 60px;
background: rgba(255, 255, 255, 0.1);
border-radius: 5px;
padding: 10px;
}
.symbol {
font-size: 30px;
text-align: center;
background: white;
border-radius: 5px;
padding: 5px 0;
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
user-select: none;
}
.symbol.above-reel {
transform: translateY(-500%);
}
.symbol.removing {
animation: fadeOut 0.5s forwards;
}
@keyframes fadeOut {
to {
opacity: 0;
transform: scale(0);
}
}
/* Controls */
.controls {
display: flex;
justify-content: center;
gap: 20px;
margin-top: 20px;
}
#spin-button {
padding: 10px 25px;
font-weight: bold;
background: #f44336;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
#spin-button.spinning {
opacity: 0.5;
cursor: not-allowed;
pointer-events: none;
}
.box {
background: #333;
color: white;
padding: 10px;
border-radius: 5px;
min-width: 100px;
text-align: center;
}< /code>
Document
LAST WIN:
SPIN
Подробнее здесь:
https://stackoverflow.com/questions/797 ... a-css-grid
1754385837
Anonymous
Я строю игровой автомат, где символы (DOV) выкладываются в столбцах внутри гибкого контейнера. Когда будет обнаружен матч, я удаляю соответствующие элементы из DOM, а затем новые падают сверху. Тем не менее, поскольку удаление элементов вызывает рефвоу, переход не применяется, и элементы просто сдвигаются вниз, чтобы заполнить пустые пространства, которые были оставлены удаленными элементами. А затем после того, как эти недавно сгенерированные заполняют все, что осталось с хорошим переходом. Заставьте символы падать с гладкой анимацией, когда я удаляю символы под ним? PrettyPrint-Override ">[code]const symbols = ["🍒", "🍋", "🍇", "🔔"]; const columns = document.querySelectorAll(".col"); const spinButton = document.querySelector("#spin-button"); const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); const getRandomSymbol = () => { const randomIndex = Math.floor(Math.random() * symbols.length); return symbols[randomIndex]; }; const generateColumns = () => { [...columns].forEach((col) => { while (col.children.length < 4) { const symbol = getRandomSymbol(); const symbolElement = document.createElement("div"); symbolElement.textContent = symbol; symbolElement.dataset.symbolType = symbol; symbolElement.classList.add("symbol", "above-reel", "falling"); setTimeout(() => { symbolElement.style.transform = "translateY(0%)"; }, 300); col.appendChild(symbolElement); } }); }; const startSpin = async () => { let currentSymbols = document.querySelectorAll(".symbol"); currentSymbols.forEach((symbol) => { symbol.remove(); }); generateColumns(); await wait(400); checkWins(); }; const checkWins = async () => { let winningSymbols = []; symbols.forEach((symbol) => { // Check for each symbol let consecutiveCount = 0; for (let col = 0; col < columns.length; col++) { // Check if each column has the symbol const columnSymbols = [...columns[col].children].map( (s) => s.dataset.symbolType ); if (columnSymbols.includes(symbol)) { consecutiveCount++; } else { break; // Stop checking if a column does not have the symbol } } if (consecutiveCount >= 3) { let lastColIndex = consecutiveCount - 1; // Get the last column index where the symbol was found winningSymbols.push([symbol, lastColIndex]); // if there are 3 or more consecutive columns with the same symbol store the winning symbol } }); if (winningSymbols.length !== 0) { await wait(1000); tumble(winningSymbols); } else { console.log("gg"); } }; const tumble = async (winningSymbols) => { const allMatches = []; for (let i = 0; i < winningSymbols.length; i++) { for (let j = 0; j < winningSymbols[i][1] + 1; j++) { const matches = columns[j].querySelectorAll( `div[data-symbol-type="${winningSymbols[i][0]}"]` ); allMatches.push(...matches); } } allMatches.map(async (match) => { match.classList.add("removing"); await wait(850); match.remove(); }); await wait(200); generateColumns(); await wait(350); // wait for symbols to drop down before checking checkWins(); }; spinButton.addEventListener("click", () => { startSpin(); });< /code> body { font-family: Arial, sans-serif; background: radial-gradient(circle, #000000, #250136); color: white; text-align: center; padding: 20px; } .slots-container { display: flex; justify-content: center; gap: 10px; padding: 20px; background: #222; border-radius: 10px; } .col { display: flex; flex-direction: column-reverse; overflow-y: hidden; gap: 5px; min-height: 215px; width: 60px; background: rgba(255, 255, 255, 0.1); border-radius: 5px; padding: 10px; } .symbol { font-size: 30px; text-align: center; background: white; border-radius: 5px; padding: 5px 0; transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1); user-select: none; } .symbol.above-reel { transform: translateY(-500%); } .symbol.removing { animation: fadeOut 0.5s forwards; } @keyframes fadeOut { to { opacity: 0; transform: scale(0); } } /* Controls */ .controls { display: flex; justify-content: center; gap: 20px; margin-top: 20px; } #spin-button { padding: 10px 25px; font-weight: bold; background: #f44336; color: white; border: none; border-radius: 5px; cursor: pointer; } #spin-button.spinning { opacity: 0.5; cursor: not-allowed; pointer-events: none; } .box { background: #333; color: white; padding: 10px; border-radius: 5px; min-width: 100px; text-align: center; }< /code> Document LAST WIN: SPIN [/code] Подробнее здесь: [url]https://stackoverflow.com/questions/79725873/how-do-i-smoothly-animate-falling-elements-after-removing-items-from-a-css-grid[/url]