简体   繁体   English

单击播放/暂停按钮时,如何让我的 canvas animation 播放/停止?

[英]How do I get my canvas animation to play/stop when the play/pause button is clicked?

How do I get my canvas animation of the rain to start when the play button is clicked and vice versa (stop the rain when the pause button is clicked)?单击播放按钮时如何让我的 canvas animation 开始下雨,反之亦然(单击暂停按钮时停止下雨)?

I really would appreciate a helping hand.我真的很感激能伸出援助之手。

So far I have the rain animation to play as soon as the window is loaded and the audio in the background is the only thing that plays when interacting with the play button.到目前为止,只要 window 被加载,我就有雨 animation 播放,并且背景中的音频是与播放按钮交互时唯一播放的东西。

I'm not sure how to go about getting the rain animation to start so that the audio also plays in sync with the rain and vice versa.我不知道如何 go 开始下雨 animation 以便音频也与雨同步播放,反之亦然。

 // Get the canvas and context and store in variables var canvas = document.getElementById("canvas"); var context = canvas.getContext("2d"); // Set canvas dimensions to window height and width canvas.width = window.innerHeight; canvas.height = window.innerHeight; // Generate the raindrops and apply attributes var rainNum = 200; // max raindrops var rainDrops = []; let isClicked = true; // Loop through the empty raindrops and apply attributes for (var i = 0; i < rainNum; i++) { rainDrops.push({ x: Math.random() * canvas.width, y: Math.random() * canvas.height, }) } // Draw raindrops onto canvas function draw() { context.clearRect(0, 0, canvas.width, canvas.height); context.lineWidth = 0.1; context.strokeStyle = "white"; context.beginPath(); for (var i = 0; i < rainNum; i++) { var r = rainDrops[i]; context.moveTo(rx, r.y); context.lineTo(rx, r.y + 30); rainDrops[i].y += 13; context.stroke(); } if (isClicked == true) { moveRain(); } else { return false } window.requestAnimationFrame(draw); } window.requestAnimationFrame(draw); // Animate the raindrops function moveRain() { for (var i = 0; i < rainNum; i++) { // Store current raindrops var r = rainDrops[i]; // If the rain reaches the bottom, send a new one to the top if (ry > canvas.height) { rainDrops[i] = { x: Math.random() * canvas.width, y: 0 }; } } } // Create a reference to the audio var audioOne = document.querySelector("#audio-1"); function playAudio() { if (isClicked == true) { isClicked = false audioOne.pause(); btn.className = "play"; } else if (isClicked == false) { isClicked = true audioOne.play(); btn.className = "pause"; draw() } }
 html { height: 100%; width: 100%; } body { height: 100vh; width: 100vw; margin: 0; padding: 0; overflow: hidden; } canvas { height: 100%; width: 100%; background-color: transparent; position: absolute; z-index: 10; } #sky-top { height: 100%; width: 100%; position: absolute; z-index: 1; animation: lightning 20s ease-in-out infinite; } @keyframes lightning { /****** This will create a lightning effect every 20 seconds ******/ 0% { background-color: rgb(46, 46, 46); } 6.25% { background-color: rgb(46, 46, 46); } 8% { background-color: rgb(255, 255, 255); } 9% { background-color: rgb(46, 46, 46); } 11% { background-color: rgb(255, 255, 255); } 30% { background-color: rgb(46, 46, 46); } 100% { background-color: rgb(46, 46, 46); } } #sky-bottom { height: 100%; width: 100%; position: absolute; z-index: 2; background: linear-gradient(rgba(255, 255, 255, 0), rgb(45, 45, 45)); }.center-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; text-align: center; z-index: 20; background-color: transparent; }.button-center { position: absolute; top: 40%; -webkit-transform: translateY(-50%); -moz-transform: translateY(-50%); -ms-transform: translateY(-50%); -o-transform: translateY(-50%); transform: translateY(-50%); -webkit-transform: translateX(-50%); -moz-transform: translateX(-50%); -ms-transform: translateX(-50%); -o-transform: translateX(-50%); transform: translateX(-50%); }.center-container:after, .button-center { display: inline-block; vertical-align: middle; } #btn { height: 130px; width: 130px; border: none; background-size: 100% 100%; outline: none; }.play { background: url('../image/play-button.png'); border-radius: 50%; cursor: pointer; -webkit-filter: drop-shadow(2px 2px 2px #666666); filter: drop-shadow(2px 2px 2px #666666); }.pause { background: url('../image/pause-button.png'); border-radius: 50%; cursor: pointer; -webkit-filter: drop-shadow(2px 2px 2px #666666); filter: drop-shadow(2px 2px 2px #666666); }
 <,DOCTYPE html> <html lang="en"> <head> <title>Rain</title> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width. initial-scale=1.0"> <meta name="description" content="Relax your mind with some rain and thunder."> <link href="css/styles.css" type="text/css" rel="stylesheet"> </head> <body> <div id="sky-top"></div> <div id="sky-bottom"></div> <canvas id="canvas"></canvas> <div class="center-container"> <div class="button-center"> <button id="btn" class="play" class="pause" onclick="playAudio()"></button> </div> <audio src="audio/rain-and-thunder.mp3" id="audio-1" loop="loop" type="audio/mp3"></audio> </div> <script src="js/script.js"></script> </body> </html>

First off, the audio file won't work for me here locally (I downloaded my own mp3 - I am working on getting it to work now), so I focused on playing/pausing the canvas animation and ignored the sound functionality.首先,音频文件在本地对我不起作用(我下载了自己的 mp3 - 我正在努力让它工作),所以我专注于播放/暂停 canvas animation 并忽略了声音功能。 Let's start with the HTML:让我们从 HTML 开始:

<html>
<head>
    <link rel = "stylesheet"
   type = "text/css"
   href = "index.css" />
</head>
<body>
              <canvas id="canvas"></canvas>

        <div class="center-container">
            
            <div class="button-center">
                <button id="btn" class="play" class="pause" onclick="playAudio()"></button>
            </div>

            <audio loop="loop" id="audio-1" width="100%" height="auto">
              <source src="audio/rain-and-thunder.mp3" type="audio/mpeg">
              </audio>
        
        </div>
</body>
<script src='index.js'></script>
</html>

You'll see I did a few things to display the canvas properly.你会看到我做了一些事情来正确显示canvas For whatever reason, I couldn't see your button and the canvas was showing up blank.无论出于何种原因,我看不到您的按钮,并且 canvas 显示为空白。 I decided to inline CSS the width and height , as well as put the script within the body .我决定inline CSSwidthheight ,并将脚本放在body中。

Also, since we are ignoring the sound functionality, I renamed the function to startStopRain() to make more sense in your JS file.此外,由于我们忽略了声音功能,我将 function 重命名为startStopRain()以便在您的 JS 文件中更有意义。 Let's talk about that next:让我们接下来谈谈:

// Get the canvas and context and store in variables
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var audioOne = document.getElementById("audio-1");

// Set canvas dimensions to window height and width 
canvas.width = window.innerHeight;
canvas.height = window.innerHeight;

// Generate the raindrops and apply attributes 
var rainNum = 200; // max raindrops 
var rainDrops = [];

let isClicked = false

// Loop through the empty raindrops and apply attributes
for(var i = 0; i < rainNum; i ++)
{
    rainDrops.push({
        x: Math.random() * canvas.width,
        y: Math.random() * canvas.height,
    })
}

// Draw raindrops onto canvas 
function draw()
{   
    context.clearRect(0, 0, canvas.width, canvas.height);

    context.lineWidth = 0.1;
    context.strokeStyle = "red";
    context.beginPath(); 

    for(var i = 0; i < rainNum; i ++)
    {
        var r = rainDrops[i];
        context.moveTo(r.x, r.y);
        context.lineTo(r.x, r.y + 30);
        rainDrops[i].y += 13;
        context.stroke();
    }
    if (isClicked == true) {
        moveRain();
    } else{
        return false
    }

    document.getElementById("canvas").onclick = moveRain();

    window.requestAnimationFrame(draw);
}


window.requestAnimationFrame(draw);

// Animate the raindrops
function moveRain(){
    for(var i = 0; i < rainNum; i++)
        {
        // Store current raindrops
        var r = rainDrops[i];

        // If the rain reaches the bottom, send a new one to the top
        if(r.y > canvas.height) {
            rainDrops[i] = {x: Math.random() * canvas.width, y: 0};
        }
    }
}

// Create a reference to the audio


// need to figure out why the audio wont play - this is new to me :D
function playAudio(){
    audioOne.play();
    if (isClicked == true){
        isClicked = false
        audioOne.pause();
    } else if (isClicked == false){
        isClicked = true
        audioOne.play();
        draw()
    }
}

Your original intent was to use two class names on the btn so you could distinguish between play/pause.您最初的意图是在btn上使用两个 class 名称,以便您可以区分播放/暂停。 While there are use cases for using multiple class names, I don't personally believe this is one of them.虽然有使用多个 class 名称的用例,但我个人不认为这是其中之一。 Instead, I used a global isClicked variable in the script so I could control the flow of the functions.相反,我在脚本中使用了一个全局isClicked变量,这样我就可以控制函数的流程。

Follow the isClicked variable from top to bottom to better understand how I used it to call/stop functions.从上到下跟踪isClicked变量,以更好地了解我如何使用它来调用/停止函数。 Minus initializing the variable at the top, you'll notice it shows up in only two functions: draw() and startStopRain() .减去在顶部初始化变量,您会注意到它仅显示在两个函数中: draw()startStopRain()

EDIT: The flow control for the sound should be no different.编辑:声音的流量控制应该没有什么不同。 You can use the same isClicked boolean value to determine when the sound should be played or not.您可以使用相同的isClicked boolean值来确定何时播放声音。 If you want, I can update it to reflect that but truthfully, that would be good practice for you.如果你愿意,我可以更新它以反映这一点,但说实话,这对你来说是个好习惯。 Also, I changed the id of the button to audio-1 since the original code was selecting the element via that specific id此外,我将按钮的id更改为audio-1 ,因为原始代码是通过该特定id选择元素

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM