我正在制作一个 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 代码来查询歌曲时,它尚未加载。
你可以通过多种方式解决这个问题,第二种方法可以让你有更好的代码组织,但也需要更多的 js 理解。
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
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将不允许它启动,除非你可以检查
您可以通过删除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>