I have a animation whose duration
decreases each time black jumps(using space) over the red, it works fine that subsequent jumps reduces the duration
.
But after a certain decrease in time, say after reducing to 4s
,3.9s
,3.8s
..., the animation don't start from the right-most end which is supposed to be. As it is decided path(110vw) in @keyframes animateVillan
Is there something I am doing wrong, first thought it is a glitch kind and decided to change duration only when red reaches less than 10 and tried below part
if (ourVillanFigXValue < 10) {
ourVillanFig.style.animationDuration = ourVillanAnimeDuration - 0.1 "s";
}
But this didn't solve the problem and path is not completely traced by the red
Sorry have to jump a little, 4 or 5 jumps only to see the error plz
let ourHeroFig = document.getElementById("ourHero");
let ourVillanFig = document.getElementById("obstacleBar");
let gameScoreDigits = document.getElementById("gameScoreDigits");
let valueXCoordinate = "";
let obstacleBarCrossed = true;
document.body.addEventListener('keydown', function(e) {
let ourHeroFigXValue = parseInt(getComputedStyle(ourHeroFig).getPropertyValue('left'));
let ourHeroFigYValue = parseInt(getComputedStyle(ourHeroFig).getPropertyValue('bottom'));
if (e.code === "ArrowRight") {
valueXCoordinate = ourHeroFigXValue 100;
} else if (e.code === "KeyA" || e.code === "ArrowLeft") {
if (ourHeroFigXValue > ourHeroFig.offsetWidth 90) {
valueXCoordinate = ourHeroFigXValue - 100;
} else {
valueXCoordinate = 0;
}
} else if (e.code === "Space") {
ourHeroFig.classList.add("animateHero");
setTimeout(function() {
ourHeroFig.classList.remove("animateHero");
}, 700)
}
changePosition();
})
function changePosition() {
ourHeroFig.style.left = valueXCoordinate 'px'
}
let delayInAnimeSub = ""
setInterval(
function() {
let ourHeroFigXValue = parseInt(getComputedStyle(ourHeroFig).getPropertyValue('left'));
let ourHeroFigYValue = parseInt(getComputedStyle(ourHeroFig).getPropertyValue('bottom'));
let ourVillanFigXValue = parseInt(getComputedStyle(ourVillanFig).getPropertyValue('left'));
let ourVillanFigYValue = parseInt(getComputedStyle(ourVillanFig).getPropertyValue('bottom'));
let gameOverValueX = Math.abs(ourVillanFigXValue - ourHeroFigXValue);
let gameOverValueY = Math.abs(ourVillanFigYValue - ourHeroFigYValue);
if (ourVillanFigXValue < 10) {
ourVillanFig.style.animationDuration = ourVillanAnimeDuration - 0.3 "s";
}
if (gameOverValueX < ourVillanFig.offsetWidth && gameOverValueY < ourVillanFig.offsetHeight) {
console.log("yes touched");
ourVillanFig.classList.remove("animateVillan");
obstacleBarCrossed = false;
} else if (obstacleBarCrossed && gameOverValueX < ourVillanFig.offsetWidth) {
ourVillanAnimeDuration = parseFloat(getComputedStyle(ourVillanFig).getPropertyValue('animation-duration'));
console.log(ourVillanFigXValue < 0, ourVillanAnimeDuration)
if (ourVillanAnimeDuration <= 2) {
ourVillanAnimeDuration = 2
}
}
// console.log(gameOverValueX,gameOverValueY)
}, 10);
#ourHero {
width: 20px;
height: 180px;
background-color: black;
position: fixed;
bottom: 0;
left: 0;
transition: 0.1s;
}
.animateHero {
animation: animateHero 0.7s linear;
}
@keyframes animateHero {
0% {
bottom: 0;
}
50% {
bottom: 350px;
}
100% {
bottom: 0;
}
}
#obstacleBar {
width: 20px;
height: 180px;
background-color: red;
position: fixed;
bottom: 0;
left: 50vw;
}
.animateVillan {
animation: animateVillan 5s linear infinite;
}
@keyframes animateVillan {
0% {
left: 110vw;
}
100% {
left: 0;
}
}
<div id="ourHero"></div>
<div id="obstacleBar" class="animateVillan"></div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Thanks for help in advance
CodePudding user response:
First make the red thing starts from far right so change left: 50vw;
to something like left: 110vw;
. Also, instead of the infinite animation, just remove the animateVillan
class after the red gets out of screen then re-add it again. Can be done by using an animationend
event handler:
ourVillanFig.addEventListener('animationend', () => {
ourVillanFig.classList.remove('animateVillan')
ourVillanFig.clientHeight // just to cause a reflow
ourVillanFig.classList.add('animateVillan')
})
or maybe by checking its x position and see when it gets out.
Here is the result. It seems that it is working just fine without any glitches:
EDIT: To make the red stops where it is when it touches black, you can make the following css class:
.pauseVillan {
animation-play-state: paused;
}
and then when the red gets in touch just add the pauseVillan
class to it:
ourVillanFig.classList.add('pauseVillan')
Here is the updated snippet:
let ourHeroFig = document.getElementById('ourHero')
let ourVillanFig = document.getElementById('obstacleBar')
let gameScoreDigits = document.getElementById('gameScoreDigits')
let valueXCoordinate = ''
let obstacleBarCrossed = true
document.body.addEventListener('keydown', function(e) {
let ourHeroFigXValue = parseInt(
getComputedStyle(ourHeroFig).getPropertyValue('left')
)
let ourHeroFigYValue = parseInt(
getComputedStyle(ourHeroFig).getPropertyValue('bottom')
)
if (e.code === 'ArrowRight') {
valueXCoordinate = ourHeroFigXValue 100
} else if (e.code === 'KeyA' || e.code === 'ArrowLeft') {
if (ourHeroFigXValue > ourHeroFig.offsetWidth 90) {
valueXCoordinate = ourHeroFigXValue - 100
} else {
valueXCoordinate = 0
}
} else if (e.code === 'Space') {
ourHeroFig.classList.add('animateHero')
setTimeout(function() {
ourHeroFig.classList.remove('animateHero')
}, 700)
}
changePosition()
})
ourVillanFig.addEventListener('animationend', () => {
ourVillanFig.classList.remove('animateVillan')
ourVillanFig.clientHeight // just to cause a reflow
ourVillanFig.classList.add('animateVillan')
})
function changePosition() {
ourHeroFig.style.left = valueXCoordinate 'px'
}
let delayInAnimeSub = ''
setInterval(function() {
let ourHeroFigXValue = parseInt(
getComputedStyle(ourHeroFig).getPropertyValue('left')
)
let ourHeroFigYValue = parseInt(
getComputedStyle(ourHeroFig).getPropertyValue('bottom')
)
let ourVillanFigXValue = parseInt(
getComputedStyle(ourVillanFig).getPropertyValue('left')
)
let ourVillanFigYValue = parseInt(
getComputedStyle(ourVillanFig).getPropertyValue('bottom')
)
let gameOverValueX = Math.abs(ourVillanFigXValue - ourHeroFigXValue)
let gameOverValueY = Math.abs(ourVillanFigYValue - ourHeroFigYValue)
if (ourVillanFigXValue < 10) {
ourVillanFig.style.animationDuration =
ourVillanAnimeDuration - 0.3 's'
}
if (
gameOverValueX < ourVillanFig.offsetWidth &&
gameOverValueY < ourVillanFig.offsetHeight
) {
console.log('yes touched')
ourVillanFig.classList.add('pauseVillan')
obstacleBarCrossed = false
} else if (
obstacleBarCrossed &&
gameOverValueX < ourVillanFig.offsetWidth
) {
ourVillanAnimeDuration = parseFloat(
getComputedStyle(ourVillanFig).getPropertyValue('animation-duration')
)
console.log(ourVillanFigXValue < 0, ourVillanAnimeDuration)
if (ourVillanAnimeDuration <= 2) {
ourVillanAnimeDuration = 2
}
}
// console.log(gameOverValueX,gameOverValueY)
}, 10)
#ourHero {
width: 20px;
height: 180px;
background-color: black;
position: fixed;
bottom: 0;
left: 0;
transition: 0.1s;
}
.animateHero {
animation: animateHero 0.7s linear;
}
@keyframes animateHero {
0% {
bottom: 0;
}
50% {
bottom: 350px;
}
100% {
bottom: 0;
}
}
#obstacleBar {
width: 20px;
height: 180px;
background-color: red;
position: fixed;
bottom: 0;
left: 110vw;
}
.animateVillan {
animation: animateVillan 4s linear;
}
.pauseVillan {
animation-play-state: paused;
}
@keyframes animateVillan {
0% {
left: 110vw;
}
100% {
left: 0;
}
}
<div id="ourHero"></div>
<div id="obstacleBar" class="animateVillan"></div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>