Ways to reduce the amount of time spent watching anime when it is not in view

My anime experiences glitches as the black container crosses the red, causing a decrease in duration. Is there a way to fix this glitch?

I attempted to delay the changes until the red path is completed, but the glitches persist.

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

I calculated the remaining distance of the red from the left side and determined the duration needed to cover that distance before adding it to the delay. However, the glitches still occur.

Below is the explanation of what happens:

  • The black box represents the hero controlled by space (to jump), < (to move left), > (to move right).
  • The red box represents the villain(demon) with an animation moving from right to left with a specific duration.
  • When the hero passes the red box, the red box speeds up by reducing the animation duration, leading to glitches where it starts from unexpected places.
  • I tried delaying the change in animation duration until the red box clears the screen, but it did not solve the issue.

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>

Your assistance is greatly appreciated. Thank you!

Answer №1

There is a method that involves using Animation.playbackRate, which is still in the experimental stage.

let VillRate = 1
...

// within the collision check

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

In the following code snippet, the speed of the red object will increase until a certain point every time it touches the black object. You can customize this behavior as needed.

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>

Answer №2

I attempted the following:

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

It seems to be working fine, but when the time is reduced to 4s and beyond that, the red doesn't start from the end but rather starts in between. It almost begins from the middle at around 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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to adjust the background color of the clicked tab with divs and revert the others back to their original color?

<span class="row top-bar-left align-items-center" style="width: 80%; float:left"> <div tabindex="1" class="link tab" routerLink="details" routerLinkActive="active" [qu ...

Improving the retrieval of API data using personalized React hooks when searching by modifying keywords

I'm just starting out with React Hooks and recently wrote a small code snippet that displays a list of courses to users. This code includes two main components, CourseList and Course, as well as a custom hook called useCourseList. Here's the code ...

Unable to access an element using jquery

This is an example of an HTML file: <div id ="main"> </div> Here is the JavaScript code: //creating a new div element var divElem = $('<div class="divText"></div>'); //creating an input element inside the div var i ...

Tips for showing nested JSON data in a PrimeNG table within Angular version 7

I am struggling to display nested json data in a PrimeNG table. When I retrieve the data using an HTTP service, it appears as [object][object] when displayed directly in the table. What I want is to show the nested json data with keys and values separated ...

Implementing complex routing with Express.js on top of Node.js

Recently delving into the world of javascript, I have embarked on creating a RESTful API using Node.js and Express.js Here is the breakdown of my directory structure: /server.js /api/api.js /api/location/location.js My goal is to make the API modular, ...

Understanding the error handling in Express.js

Learning about error handling in express is new to me and I have a straightforward piece of code like this - const express = require('express'); const MongoClient = require('mongodb').MongoClient; const app = express(); let url = &a ...

CSS styles may not be consistently displayed or may vanish after being initially implemented

The colors and background remain unchanged. In previous projects, everything ended up falling apart Refreshing the page with F5 or CTRL + F5 does not make a difference. When using Open Live Server in VS Code, it initially shows the changes being applied b ...

The 3D Circle Flip feature on a certain webpage designed by Nordstrom is experiencing issues when viewed on Firefox

Click here to see a 3D Circle Flip effect. It works correctly in Chrome, but in Firefox the text does not change when flipping. ...

The AJAX POST request is not receiving the JSON data as expected

After creating an HTML form with the following structure: <form id="loginForm" name="loginForm"> <div class="form-group"> <input type="username" class="form-control" id="username" name="username" placeholder="Your username..." > ...

Retrieving JSON data with Node.js

Receiving a JSON response from TMDB: { "id": 283350, "results": [ { "iso_3166_1": "BR", "release_dates": [ { "certification": "12", "iso_639_1": "pt", "note": "Streaming", "release_date": ...

Unable to fetch permissions for user:email via GitHub API

Currently, I am utilizing node-fetch to fetch an OAuth2 token from an OAuth2 GitHub App. The obtained token allows me to successfully retrieve user information from "https://api.github.com/user". However, I also require the email address, which necessitate ...

Warning: Non-power of two image detected in Three.js

Encountering an issue with a warning in three.js that says: THREE.WebGLRenderer: image is not power of two (600x480). Resized to 512x512. Attempted to resolve it by adding THREE.LinearFilter, but no luck. var texture = new THREE.TextureLoader().load(data[ ...

What is the best method for fetching the values of a select element in React.js?

I'm struggling to retrieve the value of a selected element in a dropdown list. I've tried debugging it, but haven't been able to get the value. I attempted to console log e.target.value, but unfortunately, it didn't work. Any thoughts o ...

Using MeanJS to assign a Mongoose object reference to an array in Angular

Having an issue with MeanJS and using the $update function of the $resource service in Angular provided by MeanJS. Here is a basic outline of my problem: Mongoose schema: var mongoose = require('mongoose'), Schema = mongoose.Schema; var Lotion ...

The random number generator often omits both the upper and lower limits

I am working with an array that contains letters from A to H. However, when using a random number generator, I have noticed that the letters A and H are rarely selected. How can I adjust my approach to make sure these two bounds are included more often? ...

Tips for including background pictures in the jumbotron using bootstrap

I've recently delved into bootstrap just a couple of days ago. Now, I'm encountering an issue where I can't seem to add a background image to my entire webpage or even the jumbotron specifically. I've attempted to directly input the pa ...

Partial data is being received from the Ajax call

I currently have a textarea and a button on my webpage <textarea id="xxx" class="myTextArea" name="Text1" cols="40" rows="15">@ViewData["translation"]</textarea> <input type="button" id="convert-btn" class="btn btn-primary" value="Convert t ...

Combining Multiple .ts Files into a Single File: A Simplified Application Structure with TypeScript 1.8

Currently, I am in the process of developing an Electron application and I have decided to implement TypeScript for this project. While TypeScript essentially boils down to JavaScript in the end, my familiarity with it makes the transition seamless. As of ...

Is there a way to alter multiple classes using hover effect on a single class without the use of JavaScript, only employing

Hello there! I have a question about applying styles to specific classes when hovering over certain elements. Unfortunately, I am unable to make changes to the HTML files and can only work with the CSS file. Take a look at the image below for reference: ht ...

Encountering Error 500 with Jquery Min.Map File

ERROR: GET request to http://domain.com/assets/js/jquery-1.10.2.min.map returned a 500 Internal Server Error Can anyone help me figure out what's causing this error? I checked the log files in /var/log/error but couldn't find any information. T ...