Particles.js canvas 位于其他 Bootstrap 轮播幻灯片位置时不起作用

Particles.js canvas does not work when positioned in other Bootstrap carousel slide position

我正在制作一个带有 Bootstrap 轮播的网站,其中应该包含一些动画 canvas。 我想在第二张幻灯片上使用 Particles.js 动画,但它不起作用。 它只适用于第一张幻灯片,我不明白为什么。

有人可以帮助我吗?

代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <title>Bootstrap Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
  <style>
    #myCarousel {
      height: 500px
    }
    .carousel-inner > .item > img,
    .carousel-inner > .item > a > img {
      width: 70%;
      margin: auto;
    }
    canvas {
      position: relative;
      /*pointer-events:none;*/
      top: 0;
      left: 0
    }
    /* Particles Canvas*/
    #particles-js{
      height: 500px;
      width: 100%;
      background-color: #D0EDF5;
      background-image: url('');
      background-size: cover;
      background-position: 50% 50%;
      background-repeat: no-repeat;
    }
  </style>
</head>

<body>
  <div class="container">
    <br>
    <div id="myCarousel" class="carousel slide" data-ride="carousel">
      <!-- Indicators -->
      <ol class="carousel-indicators">
        <li data-target="#myCarousel" data-slide-to="0" class="active"></li>
        <li data-target="#myCarousel" data-slide-to="1"></li>
        <li data-target="#myCarousel" data-slide-to="2"></li>
      </ol>
      <!-- Wrapper for slides -->
      <div class="carousel-inner" role="listbox">
        <div class="item active">
          <h1>First Slide</h1>
        </div>
        <div class="item">
          <div id="particles-js"></div>
        </div>
        <div class="item">
          <h1>Third Slide</h1>
        </div>
      </div>
      <!-- Left and right controls -->
      <a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
        <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
        <span class="sr-only">Previous</span>
      </a>
      <a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
        <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
        <span class="sr-only">Next</span>
      </a>
    </div>
  </div>
  <script type="text/javascript" src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script>
  <script type="text/javascript">
    particlesJS('particles-js',

      {
        "particles": {
          "number": {
            "value": 60,
            "density": {
              "enable": true,
              "value_area": 800
            }
          },
          "color": {
            "value": "#0A8B80"
          },
          "shape": {
            "type": "circle",
            "stroke": {
              "width": 0,
              "color": "#000000"
            },
            "polygon": {
              "nb_sides": 5
            },
            "image": {
              "src": "img/github.svg",
              "width": 100,
              "height": 50
            }
          },
          "opacity": {
            "value": 0.5,
            "random": false,
            "anim": {
              "enable": false,
              "speed": 1,
              "opacity_min": 0.1,
              "sync": false
            }
          },
          "size": {
            "value": 20,
            "random": true,
            "anim": {
              "enable": false,
              "speed": 40,
              "size_min": 0.1,
              "sync": false
            }
          },
          "line_linked": {
            "enable": true,
            "distance": 150,
            "color": "#65BBC4",
            "opacity": 0.4,
            "width": 2
          },
          "move": {
            "enable": true,
            "speed": 6,
            "direction": "none",
            "random": false,
            "straight": false,
            "out_mode": "out",
            "attract": {
              "enable": false,
              "rotateX": 600,
              "rotateY": 1200
            }
          }
        },
        "interactivity": {
          "detect_on": "canvas",
          "events": {
            "onhover": {
              "enable": true,
              "mode": "repulse"
            },
            "onclick": {
              "enable": true,
              "mode": "push"
            },
            "resize": true
          },
          "modes": {
            "grab": {
              "distance": 400,
              "line_linked": {
                "opacity": 1
              }
            },
            "bubble": {
              "distance": 400,
              "size": 80,
              "duration": 2,
              "opacity": 8,
              "speed": 3
            },
            "repulse": {
              "distance": 200
            },
            "push": {
              "particles_nb": 4
            },
            "remove": {
              "particles_nb": 2
            }
          }
        },
        "retina_detect": true,
        "config_demo": {
          "hide_card": false,
          "background_color": "#D0EDF5",
          "background_image": "",
          "background_position": "50% 50%",
          "background_repeat": "no-repeat",
          "background_size": "cover"
        }
      }
    );
  </script>
</body>

</html>

此外,我注意到动画在打开浏览器的开发人员控制台时启动,如下例所示:

Before

After

因为 particles.js 初始化时,它读取 offsetHeightoffsetWidth 属性[1],其中这些描述了可见区域的大小[2]。这可能是 particles.js 的错误,但您可以捕获 Bootstrap 轮播的幻灯片事件,然后初始化 particles.js。


补充说明:

在幻灯片事件后初始化 particles.js 确保当它发生时,目标元素已经可见,以便 particles.js 可以获得有效的指标。

另一种解决方案是在每次滑动事件后触发调整大小事件。将重新计算宽度和高度 [3]。这也是为什么本题作者打开开发者控制台就可以启动动画的原因。

参考: