A Pen by Yariv Fruend on CodePen.
Created
April 13, 2018 04:08
-
-
Save e1blue/f51635fc341741b332c67eb0f8fc0b03 to your computer and use it in GitHub Desktop.
Simple Shooter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div class="container"> | |
| <div class="loading">טוען...</div> | |
| <div class="cover"> | |
| <div class="status"></div> | |
| <div class="instructions"> | |
| <div class="inner"> | |
| <div class="cell cell-1"></div> | |
| <div class="cell cell-2 "></div> | |
| <div class="cell cell-3"></div> | |
| <div class="cell cell-4"></div> | |
| <div class="show cell cell-5 key up"></div> | |
| <div class="cell cell-6"></div> | |
| <div class="cell cell-7"></div> | |
| <div class="show cell cell-8 key shoot"></div> | |
| <div class="cell cell-9"></div> | |
| <div class="show cell cell-10 key right"></div> | |
| <div class="show cell cell-11 key down"></div> | |
| <div class="show cell cell-12 key left"></div> | |
| <div class="show cell cell-13 label">יריה</div> | |
| <div class="show cell cell-14 label">תזוזה</div> | |
| </div> | |
| </div> | |
| <button class="play">התחל</button> | |
| <button class="replay">שוב!</button> | |
| </div> | |
| <div class="player"></div> | |
| <div class="enemy r-1 c-1"></div> | |
| <div class="enemy r-1 c-2"></div> | |
| <div class="enemy r-1 c-3"></div> | |
| <div class="enemy r-1 c-4"></div> | |
| <div class="enemy r-1 c-5"></div> | |
| <div class="enemy r-1 c-6"></div> | |
| <div class="enemy r-1 c-7"></div> | |
| <div class="enemy r-2 c-1"></div> | |
| <div class="enemy r-2 c-2"></div> | |
| <div class="enemy r-2 c-3"></div> | |
| <div class="enemy r-2 c-4"></div> | |
| <div class="enemy r-2 c-5"></div> | |
| <div class="enemy r-2 c-6"></div> | |
| <div class="enemy r-2 c-7"></div> | |
| </div> | |
| <div class="credits"> | |
| מוזיקה: <a href="https://www.youtube.com/watch?v=XblaHyMf3uw" target="_blank">BRD - Teleport Pro</a> | |
| </div> | |
| <audio class="music menu" src="//Yarivfruend.com/Portfolio/simple-shooter/sound/start-loop.ogg"/></audio> | |
| <audio class="music main" src="//Yarivfruend.com/Portfolio/simple-shooter/sound/game-loop.ogg"/></audio> | |
| <audio class="sound shoot" src="//Yarivfruend.com/Portfolio/simple-shooter/sound/shoot.wav"/></audio> | |
| <audio class="sound shoot-enemy" src="//Yarivfruend.com/Portfolio/simple-shooter/sound/shoot-enemy.wav"/></audio> | |
| <audio class="sound win" src="//Yarivfruend.com/Portfolio/simple-shooter/sound/win.wav"/></audio> | |
| <audio class="sound kill" src="//Yarivfruend.com/Portfolio/simple-shooter/sound/kill.wav"/></audio> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| let game = {}; | |
| game.hasEnded = false; | |
| game.keyPressMap = new Set(); // Keeps track of simulatneously pressed down keys | |
| game.loading = document.querySelector('.loading'); | |
| game.container = document.querySelector('.container'); | |
| game.cover = document.querySelector('.cover'); | |
| game.cover.status = document.querySelector('.cover > .status'); | |
| game.cover.replayButton = document.querySelector('.cover > .replay'); | |
| game.cover.playButton = document.querySelector('.cover > .play'); | |
| game.sound = {} | |
| game.sound.music = {} | |
| game.sound.effects = {} | |
| game.sound.music.menu = document.querySelector('.music.menu'); | |
| game.sound.music.main = document.querySelector('.music.main'); | |
| game.sound.effects.kill = document.querySelector('.sound.kill'); | |
| game.sound.effects.win = document.querySelector('.sound.win'); | |
| game.sound.effects.shoot = document.querySelector('.sound.shoot'); | |
| game.sound.effects.shootEnemy = document.querySelector('.sound.shoot-enemy'); | |
| // Set control values by the "key" property value of the event | |
| game.controls = {}; | |
| game.controls.moveUp = 'ArrowUp'; | |
| game.controls.moveDown = 'ArrowDown'; | |
| game.controls.moveLeft = 'ArrowLeft'; | |
| game.controls.moveRight = 'ArrowRight'; | |
| game.controls.shoot = ' '; // Empty string means the Space button | |
| game.player = {}; | |
| game.player.size = 4; | |
| game.player.avatar = document.querySelector('.player'); | |
| game.player.moveSpeed = 4; | |
| game.player.projectileSpeed = 10; | |
| game.enemies = new Set(); | |
| game.enemies.moveSpeed = 1; | |
| game.enemies.projectileSpeed = 3; | |
| game.enemies.attackSpeed = 4; // Higher => Slower | |
| game.projectileSize = 1; | |
| game.explosionSize = 3; | |
| game.showStart = () => { | |
| game.loading.remove(); | |
| game.cover.classList.add('start'); | |
| game.cover.status.textContent = 'משחק יריות פשוט'; | |
| game.setInstructions(); | |
| game.cover.toggle('show'); | |
| game.sound.music.menu.play(); | |
| } | |
| game.setInstructions = () => { | |
| let instructions = document.querySelector('.instructions'); | |
| let keyUpInstruct = document.querySelector('.key.up'); | |
| let keyLeftInstruct = document.querySelector('.key.left'); | |
| let keyDownInstruct = document.querySelector('.key.down'); | |
| let keyRightInstruct = document.querySelector('.key.right'); | |
| let keyShootInstruct = document.querySelector('.key.shoot'); | |
| keyUpInstruct.textContent = (game.controls.moveUp === 'ArrowUp') ? '▲' : game.controls.moveUp; | |
| keyLeftInstruct.textContent = (game.controls.moveLeft === 'ArrowLeft') ? '◄' : game.controls.moveLeft; | |
| keyDownInstruct.textContent = (game.controls.moveDown === 'ArrowDown') ? '▼' : game.controls.moveDown; | |
| keyRightInstruct.textContent = (game.controls.moveRight === 'ArrowRight') ? '►' : game.controls.moveRight; | |
| keyShootInstruct.textContent = game.controls.shoot; | |
| if (game.controls.shoot === ' ') { | |
| instructions.style.padding = '15px 21px 15px 25px'; | |
| keyShootInstruct.textContent = 'space'; | |
| keyShootInstruct.style.width = '105px'; | |
| } | |
| } | |
| game.initialize = () => { | |
| game.sound.music.menu.pause(); | |
| game.sound.music.main.play(); | |
| game.projectileSize = game.projectileSize * 10; | |
| game.initializePlayer(); | |
| game.initializeEnemies(); | |
| document.addEventListener('keydown', game.handleKeyDown); | |
| document.addEventListener('keyup', game.handleKeyUp); | |
| } | |
| game.initializePlayer = () => { | |
| let player = game.player.avatar; | |
| player.style.width = 10 * game.player.size + 'px'; | |
| player.style.height = 10 * game.player.size + 'px'; | |
| player.style.left = (game.container.clientWidth / 2) - (game.player.avatar.clientWidth / 2) + 'px'; // X | |
| player.style.top = game.container.clientHeight - 100 + 'px'; // Y | |
| } | |
| game.initializeEnemies = () => { | |
| let enemies = document.querySelectorAll('.enemy') | |
| for (let enemy of enemies) { | |
| game.enemies.add(enemy); | |
| enemy.style.display = 'block'; | |
| } | |
| game.enemies.oscillate(); | |
| game.enemies.attack = window.setInterval(() => { | |
| game.enemies.shoot(); | |
| }, game.enemies.attackSpeed * 100); | |
| } | |
| game.createProjectile = (shooter) => { | |
| let projectile = document.createElement("div"); | |
| projectile.classList.add('projectile'); | |
| projectile.style.height = game.projectileSize + 'px'; | |
| projectile.style.width = game.projectileSize / 2 + 'px'; | |
| projectile.style.left = (shooter.offsetLeft + shooter.clientWidth / 2 - game.projectileSize / 2) + 'px'; | |
| projectile.style.top = (shooter.offsetTop + shooter.clientHeight) + 'px'; | |
| projectile = projectile.cloneNode(); | |
| switch (shooter.classList[0]) { | |
| case 'player': | |
| projectile.classList.add('friendly'); | |
| projectile.style.top = shooter.offsetTop + 'px'; | |
| break; | |
| } | |
| game.container.append(projectile); | |
| return projectile; | |
| } | |
| game.collision = (projectile) => { | |
| let projectileTop = Number(projectile.style.top.replace(/\D/g, '')); | |
| let projectileLeft = Number(projectile.style.left.replace(/\D/g, '')); | |
| let projectileWidth = Number(window.getComputedStyle(projectile, null).getPropertyValue("width").replace(/\D/g, '')); | |
| // Enemy is hit. | |
| if (projectile.classList.contains('friendly')) { | |
| for (let enemy of game.enemies) { | |
| if (projectileTop < (enemy.offsetTop + enemy.clientHeight) && | |
| projectileLeft + projectileWidth / 2 > enemy.offsetLeft - projectileWidth / 2 && | |
| projectileLeft + projectileWidth / 2 < enemy.offsetLeft + enemy.clientWidth + projectileWidth / 2 | |
| ) { | |
| game.createExplosion(projectileTop, projectileLeft); | |
| game.sound.effects.kill.currentTime = 0; | |
| game.sound.effects.kill.play(); | |
| game.enemies.delete(enemy); | |
| enemy.remove(); | |
| return true; | |
| } | |
| } | |
| // Player is hit. | |
| } else if (projectileTop + game.projectileSize > game.player.avatar.offsetTop && | |
| projectileTop < game.player.avatar.offsetTop + game.player.avatar.clientHeight && | |
| projectileLeft + projectileWidth / 2 > game.player.avatar.offsetLeft - projectileWidth / 2 && | |
| projectileLeft + projectileWidth / 2 < game.player.avatar.offsetLeft + game.player.avatar.clientWidth + projectileWidth / 2 | |
| ) { | |
| // Lose game when player is hit | |
| if (!game.hasEnded) { | |
| // projectile.style.backgroundColor = 'red'; | |
| game.isOver('defeat'); | |
| } | |
| } | |
| } | |
| game.createExplosion = (hitLocationTop, hitLocationLeft) => { | |
| let explosion = document.createElement("div"); | |
| explosion.classList.add('explosion'); | |
| explosion.style.height = game.explosionSize * 10 + 'px'; | |
| explosion.style.width = game.explosionSize * 10 + 'px'; | |
| explosion.style.left = hitLocationLeft + 'px'; | |
| explosion.style.top = hitLocationTop + 'px'; | |
| explosion = explosion.cloneNode(); | |
| game.container.append(explosion); | |
| explosion.addEventListener('animationend', () => { | |
| explosion.remove(); | |
| }); | |
| } | |
| game.isOver = (result) => { | |
| game.hasEnded = true; | |
| document.removeEventListener('keydown', game.handleKeyDown); | |
| document.removeEventListener('keyup', game.handleKeyUp); | |
| game.enemies.projectileSpeed = 0; | |
| game.player.projectileSpeed = 0; | |
| clearInterval(game.enemies.attack); | |
| game.enemies.clear(); | |
| switch (result) { | |
| case 'victory': | |
| game.sound.effects.win.play(); | |
| game.cover.status.classList.add('victory'); | |
| game.cover.classList.add('victory'); | |
| game.cover.status.textContent = 'ניצחון!'; | |
| break; | |
| case 'defeat': | |
| game.sound.effects.kill.currentTime = 0; | |
| game.sound.effects.kill.play(); | |
| game.cover.status.classList.add('defeat'); | |
| game.cover.classList.add('defeat'); | |
| game.cover.status.textContent = 'game over'; | |
| break; | |
| } | |
| game.cover.toggle('show'); | |
| } | |
| game.cover.toggle = (state) => { | |
| switch (state) { | |
| case 'show': | |
| game.cover.classList.add('active'); | |
| break; | |
| case 'hide': | |
| game.cover.classList.remove('active'); | |
| break; | |
| } | |
| } | |
| game.player.move = (direction) => { | |
| (function step() { | |
| switch (direction) { | |
| case game.controls.moveUp: | |
| if (game.player.avatar.offsetTop > 0) { | |
| game.player.avatar.style.top = Number(game.player.avatar.style.top.replace(/\D/g, '')) - game.player.moveSpeed + 'px'; | |
| } | |
| break; | |
| case game.controls.moveDown: | |
| if (game.player.avatar.offsetTop < game.container.clientHeight - game.player.avatar.clientHeight) { | |
| game.player.avatar.style.top = Number(game.player.avatar.style.top.replace(/\D/g, '')) + game.player.moveSpeed + 'px'; | |
| } | |
| break; | |
| case game.controls.moveLeft: | |
| if (game.player.avatar.offsetLeft > 0) { | |
| game.player.avatar.style.left = Number(game.player.avatar.style.left.replace(/\D/g, '')) - game.player.moveSpeed + 'px'; | |
| } | |
| break; | |
| case game.controls.moveRight: | |
| if (game.player.avatar.offsetLeft < game.container.clientWidth - game.player.avatar.clientWidth) { | |
| game.player.avatar.style.left = Number(game.player.avatar.style.left.replace(/\D/g, '')) + game.player.moveSpeed + 'px'; | |
| } | |
| break; | |
| } | |
| if (game.keyPressMap.has(direction) && !game.hasEnded) { | |
| window.requestAnimationFrame(step); | |
| } | |
| })(); | |
| } | |
| game.player.shoot = () => { | |
| let projectile = game.createProjectile(game.player.avatar); | |
| // Recoil animation | |
| game.player.avatar.classList.remove('recoil'); | |
| game.player.avatar.classList.add('recoil'); | |
| game.player.avatar.addEventListener('animationend', () => { | |
| game.player.avatar.classList.remove('recoil'); | |
| }) | |
| // Shooting sound | |
| game.sound.effects.shoot.currentTime = 0; | |
| game.sound.effects.shoot.play(); | |
| (function projection() { | |
| projectile.style.top = Number(projectile.style.top.replace(/\D/g, '')) - game.player.projectileSpeed + 'px'; | |
| // Detect collision or exit of bounds | |
| if (Number(projectile.style.top.replace(/\D/g, '')) > 5 && !game.collision(projectile)) { | |
| window.requestAnimationFrame(projection); | |
| } else { | |
| projectile.remove(); | |
| // Win game when all enemies are defeated | |
| if (!game.enemies.size) { | |
| game.isOver('victory'); | |
| } | |
| } | |
| })(); | |
| } | |
| game.enemies.oscillate = () => { | |
| // Animate enemies | |
| (function oscillation() { | |
| for (var enemy of game.enemies) { | |
| if (enemy.classList.contains('r-1')) { | |
| enemy.style.left = enemy.offsetLeft + game.enemies.moveSpeed + 'px'; | |
| if (enemy.offsetLeft > game.container.clientWidth) { | |
| enemy.style.left = 0 - enemy.clientWidth + 'px'; | |
| } | |
| } else if (enemy.classList.contains('r-2')) { | |
| enemy.style.left = enemy.offsetLeft - game.enemies.moveSpeed + 'px'; | |
| if ((enemy.offsetLeft + enemy.clientWidth) < 0) { | |
| enemy.style.left = game.container.clientWidth + 'px'; | |
| } | |
| } | |
| } | |
| if (game.enemies) { | |
| window.requestAnimationFrame(oscillation); | |
| } | |
| })(); | |
| } | |
| game.enemies.shoot = () => { | |
| let enemyArr = Array.from(game.enemies); | |
| let randomEnemy = enemyArr[Math.floor(Math.random() * enemyArr.length)]; | |
| let projectile = game.createProjectile(randomEnemy); | |
| // Shooting sound | |
| game.sound.effects.shootEnemy.currentTime = 0; | |
| game.sound.effects.shootEnemy.play(); | |
| (function projection() { | |
| projectile.style.top = Number(projectile.style.top.replace(/\D/g, '')) + game.enemies.projectileSpeed + 'px'; | |
| // Detect collision or exit of bounds | |
| if (Number(projectile.style.top.replace(/\D/g, '')) < (game.container.clientHeight) && !game.collision(projectile)) { | |
| window.requestAnimationFrame(projection); | |
| } else { | |
| projectile.remove(); | |
| } | |
| })(); | |
| } | |
| game.handleKeyDown = (e) => { | |
| if (!game.keyPressMap.has(e.key)) { | |
| game.keyPressMap.add(e.key); | |
| if (e.key === game.controls.moveUp || e.key === game.controls.moveDown || e.key === game.controls.moveLeft || e.key === game.controls.moveRight) { | |
| game.player.move(e.key); | |
| } else if (e.key === game.controls.shoot) { | |
| game.player.shoot(); | |
| } | |
| } | |
| } | |
| game.handleKeyUp = (e) => { | |
| game.keyPressMap.delete(e.key); | |
| } | |
| game.cover.playButton.addEventListener('click', () => { | |
| game.cover.classList.remove('start'); | |
| game.cover.toggle('hide'); | |
| game.initialize(); | |
| }) | |
| game.cover.replayButton.addEventListener('click', () => { | |
| window.location.reload(false); | |
| }) | |
| window.addEventListener('load', () => { | |
| game.showStart(); | |
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| :root { | |
| --background: white; | |
| --accent: #333; | |
| --player: white; | |
| --enemy: #333; | |
| --enemies-start-x: 38px; | |
| --enemies-start-y: 40px; | |
| } | |
| body { | |
| direction: rtl; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| height: 100vh; | |
| margin: 0; | |
| flex-direction: column; | |
| } | |
| body, | |
| button { | |
| font-family: 'Varela Round', sans-serif; | |
| } | |
| .cover { | |
| display: none; | |
| position: absolute; | |
| top: 0; | |
| right: 0; | |
| bottom: 0; | |
| left: 0; | |
| background-color: var(--background); | |
| z-index: 1; | |
| color: var(--accent); | |
| justify-content: space-evenly; | |
| align-items: center; | |
| font-size: 50px; | |
| text-transform: uppercase; | |
| flex-direction: column; | |
| } | |
| .cover.active { | |
| display: flex; | |
| } | |
| .cover>.status { | |
| border: solid 3px #333; | |
| border-radius: 10px; | |
| padding: 0 15px; | |
| } | |
| .cover>.status.victory { | |
| font-size: 70px; | |
| border: 0; | |
| color: white; | |
| box-shadow: 0 0 0px 1px #ccc; | |
| animation: vibrate 100ms linear infinite forwards, color-cycle 800ms linear infinite forwards; | |
| } | |
| .cover>.status.defeat { | |
| padding-top: 3px; | |
| background-color: orangered; | |
| color: white; | |
| border: 0; | |
| animation: pulse 500ms cubic-bezier(0.12, 0.11, 0.27, 1.55) 1 forwards; | |
| } | |
| .instructions { | |
| width: 45%; | |
| font-size: 12px; | |
| border: solid 3px #333; | |
| border-radius: 10px; | |
| padding: 15px 5px 15px 25px | |
| } | |
| .instructions>.inner { | |
| display: grid; | |
| grid-template-columns: repeat(6, 1fr); | |
| text-align: center; | |
| grid-gap: 3px; | |
| } | |
| .instructions>.inner>.cell:not(.show) { | |
| visibility: hidden; | |
| } | |
| .instructions>.inner>.cell-13 { | |
| grid-column: 1 / 4; | |
| grid-row: 4; | |
| } | |
| .instructions>.inner>.cell-14 { | |
| grid-column: 4 / 7; | |
| grid-row: 4; | |
| } | |
| .instructions>.inner>.key { | |
| background-color: #333; | |
| color: white; | |
| font-size: 20px; | |
| height: 35px; | |
| width: 35px; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| border-radius: 5px; | |
| } | |
| .instructions>.inner>.label { | |
| color: var(--accent); | |
| background-color: transparent; | |
| font-size: 16px; | |
| font-weight: bold; | |
| border-top: dotted 3px #333; | |
| padding-top: 5px; | |
| margin: 3px 25px 0; | |
| } | |
| button { | |
| font-weight: bold; | |
| cursor: pointer; | |
| background-color: transparent; | |
| border: solid 3px var(--accent); | |
| font-size: 30px; | |
| padding: 10px 10px; | |
| border-radius: 10px; | |
| transition: all 100ms ease; | |
| text-transform: uppercase; | |
| } | |
| button:hover { | |
| letter-spacing: 2px; | |
| padding: 10px 13px; | |
| border-radius: 8px; | |
| } | |
| button:active { | |
| transform: scale(0.95); | |
| } | |
| .cover>button.replay, | |
| .cover>button.play, | |
| .instructions { | |
| display: none; | |
| } | |
| .cover.active.victory>button.replay, | |
| .cover.active.defeat>button.replay, | |
| .cover.active.start>button.play, | |
| .cover.active.start>.instructions { | |
| display: block; | |
| } | |
| .cover, | |
| .container { | |
| border-radius: 20px; | |
| } | |
| .container { | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| width: 500px; | |
| height: 500px; | |
| border: solid 3px var(--accent); | |
| background-color: var(--background); | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .loading { | |
| background-color: white; | |
| z-index: 1; | |
| font-size: 50px; | |
| } | |
| .player { | |
| position: absolute; | |
| background-color: var(--player); | |
| border: solid 3px var(--accent); | |
| border-radius: 50%; | |
| } | |
| .player.recoil { | |
| animation: recoil 100ms ease 1 forwards; | |
| } | |
| .projectile { | |
| border-radius: 5px; | |
| position: absolute; | |
| background-color: var(--enemy); | |
| } | |
| .projectile.friendly { | |
| background-color: var(--player); | |
| border: solid 3px var(--accent); | |
| } | |
| .explosion { | |
| position: absolute; | |
| background-color: var(--enemy); | |
| border-radius: 50%; | |
| animation: explode 200ms linear 1 forwards; | |
| } | |
| .enemy { | |
| display: none; | |
| position: absolute; | |
| height: 40px; | |
| width: 40px; | |
| background-color: var(--enemy); | |
| border-radius: 7px; | |
| animation: rotate 1s linear infinite forwards; | |
| } | |
| .enemy.r-1 { | |
| top: calc(var(--enemies-start-y) * 3); | |
| } | |
| .enemy.r-2 { | |
| top: var(--enemies-start-y); | |
| } | |
| .enemy.c-1 { | |
| left: var(--enemies-start-x); | |
| } | |
| .enemy.c-2 { | |
| left: calc(var(--enemies-start-x) * 3); | |
| } | |
| .enemy.c-3 { | |
| left: calc(var(--enemies-start-x) * 5); | |
| } | |
| .enemy.c-4 { | |
| left: calc(var(--enemies-start-x) * 7); | |
| } | |
| .enemy.c-5 { | |
| left: calc(var(--enemies-start-x) * 9); | |
| } | |
| .enemy.c-6 { | |
| left: calc(var(--enemies-start-x) * 11); | |
| } | |
| .enemy.c-7 { | |
| left: calc(var(--enemies-start-x) * 13); | |
| } | |
| .credits { | |
| padding: 5px; | |
| } | |
| .credits>a { | |
| color: var(--accent); | |
| } | |
| @keyframes rotate { | |
| 0% { | |
| transform: rotate(0); | |
| } | |
| 100% { | |
| transform: rotate(360deg); | |
| } | |
| } | |
| @keyframes recoil { | |
| 0% { | |
| transform: translate(0, 0); | |
| } | |
| 50% { | |
| transform: translate(0, 10px); | |
| } | |
| 100% { | |
| transform: translate(0, 0); | |
| } | |
| } | |
| @keyframes vibrate { | |
| 0% { | |
| transform: translate(0, 0); | |
| } | |
| 50% { | |
| transform: translate(0, -5px); | |
| } | |
| 100% { | |
| transform: translate(0, 0); | |
| } | |
| } | |
| @keyframes color-cycle { | |
| 0% { | |
| background-color: orangered; | |
| } | |
| 20% { | |
| background-color: orange; | |
| } | |
| 40% { | |
| background-color: yellow; | |
| } | |
| 60% { | |
| background-color: limegreen; | |
| } | |
| 80% { | |
| background-color: dodgerblue; | |
| } | |
| 100% { | |
| background-color: orangered; | |
| } | |
| } | |
| @keyframes pulse { | |
| 0% { | |
| transform: scale(1); | |
| } | |
| 50% { | |
| transform: scale(1.25); | |
| } | |
| 100% { | |
| transform: scale(1); | |
| } | |
| } | |
| @keyframes explode { | |
| 0% { | |
| transform: scale(1); | |
| opacity: 1; | |
| } | |
| 100% { | |
| transform: scale(1.5); | |
| opacity: 0; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment