首页 > 解决方案 > 如何通过单击导航按钮开始/结束smoke.js 动画?

问题描述

好的,所以我有一个nav使用轮播幻灯片导航到某个幻灯片的列表,smoke.js 在访问该站点时加载并自动启动,这是我想要的,但是当他们单击nav“主页”以外的任何按钮时"按钮,我需要它来结束烟雾动画,如果他们点击主页按钮回到主页幻灯片,我需要它来重新启动烟雾机。我怎样才能做到这一点?

Smoke.js 的 codepen 在这里codepen

var smokemachine = function(context, color) {
  color = color || [24, 46.8, 48.2]
  var polyfillAnimFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
    window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
  var lastframe;
  var currentparticles = []
  var pendingparticles = []

  var buffer = document.createElement('canvas'),
    bctx = buffer.getContext('2d')

  buffer.width = 20
  buffer.height = 20

  var opacities = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 5, 7, 4, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 17, 27, 41, 52, 56, 34, 23, 15, 11, 4, 9, 5, 1, 0, 0, 0, 0, 0, 0, 1, 45, 63, 57, 45, 78, 66, 52, 41, 34, 37, 23, 20, 0, 1, 0, 0, 0, 0, 1, 43, 62, 66, 64, 67, 115, 112, 114, 56, 58, 47, 33, 18, 12, 10, 0, 0, 0, 0, 39, 50, 63, 76, 87, 107, 105, 112, 128, 104, 69, 64, 29, 18, 21, 15, 0, 0, 0, 7, 42, 52, 85, 91, 103, 126, 153, 128, 124, 82, 57, 52, 52, 24, 1, 0, 0, 0, 2, 17, 41, 67, 84, 100, 122, 136, 159, 127, 78, 69, 60, 50, 47, 25, 7, 1, 0, 0, 0, 34, 33, 66, 82, 113, 138, 149, 168, 175, 82, 142, 133, 70, 62, 41, 25, 6, 0, 0, 0, 18, 39, 55, 113, 111, 137, 141, 139, 141, 128, 102, 130, 90, 96, 65, 37, 0, 0, 0, 2, 15, 27, 71, 104, 129, 129, 158, 140, 154, 146, 150, 131, 92, 100, 67, 26, 3, 0, 0, 0, 0, 46, 73, 104, 124, 145, 135, 122, 107, 120, 122, 101, 98, 96, 35, 38, 7, 2, 0, 0, 0, 50, 58, 91, 124, 127, 139, 118, 121, 177, 156, 88, 90, 88, 28, 43, 3, 0, 0, 0, 0, 30, 62, 68, 91, 83, 117, 89, 139, 139, 99, 105, 77, 32, 1, 1, 0, 0, 0, 0, 0, 16, 21, 8, 45, 101, 125, 118, 87, 110, 86, 64, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 28, 79, 79, 117, 122, 88, 84, 54, 46, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 55, 61, 68, 71, 30, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 23, 25, 20, 12, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 12, 9, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0]

  var data = bctx.createImageData(20, 20)
  var d = data.data

  for (var i = 0; i < d.length; i += 4) {
    d[i] = color[0]
    d[i + 1] = color[1]
    d[i + 2] = color[2]
    d[i + 3] = opacities[i / 4]
  }

  bctx.putImageData(data, 0, 0)

  var imagewidth = 20 * 5
  var imageheight = 20 * 5

  function particle(x, y, l) {
    this.x = x
    this.y = y
    this.age = 0
    this.vx = (Math.random() * 8 - 4) / 100
    this.startvy = -(Math.random() * 30 + 10) / 100
    this.vy = this.startvy
    this.scale = Math.random() * .5
    this.lifetime = Math.random() * l + l / 2
    this.finalscale = 5 + this.scale + Math.random()

    this.update = function(deltatime) {
      this.x += this.vx * deltatime
      this.y += this.vy * deltatime
      var frac = Math.pow((this.age) / this.lifetime, .5)
      this.vy = (1 - frac) * this.startvy
      this.age += deltatime
      this.scale = frac * this.finalscale
    }

    this.draw = function() {
      context.globalAlpha = (1 - Math.abs(1 - 2 * (this.age) / this.lifetime)) / 8
      var off = this.scale * imagewidth / 2
      var xmin = this.x - off
      var xmax = xmin + this.scale * imageheight
      var ymin = this.y - off
      var ymax = ymin + this.scale * imageheight
      context.drawImage(buffer, xmin, ymin, xmax - xmin, ymax - ymin)
    }
  }


  function addparticles(x, y, n, lifetime) {
    lifetime = lifetime || 4000
    n = n || 10
    if (n < 1) return Math.random() <= n && pendingparticles.push(new particle(x, y, lifetime));
    for (var i = 0; i < n; i++) {
      pendingparticles.push(new particle(x, y, lifetime))
    };
  }

  function updateanddrawparticles(deltatime) {
    context.clearRect(0, 0, canvas.width, canvas.height);
    deltatime = deltatime || 16
    var newparticles = []
    currentparticles = currentparticles.concat(pendingparticles)
    pendingparticles = []

    currentparticles.forEach(function(p) {
      p.update(deltatime)
      if (p.age < p.lifetime) {
        p.draw()
        newparticles.push(p)
      }
    })
    currentparticles = newparticles
  }

  function frame(time) {
    if (running) {
      var deltat = time - lastframe
      lastframe = time;

      updateanddrawparticles(deltat)

      polyfillAnimFrame(frame)
    }
  }

  var running = false

  function start() {
    running = true
    polyfillAnimFrame(function(time) {
      lastframe = time
      polyfillAnimFrame(frame)
    })
  }

  function stop() {
    running = false
  }

  return {
    start: start,
    stop: stop,
    step: updateanddrawparticles,
    addsmoke: addparticles
  }

}



var canvas = document.getElementById('canvas')
var ctx = canvas.getContext('2d')
canvas.width = innerWidth
canvas.height = innerHeight

var party = smokemachine(ctx, [54, 16.8, 18.2])
party.start() // start animating

onmousemove = function(e) {
  var x = e.clientX
  var y = e.clientY
  var n = .5
  var t = Math.floor(Math.random() * 200) + 3800
  party.addsmoke(x, y, n, t)
}

setInterval(function() {
  party.addsmoke(innerWidth / 2, innerHeight, 1)
}, 100)
html,
body {
  position: absolute;
  margin: 0;
  width: 100%;
}

#hi {
  position: absolute;
  top: 40%;
  width: 100%;
  text-align: center;
}

#hi a {
  color: #fff;
  font-size: 80px;
  text-decoration: none;
  font-family: Lobster;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" />

<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
  <div class="container">
    <ul>
      <li>
        <a href="#" class="current">
          <span data-text="Home" data-target="#carouselExampleIndicators" data-slide-to="0">Home</span>
        </a>
      </li>
      <li>
        <a href="#">
          <span data-text="About" data-target="#carouselExampleIndicators" data- slide-to="1">About</span>
        </a>
      </li>
      <li>
        <a href="#">
          <span data-text="Chronic Menu" data-target="#carouselExampleIndicators" data-slide-to="2">Chronic Menu</span>
        </a>
      </li>
      <li>
        <a href="#">
          <span data-text="Strains" data-target="#carouselExampleIndicators" data- slide-to="3">Strains</span>
        </a>
      </li>
      <li>
        <a href="#">
          <span data-text="Gallery" data-target="#carouselExampleIndicators" data- slide-to="4">Gallery</span>
        </a>
      </li>
      <li>
        <a href="#">
          <span data-text="Reviews" data-target="#carouselExampleIndicators" data- slide-to="5">Reviews</span>
        </a>
      </li>
    </ul>
  </div>
</nav>

<canvas id="canvas" width="1777" height="898"></canvas>

标签: javascripthtmlcsssmokejs

解决方案


如果您查看GitHub 上的 Smoke.js 插件的文档,您会看到有两种方法:(start()启动烟雾)和stop()(停止烟雾)。因此,您要做的是party.stop()在单击导航并且它不是主页时调用,party.start() 如果它是主页选项。

像这样的东西(我的代码在顶部)​​:

注意:该.stop()方法将停止烟雾但它想删除现有的烟雾,它更像是一个暂停。目前尚不清楚您是否还想去除现有的烟雾,但如果您需要这样做,您可以按照此问题的说明来清洁canvas.

var navbaroptions = document.querySelectorAll("nav a");
for (var x = 0; x < navbaroptions.length; x++) {
  navbaroptions[x].addEventListener("click", function() {
    const canvas = document.querySelector("#canvas");
    if (this.id === "option-home") {
      party.start();
      canvas.removeAttribute("hidden");
    } else {
      party.stop();
      // hide the canvas
      canvas.setAttribute("hidden", true);
      const context = canvas.getContext('2d');
      context.clearRect(0, 0, canvas.width, canvas.height);
    }
  });
}

var smokemachine = function(context, color) {
  color = color || [24, 46.8, 48.2]
  var polyfillAnimFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
    window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
  var lastframe;
  var currentparticles = []
  var pendingparticles = []

  var buffer = document.createElement('canvas'),
    bctx = buffer.getContext('2d')

  buffer.width = 20
  buffer.height = 20

  var opacities = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 5, 7, 4, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 17, 27, 41, 52, 56, 34, 23, 15, 11, 4, 9, 5, 1, 0, 0, 0, 0, 0, 0, 1, 45, 63, 57, 45, 78, 66, 52, 41, 34, 37, 23, 20, 0, 1, 0, 0, 0, 0, 1, 43, 62, 66, 64, 67, 115, 112, 114, 56, 58, 47, 33, 18, 12, 10, 0, 0, 0, 0, 39, 50, 63, 76, 87, 107, 105, 112, 128, 104, 69, 64, 29, 18, 21, 15, 0, 0, 0, 7, 42, 52, 85, 91, 103, 126, 153, 128, 124, 82, 57, 52, 52, 24, 1, 0, 0, 0, 2, 17, 41, 67, 84, 100, 122, 136, 159, 127, 78, 69, 60, 50, 47, 25, 7, 1, 0, 0, 0, 34, 33, 66, 82, 113, 138, 149, 168, 175, 82, 142, 133, 70, 62, 41, 25, 6, 0, 0, 0, 18, 39, 55, 113, 111, 137, 141, 139, 141, 128, 102, 130, 90, 96, 65, 37, 0, 0, 0, 2, 15, 27, 71, 104, 129, 129, 158, 140, 154, 146, 150, 131, 92, 100, 67, 26, 3, 0, 0, 0, 0, 46, 73, 104, 124, 145, 135, 122, 107, 120, 122, 101, 98, 96, 35, 38, 7, 2, 0, 0, 0, 50, 58, 91, 124, 127, 139, 118, 121, 177, 156, 88, 90, 88, 28, 43, 3, 0, 0, 0, 0, 30, 62, 68, 91, 83, 117, 89, 139, 139, 99, 105, 77, 32, 1, 1, 0, 0, 0, 0, 0, 16, 21, 8, 45, 101, 125, 118, 87, 110, 86, 64, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 28, 79, 79, 117, 122, 88, 84, 54, 46, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 6, 55, 61, 68, 71, 30, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 23, 25, 20, 12, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 12, 9, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0]

  var data = bctx.createImageData(20, 20)
  var d = data.data

  for (var i = 0; i < d.length; i += 4) {
    d[i] = color[0]
    d[i + 1] = color[1]
    d[i + 2] = color[2]
    d[i + 3] = opacities[i / 4]
  }

  bctx.putImageData(data, 0, 0)

  var imagewidth = 20 * 5
  var imageheight = 20 * 5

  function particle(x, y, l) {
    this.x = x
    this.y = y
    this.age = 0
    this.vx = (Math.random() * 8 - 4) / 100
    this.startvy = -(Math.random() * 30 + 10) / 100
    this.vy = this.startvy
    this.scale = Math.random() * .5
    this.lifetime = Math.random() * l + l / 2
    this.finalscale = 5 + this.scale + Math.random()

    this.update = function(deltatime) {
      this.x += this.vx * deltatime
      this.y += this.vy * deltatime
      var frac = Math.pow((this.age) / this.lifetime, .5)
      this.vy = (1 - frac) * this.startvy
      this.age += deltatime
      this.scale = frac * this.finalscale
    }

    this.draw = function() {
      context.globalAlpha = (1 - Math.abs(1 - 2 * (this.age) / this.lifetime)) / 8
      var off = this.scale * imagewidth / 2
      var xmin = this.x - off
      var xmax = xmin + this.scale * imageheight
      var ymin = this.y - off
      var ymax = ymin + this.scale * imageheight
      context.drawImage(buffer, xmin, ymin, xmax - xmin, ymax - ymin)
    }
  }


  function addparticles(x, y, n, lifetime) {
    lifetime = lifetime || 4000
    n = n || 10
    if (n < 1) return Math.random() <= n && pendingparticles.push(new particle(x, y, lifetime));
    for (var i = 0; i < n; i++) {
      pendingparticles.push(new particle(x, y, lifetime))
    };
  }

  function updateanddrawparticles(deltatime) {
    context.clearRect(0, 0, canvas.width, canvas.height);
    deltatime = deltatime || 16
    var newparticles = []
    currentparticles = currentparticles.concat(pendingparticles)
    pendingparticles = []

    currentparticles.forEach(function(p) {
      p.update(deltatime)
      if (p.age < p.lifetime) {
        p.draw()
        newparticles.push(p)
      }
    })
    currentparticles = newparticles
  }

  function frame(time) {
    if (running) {
      var deltat = time - lastframe
      lastframe = time;

      updateanddrawparticles(deltat)

      polyfillAnimFrame(frame)
    }
  }

  var running = false

  function start() {
    running = true
    polyfillAnimFrame(function(time) {
      lastframe = time
      polyfillAnimFrame(frame)
    })
  }

  function stop() {
    running = false
  }

  return {
    start: start,
    stop: stop,
    step: updateanddrawparticles,
    addsmoke: addparticles
  }

}


var canvas = document.getElementById('canvas')
var ctx = canvas.getContext('2d')
canvas.width = innerWidth
canvas.height = innerHeight

var party = smokemachine(ctx, [54, 16.8, 18.2])
party.start() // start animating

onmousemove = function(e) {
  var x = e.clientX
  var y = e.clientY
  var n = .5
  var t = Math.floor(Math.random() * 200) + 3800
  party.addsmoke(x, y, n, t)
}

setInterval(function() {
  party.addsmoke(innerWidth / 2, innerHeight, 1)
}, 100)
html,
body {
  position: absolute;
  margin: 0;
  width: 100%;
}

#hi {
  position: absolute;
  top: 40%;
  width: 100%;
  text-align: center;
}

#hi a {
  color: #fff;
  font-size: 80px;
  text-decoration: none;
  font-family: Lobster;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" />

<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark fixed-top">
  <div class="container">
    <ul>
      <li>
        <a href="#" class="current" id="option-home">
          <span data-text="Home" data-target="#carouselExampleIndicators" data-slide-to="0">Home</span>
        </a>
      </li>
      <li>
        <a href="#">
          <span data-text="About" data-target="#carouselExampleIndicators" data- slide-to="1">About</span>
        </a>
      </li>
      <li>
        <a href="#">
          <span data-text="Chronic Menu" data-target="#carouselExampleIndicators" data-slide-to="2">Chronic Menu</span>
        </a>
      </li>
      <li>
        <a href="#">
          <span data-text="Strains" data-target="#carouselExampleIndicators" data- slide-to="3">Strains</span>
        </a>
      </li>
      <li>
        <a href="#">
          <span data-text="Gallery" data-target="#carouselExampleIndicators" data- slide-to="4">Gallery</span>
        </a>
      </li>
      <li>
        <a href="#">
          <span data-text="Reviews" data-target="#carouselExampleIndicators" data- slide-to="5">Reviews</span>
        </a>
      </li>
    </ul>
  </div>
</nav>

<div style="margin-top:300px;position:absolute;"><a href="#">Link for testing</a></div>

<canvas id="canvas" width="1777" height="898" style="position:relative;"></canvas>


推荐阅读