gpt4 book ai didi

javascript - Web Audio API 循环与 SVG 动画同步

转载 作者:行者123 更新时间:2023-12-02 21:56:51 24 4
gpt4 key购买 nike

我有一个简单的 4 秒音频剪辑,每秒点击一次。我有一个带有 4 个圆圈的 SVG 图像。我希望能够无限循环音频,并使圆圈每秒显示/隐藏与音频同步。所以...

0 seconds, show just the red circle
1 second, show just the green circle
2 seconds, show just the yellow circle
3 seconds, show just the blue circle (audio loops to the beggining, time is reset to 0)
0 seconds, show just the red circle
etc...

一切正常,除了我不知道如何捕获循环的时间。 (请参阅下面的 JavaScript,其中显示“某些事件监听器()”)。有什么想法吗?

<button id='go'>Go</button>      
<button id='stop'>Stop</button>
<br/><br/>
<svg width='500' height='100'>
<rect width="250" height="100" style="fill:Tan;stroke-width:3;stroke:rgb(0,0,0)" />
<g id='circle1'><circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" /></g>
<g id='circle2'><circle cx="100" cy="50" r="40" stroke="black" stroke-width="3" fill="green" /></g>
<g id='circle3'><circle cx="150" cy="50" r="40" stroke="black" stroke-width="3" fill="yellow" /></g>
<g id='circle4'><circle cx="200" cy="50" r="40" stroke="black" stroke-width="3" fill="blue" /></g>
</svg>
var actx = new (AudioContext || webkitAudioContext)(),
src = "https://smantei.s3-us-west-2.amazonaws.com/Click.wav",
audioData, srcNode;

fetch(src, {mode: "cors"}).then(function(resp) {return resp.arrayBuffer()}).then(decode);

function decode(buffer) {
actx.decodeAudioData(buffer, playLoop);
}

function playLoop(abuffer) {
if (!audioData) audioData = abuffer;
srcNode = actx.createBufferSource();
srcNode.buffer = abuffer;
srcNode.connect(actx.destination);
srcNode.loop = true;
srcNode.start();
}

document.querySelector("#go").onclick = function() {
playLoop(audioData);
};

document.querySelector("#stop").onclick = function() {
srcNode.stop();
};

/*
some event listener() {
if (time >= 0 && time < 1.0) {
document.querySelector("#circle1").style.display = 'block';
document.querySelector("#circle2").style.display = 'none';
document.querySelector("#circle3").style.display = 'none';
document.querySelector("#circle4").style.display = 'none';
}
if (time >= 1.0 && time < 2.0) {
document.querySelector("#circle1").style.display = 'none';
document.querySelector("#circle2").style.display = 'block';
document.querySelector("#circle3").style.display = 'none';
document.querySelector("#circle4").style.display = 'none';
}
if (time >= 2.0 && time < 3.0) {
document.querySelector("#circle1").style.display = 'none';
document.querySelector("#circle2").style.display = 'none';
document.querySelector("#circle3").style.display = 'block';
document.querySelector("#circle4").style.display = 'none';
}
if (time >= 3.0 && time < 4.0) {
document.querySelector("#circle1").style.display = 'none';
document.querySelector("#circle2").style.display = 'none';
document.querySelector("#circle3").style.display = 'none';
document.querySelector("#circle4").style.display = 'block';
}
}
*/

最佳答案

由于您正在循环播放音频剪辑,因此没有可用的事件。但是,如果您使用 4 个单独的 1 秒剪辑,则可以安排每个剪辑每秒开始一次。然后,您将从每个剪辑中获得一个可用于驱动 SVG 动画的 onending 事件。

但是,这意味着您必须每 4 秒不断安排新剪辑来进行自己的音频循环。确保在当前回合结束之前安排下一轮,并且不要使用已结束的事件来安排下一个剪辑。随着时间的推移,这会慢慢发生变化,但也许这对您的应用程序来说是可以接受的。

关于它如何工作的非常粗略的草图。完全未经测试,但我希望它给出了基本的想法:

// Clip is the 4 sec audio clip.
// context is the audioContext
clip = new Array(4);
// Create 4 clips using the same buffer
for (let k = 0; k < clip.length; ++k) {
clip[k] = new AudioBufferSourceNode(context, {buffer: clip};
clip[0].connect(context.destiantion);
}

let now = context.currentTime;
// Play out each 1 sec part of the clip consecutively, playing out
// the whole buffer 1 sec at a time.
clip[0].start(now, 0, 1);
clip[1].start(now + 1, 1, 1);
clip[2].start(now + 2, 2, 1);
clip[3].start(now + 3, 3, 1);

clip[0].onended = () => {
// SVG when first clip ends
};
clip[1].onended = () => {
// SVG when second clip ends
};
clip[2].onended = () => {
// SVG when third clip ends
};
clip[3].onended = () => {
// SVG when fourth clip ends
};

这是基本结构。您需要将其修改为循环。所以也许当第三个剪辑结束时,再次创建新的剪辑[0]到剪辑[2],使用新的开始时间,当第四个剪辑结束时,创建一个新的剪辑[3]。还要确保为每个新添加持续事件剪辑。

还有其他方法,但这相对简单使动画始终与音频保持同步(有一些滞后由于事件处理)。

关于javascript - Web Audio API 循环与 SVG 动画同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59981455/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com