如何用 CSS/Javascript 中的圣诞歌曲暂停闪烁的圣诞灯?

问题描述 投票:0回答:2

我正在制作一个 CSS 动画,其中圣诞树上的灯光随着圣诞歌曲的节奏闪烁,当我按下树下方的按钮暂停歌曲时,灯光也会暂停闪烁。当我再次按下按钮播放歌曲时,灯将继续闪烁。

这就是我到目前为止所拥有的。我已经设法让灯闪烁,但是当我尝试添加音频时它没有运行。

let play = false;

const lights = document.querySelectorAll('.light');
const christmasSong = document.getElementById('christmasSong');
const audioContext = new(window.AudioContext || window.webkitAudioContext)();

const gainNode = audioContext.createGain();
const audioSource = audioContext.createMediaElementSource(christmasSong);
audioSource.connect(gainNode);
gainNode.connect(audioContext.destination);

function pauseButton() {
  if (play === false) {
    lights.forEach(light => {
      light.style.animationPlayState = "running";
    });
    christmasSong.play();
    gainNode.gain.setValueAtTime(1, audioContext.currentTime);
    play = true;
  } else {
    lights.forEach(light => {
      light.style.animationPlayState = "paused";
    });
    christmasSong.pause();
    gainNode.gain.setValueAtTime(0, audioContext.currentTime);
    play = false;
  }
}
.christmas-tree {
  top: 10%;
}

.play-pause {
  /* top: 50%; */
  padding-top: 30px;
  left: 23%;
  position: relative;
}

