【问题标题】:How to decrease anime time when it is out of screen如何减少动画离开屏幕时的时间
【发布时间】:2021-12-21 03:17:46
【问题描述】:

我有一个动画,当黑色容器变成红色时,它的持续时间会减少,但这会产生故障。有什么方法可以消除其中的故障吗?

我试图延迟更改,直到红色完成路径,但仍然面临故障。

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

我计算了红色与左侧的剩余距离,并获得了完成该距离的持续时间并将其添加到延迟中。但它仍然显示故障。

sn-p下面会发生什么

  • 黑盒子是由space(跳跃)、<(向左移动)、>(向右移动)控制的英雄。
  • 红色是恶棍(恶魔),它有动画从右侧移动到左侧,动画有一定的持续时间。
  • 每当英雄通过红色时,红色会变得更快(通过尝试减少动画持续时间),但是这种红色会出现故障并且从任何地方开始(而不是从下一个应该在的位置)。
  • 我想提高红色的速度,但遇到了故障,因此试图延迟动画持续时间的变化,直到红色穿过屏幕,但这似乎不起作用

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>

提前感谢您的帮助

【问题讨论】:

    标签: javascript html css animation


    【解决方案1】:

    一种方法是使用Animation.playbackRate,但它仍处于试验阶段。

    let VillRate = 1
    ...
    
    // inside the collision check
    
    if (VillRate < 20) {
      ourVillanFig.getAnimations()[0].playbackRate += 0.2
      VillRate += 0.5
    }
    

    在下面的sn-p中,每次碰到黑色时,红色的速度都会增加,直到某个点。您可以根据需要调整该行为。

    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>

    【讨论】:

      【解决方案2】:

      我试过了:

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

      它工作正常,但是当时间减少到4s 之后,红色不是从末尾开始,而是从中间开始。几乎从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>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-12
        • 1970-01-01
        • 1970-01-01
        • 2023-04-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多