Home > other >  How to decrease anime time when it is out of screen
How to decrease anime time when it is out of screen

Time:11-10

I have a anime whose duration decreases when the black container crosses red, but this creates glitches. Can there be any method to remove the glitch in it.

I tried to delay the changes until path is completed by red but still faces the glitches.

delayInAnimeSub = ourVillanAnimeDuration * (ourVillanFigXValue / window.innerWidth)
animeDelayAmount = Math.abs(delayInAnimeSub.toFixed(2) - 0.2).toFixed(2);

I calculated the leftover distance of red from the left side and get the duration to complete that distance and added that to delay. But it still show glitches.

Here what happens in below snippet

  • Black box is hero which is controlled by space(to jump), <(to move left), >(to move right).
  • Red is villan(demon) which have animation to move from right side to left side with some duration in animation.
  • Whenever hero passes the red, red becomes faster(by trying to reduce animation duration), but with this red has glitches and start from anywhere(not from the place it should be next).
  • I want to increase speed of red but facing the glitches so tried to delay the change in animation duration until red crosses the screen but that didn't seems to work

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 (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'));
      delayInAnimeSub = ourVillanAnimeDuration * (ourVillanFigXValue / window.innerWidth)
      animeDelayAmount = Math.abs(delayInAnimeSub.toFixed(2) - 0.2).toFixed(2);
      console.log(animeDelayAmount, ourVillanAnimeDuration, ourVillanFigXValue)
      if (ourVillanAnimeDuration <= 2) {
        ourVillanAnimeDuration = 2
      }
      setTimeout(() => {
        ourVillanFig.style.animationDuration = ourVillanAnimeDuration - 0.1   "s";
      }, animeDelayAmount);
    }
    // console.log(gameOverValueX,gameOverValueY)
  }, 10);
#ourHero {
  width: 20px;
  height: 100px;
  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: 100px;
  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:

One way is to use Animation.playbackRate but it is still experimental.

let VillRate = 1
...

// inside the collision check

if (VillRate < 20) {
  ourVillanFig.getAnimations()[0].playbackRate  = 0.2
  VillRate  = 0.5
}

In the below snippet, red speed will increase untill a certain point everytime it touches black. You can adjust that behavior as you need.

let ourHeroFig = document.getElementById('ourHero')
let ourVillanFig = document.getElementById('obstacleBar')
let gameScoreDigits = document.getElementById('gameScoreDigits')
let valueXCoordinate = ''
let obstacleBarCrossed = true

let VillRate = 1

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 (
    gameOverValueX < ourVillanFig.offsetWidth &&
    gameOverValueY < ourVillanFig.offsetHeight
  ) {
    if (VillRate < 20) {
      ourVillanFig.getAnimations()[0].playbackRate  = 0.2
      VillRate  = 0.5
    }
  }
}, 10)
#ourHero {
  width: 20px;
  height: 100px;
  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: 100px;
  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="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

I tried this:

 if (ourVillanFigXValue < 10) {
    ourVillanFig.style.animationDuration = ourVillanAnimeDuration - 0.1   "s";
  }

It works ok but when time get reduced to 4s and after it, the red don't start from the end but start in between. Almost start from middle at 3s

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.1   "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="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related