button {
  display: inline-block;
  padding: 10px 20px;
  font-size: 16px;
  text-align: center;
  text-decoration: none;
  background-color: #FF0000;
  color: #FFFFFF;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}

button:hover {
  background-color: #ffffff;
  color: #d21d1d;
}

.tree-top {
  top: 2%;
  left: 14%;
  position: relative;
  width: 0;
  height: 0;
  border-left: 100px solid transparent;
  border-right: 100px solid transparent;
  border-bottom: 160px solid green;
  /* animation: move 2s infinite; */
}

.tree-middle {
  margin-top: -15%;
  margin-left: 10%;
  position: relative;
  width: 15px;
  height: 10px;
  border-left: 100px solid transparent;
  border-right: 100px solid transparent;
  border-bottom: 160px solid green;
  /* animation: move 2s infinite; */
}

.tree-bottom {
  margin-top: -20%;
  margin-left: 7%;
  position: relative;
  width: 25px;
  height: 25px;
  border-left: 100px solid transparent;
  border-right: 100px solid transparent;
  border-bottom: 160px solid green;
  /* animation: move 2s infinite; */
}

.lights-top {
  position: absolute;
  bottom: -100px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 10px;
}

.lights-middle {
  position: absolute;
  bottom: -115px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 20px;
}

.lights-bottom {
  position: absolute;
  bottom: -120px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 25px;
}


/* BLINKING LIGHTS */

.light {
  width: 20px;
  height: 25px;
  border-radius: 50%;
  animation: blink 1s infinite alternate;
  animation-play-state: paused;
}

.light-red {
  background-color: #f00;
  animation-duration: 0.6s;
}

.light-yellow {
  background-color: rgb(246, 255, 0);
  animation-duration: 0.45s;
}

.light-blue {
  background-color: rgb(0, 85, 255);
  animation-duration: 0.5s;
}

.light-green {
  background-color: rgb(17, 255, 0);
  animation-duration: 0.7s;
}

@keyframes blink {
  0% {
    opacity: 1;
  }
  100% {
    opacity: 0.3;
  }
}
<div class="christmas-tree">
  <div class="tree-top">
    <div class="lights-top">
      <div class="light light-red"></div>
      <div class="light light-yellow"></div>
      <div class="light light-blue"></div>
      <div class="light light-green"></div>
    </div>
  </div>
  <div class="tree-middle">
    <div class="lights-middle">
      <div class="light light-blue"></div>
      <div class="light light-red"></div>
      <div class="light light-green"></div>
      <div class="light light-yellow"></div>
    </div>
  </div>
  <div class="tree-bottom">
    <div class="lights-bottom">
      <div class="light light-green"></div>
      <div class="light light-yellow"></div>
      <div class="light light-red"></div>
      <div class="light light-blue"></div>
    </div>
  </div>
  <div class="play-pause">
    <button onclick="pauseButton()">Pause / Resume</button>
  </div>
</div>
<audio id="christmasSong" controls>
  <source src="I Saw Mommy Kissing Santa Claus Jackson 5-GPNu0H6jNJc-192k-1702586134.mp3" type="audio/mpeg">
  Your browser does not support the audio element.
</audio>

javascript html css html5-audio web-audio-api
2个回答
0
投票

问题是,当执行 javascript 代码来查询歌曲时,它尚未加载。

你可以通过多种方式解决这个问题,第二种方法可以让你有更好的代码组织,但也需要更多的 js 理解。

  1. 在pauseButton函数中查询
function pauseButton() {
  
const lights = document.querySelectorAll(".light");
const christmasSong = document.getElementById('christmasSong');
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
const gainNode = audioContext.createGain();
const audioSource = audioContext.createMediaElementSource(christmasSong);
audioSource.connect(gainNode);
gainNode.connect(audioContext.destination);

  if (play === false) {
    lights.forEach((light) => {
    ...

不要忘记创建 if 语句,以便仅在您第一次单击该按钮时才初始化 audioContext

  1. 你可以使用 window.addEventListener 检查 dom 内容是否已加载,如下所示:
let play = false;
let christmasSong = null;
let audioContext = null;
let gainNode = null;
let lights = null;

window.addEventListener('DOMContentLoaded', () => {
  lights = document.querySelectorAll(".light");
  christmasSong = document.getElementById('christmasSong');
  audioContext = new (window.AudioContext || window.webkitAudioContext)();
  gainNode = audioContext.createGain();
  const audioSource = audioContext.createMediaElementSource(christmasSong);
  audioSource.connect(gainNode);
  gainNode.connect(audioContext.destination);
 

});

function pauseButton() {
 
  audioContext.resume();

不要忘记恢复audioContext,因为chrome将不允许它启动,除非你可以检查


0
投票

您可以通过删除audioContext和相关部分来修复动画音频:

// REMOVE
const audioContext = new(window.AudioContext || window.webkitAudioContext)();
const gainNode = audioContext.createGain();
const audioSource = audioContext.createMediaElementSource(christmasSong);
audioSource.connect(gainNode);
gainNode.connect(audioContext.destination);

查看代码片段中的更改并运行以播放带有音频的动画。

代码片段:

const lights = document.querySelectorAll('.light');
const christmasSong = document.getElementById('christmasSong');

// Optional Change:
// use ChristmasSong.paused rather than variable paused 

function pauseButton() {

  if (christmasSong.paused === true) {
    lights.forEach(light => {
      light.style.animationPlayState = "running";
    });
    christmasSong.play();
  } else {
    lights.forEach(light => {
      light.style.animationPlayState = "paused";
    });
    christmasSong.pause();
  }
}
.christmas-tree {
  top: 10%;
}

.play-pause {
  /* top: 50%; */
  padding-top: 30px;
  left: 23%;
  position: relative;
}

button {
  display: inline-block;
  padding: 10px 20px;
  font-size: 16px;
  text-align: center;
  text-decoration: none;
  background-color: #FF0000;
  color: #FFFFFF;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}

button:hover {
  background-color: #ffffff;
  color: #d21d1d;
}

.tree-top {
  top: 2%;
  left: 14%;
  position: relative;
  width: 0;
  height: 0;
  border-left: 100px solid transparent;
  border-right: 100px solid transparent;
  border-bottom: 160px solid green;
  /* animation: move 2s infinite; */
}

.tree-middle {
  margin-top: -15%;
  margin-left: 10%;
  position: relative;
  width: 15px;
  height: 10px;
  border-left: 100px solid transparent;
  border-right: 100px solid transparent;
  border-bottom: 160px solid green;
  /* animation: move 2s infinite; */
}

.tree-bottom {
  margin-top: -20%;
  margin-left: 7%;
  position: relative;
  width: 25px;
  height: 25px;
  border-left: 100px solid transparent;
  border-right: 100px solid transparent;
  border-bottom: 160px solid green;
  /* animation: move 2s infinite; */
}

.lights-top {
  position: absolute;
  bottom: -100px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 10px;
}

.lights-middle {
  position: absolute;
  bottom: -115px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 20px;
}

.lights-bottom {
  position: absolute;
  bottom: -120px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: 25px;
}


/* BLINKING LIGHTS */

.light {
  width: 20px;
  height: 25px;
  border-radius: 50%;
  animation: blink 1s infinite alternate;
  animation-play-state: paused;
}

.light-red {
  background-color: #f00;
  animation-duration: 0.6s;
}

.light-yellow {
  background-color: rgb(246, 255, 0);
  animation-duration: 0.45s;
}

.light-blue {
  background-color: rgb(0, 85, 255);
  animation-duration: 0.5s;
}

.light-green {
  background-color: rgb(17, 255, 0);
  animation-duration: 0.7s;
}

@keyframes blink {
  0% {
    opacity: 1;
  }
  100% {
    opacity: 0.3;
  }
}
<div class="christmas-tree">
  <div class="tree-top">
    <div class="lights-top">
      <div class="light light-red"></div>
      <div class="light light-yellow"></div>
      <div class="light light-blue"></div>
      <div class="light light-green"></div>
    </div>
  </div>
  <div class="tree-middle">
    <div class="lights-middle">
      <div class="light light-blue"></div>
      <div class="light light-red"></div>
      <div class="light light-green"></div>
      <div class="light light-yellow"></div>
    </div>
  </div>
  <div class="tree-bottom">
    <div class="lights-bottom">
      <div class="light light-green"></div>
      <div class="light light-yellow"></div>
      <div class="light light-red"></div>
      <div class="light light-blue"></div>
    </div>
  </div>
  <div class="play-pause">
    <button onclick="pauseButton()">Pause / Resume</button>
  </div>
</div>

<audio id="christmasSong" controls>
  <source src="https://jesusful.com/wp-content/uploads/music/2022/12/Jackson_5_-_I_Saw_Mommy_Kissing_Santa_Claus_(Jesusful.com).mp3" type="audio/mpeg">
  Your browser does not support the audio element.
</audio>

© www.soinside.com 2019 - 2024. All rights reserved.