0

This is code for a spinning wheel. When a person clicks the spinning wheel, it rotates and gives a result after a few seconds (depending on the script's time settings). How can an auto-playing sound be added to the below code? So, when the wheel stops, the sound also plays automatically and stops when the audio file ends.

(function($) {
  var venues = [{
    "name": "1900 Mexican Grill",
    "type": "Mexican"
  }, {
    "name": "300 East",
    "type": "American/Upscale"
  }, {
    "name": "Angry Ale's",
    "type": "American/Pub "
  }, {
    "name": "Azteca",
    "type": "Mexican"
  }, {
    "name": "Bedder Bedder and Moore",
    "type": "Sandwiches, Salads, Soups"
  }, {
    "name": "Boading",
    "type": "Chinese"
  }, {
    "name": "Brazwell's Premium Pub",
    "type": "American/Pub "
  }, {
    "name": "Brio Tuscan Grille",
    "type": "Italian"
  }, {
    "name": "Brixx",
    "type": "Pizza/Salads"
  }, {
    "name": "Café at 6100",
    "type": "Home Cooking"
  }, {
    "name": "California Pizza Kitchen",
    "type": "Pizza/Salads"
  }, {
    "name": "Chick-Fil-A",
    "type": "Fast Food"
  }, {
    "name": "City Tavern",
    "type": "American/Upscale"
  }, {
    "name": "Copper",
    "type": "Indian"
  }, {
    "name": "Cowfish",
    "type": "Sushi"
  }, {
    "name": "Duckworth's",
    "type": "American/Pub "
  }, {
    "name": "Eddie's Place",
    "type": "American/Pub "
  }, {
    "name": "El Camino",
    "type": "Mexican"
  }, {
    "name": "Fairview Plaza Restaurant",
    "type": "Home Cooking"
  }, {
    "name": "Firebird's Wood Fired Grill",
    "type": "American/Upscale"
  }, {
    "name": "Firehouse Subs",
    "type": "Sandwiches, Salads, Soups"
  }, {
    "name": "Flying Biscuit",
    "type": "American/Fast"
  }, {
    "name": "Fuel",
    "type": "Pizza"
  }, {
    "name": "Good Food on Montford",
    "type": "American/Upscale"
  }, {
    "name": "Harper's Restaurant",
    "type": "American/Upscale"
  }, {
    "name": "Hawthorne's Pizza",
    "type": "Pizza/Italian"
  }, {
    "name": "Luisa's Brick Oven Pizza",
    "type": "Pizza/Italian"
  }, {
    "name": "Maverick Rock Taco",
    "type": "Mexican"
  }, {
    "name": "McAllister's",
    "type": "Sandwiches, Salads, Soups"
  }, {
    "name": "Mellow Mushroom",
    "type": "Pizza/Salads"
  }, {
    "name": "Moe's",
    "type": "Mexican"
  }, {
    "name": "Moosehead Grill",
    "type": "American/Pub "
  }, {
    "name": "Paco's Tacos and Tequila",
    "type": "Mexican"
  }, {
    "name": "Panera ",
    "type": "Sandwiches, Salads, Soups"
  }, {
    "name": "PF Chang's",
    "type": "Chinese"
  }, {
    "name": "Portofinos",
    "type": "Pizza/Italian"
  }, {
    "name": "Qdoba",
    "type": "Mexican"
  }, {
    "name": "Rooster's Wood Fire Kitchen",
    "type": "American/Upscale"
  }, {
    "name": "Rusty's Deli",
    "type": "Sandwiches, Salads, Soups"
  }, {
    "name": "Taco Bell",
    "type": "Fast Food"
  }, {
    "name": "Taco Mac",
    "type": "American/Pub "
  }, {
    "name": "Terrace Café",
    "type": "American/Upscale"
  }, {
    "name": "The Roasting Company",
    "type": "American/Fast"
  }, {
    "name": "Village Tavern",
    "type": "American/Upscale"
  }, {
    "name": "Which Witch?",
    "type": "Sandwiches, Salads, Soups"
  }, {
    "name": "Zack's Hamburgers",
    "type": "American/Fast"
  }];

  // Helpers
  var blackHex = '#333',
    whiteHex = '#fff',
    shuffle = function(o) {
      for (var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x)
      ;
      return o;
    },
    halfPI = Math.PI / 2,
    doublePI = Math.PI * 2;

  String.prototype.hashCode = function() {
    // See http://www.cse.yorku.ca/~oz/hash.html        
    var hash = 5381,
      i;
    for (i = 0; i < this.length; i++) {
      char = this.charCodeAt(i);
      hash = ((hash << 5) + hash) + char;
      hash = hash & hash; // Convert to 32bit integer
    }
    return hash;
  };

  Number.prototype.mod = function(n) {
    return ((this % n) + n) % n;
  };

  // WHEEL!
  var wheel = {
    timerHandle: 0,
    timerDelay: 33,

    angleCurrent: 0,
    angleDelta: 0,

    size: 290,

    canvasContext: null,

    colors: ['#003366', '#FF6600', '#CCCC00', '#006600', '#3333CC', '#CC0066', '#FF3300', '#009900', '#6600CC', '#33CC33', '#0066CC', '#FF0066', '#3300FF', '#00CC00', '#FFCC00'],

    segments: [],

    seg_colors: [], // Cache of segments to colors

    maxSpeed: Math.PI / 16,

    upTime: 1000, // How long to spin up for (in ms)
    downTime: 5000, // How long to slow down for (in ms)

    spinStart: 0,

    frames: 0,

    centerX: 300,
    centerY: 300,

    spin: function() {
      // Start the wheel only if it's not already spinning
      if (wheel.timerHandle == 0) {
        wheel.spinStart = new Date().getTime();
        wheel.maxSpeed = Math.PI / (16 + Math.random()); // Randomly vary how hard the spin is
        wheel.frames = 0;
        wheel.sound.play();

        wheel.timerHandle = setInterval(wheel.onTimerTick, wheel.timerDelay);
      }
    },

    onTimerTick: function() {
      var duration = (new Date().getTime() - wheel.spinStart),
        progress = 0,
        finished = false;

      wheel.frames++;
      wheel.draw();

      if (duration < wheel.upTime) {
        progress = duration / wheel.upTime;
        wheel.angleDelta = wheel.maxSpeed *
          Math.sin(progress * halfPI);
      } else {
        progress = duration / wheel.downTime;
        wheel.angleDelta = wheel.maxSpeed *
          Math.sin(progress * halfPI + halfPI);
        if (progress >= 1) {
          finished = true;
        }
      }

      wheel.angleCurrent += wheel.angleDelta;
      while (wheel.angleCurrent >= doublePI) {
        // Keep the angle in a reasonable range
        wheel.angleCurrent -= doublePI;
      }
      if (finished) {
        clearInterval(wheel.timerHandle);
        wheel.timerHandle = 0;
        wheel.angleDelta = 0;

        if (console) {
          console.log((wheel.frames / duration * 1000) + " FPS");
        }
      }

      /*
      // Display RPM
      var rpm = (wheel.angleDelta * (1000 / wheel.timerDelay) * 60) / (Math.PI * 2);
      $("#counter").html( Math.round(rpm) + " RPM" );
       */
    },

    init: function(optionList) {
      try {
        wheel.initWheel();
        wheel.initAudio();
        wheel.initCanvas();
        wheel.draw();

        $.extend(wheel, optionList);

      } catch (exceptionData) {
        alert('Wheel is not loaded ' + exceptionData);
      }

    },

    initAudio: function() {
      var sound = document.createElement('audio');
      sound.setAttribute('src', 'wheel.mp3');
      wheel.sound = sound;
    },

    initCanvas: function() {
      var canvas = $('#canvas')[0];
      canvas.addEventListener("click", wheel.spin, false);
      wheel.canvasContext = canvas.getContext("2d");
    },

    initWheel: function() {
      shuffle(wheel.colors);
    },

    // Called when segments have changed
    update: function() {
      // Ensure we start mid way on a item
      //var r = Math.floor(Math.random() * wheel.segments.length);
      var r = 0,
        segments = wheel.segments,
        len = segments.length,
        colors = wheel.colors,
        colorLen = colors.length,
        seg_color = [], // Generate a color cache (so we have consistant coloring)
        i
      wheel.angleCurrent = ((r + 0.5) / wheel.segments.length) * doublePI;

      for (i = 0; i < len; i++) {
        seg_color.push(colors[segments[i].hashCode().mod(colorLen)]);
      }
      wheel.seg_color = seg_color;

      wheel.draw();
    },

    draw: function() {
      wheel.clear();
      wheel.drawWheel();
      wheel.drawNeedle();
    },

    clear: function() {
      wheel.canvasContext.clearRect(0, 0, 1000, 800);
    },

    drawNeedle: function() {
      var ctx = wheel.canvasContext,
        centerX = wheel.centerX,
        centerY = wheel.centerY,
        size = wheel.size,
        i,
        centerSize = centerX + size,
        len = wheel.segments.length,
        winner;

      ctx.lineWidth = 2;
      ctx.strokeStyle = blackHex;
      ctx.fillStyle = whiteHex;

      ctx.beginPath();

      ctx.moveTo(centerSize - 10, centerY);
      ctx.lineTo(centerSize + 10, centerY - 10);
      ctx.lineTo(centerSize + 10, centerY + 10);
      ctx.closePath();

      ctx.stroke();
      ctx.fill();

      // Which segment is being pointed to?
      i = len - Math.floor((wheel.angleCurrent / doublePI) * len) - 1;

      // Now draw the winning name
      ctx.textAlign = "left";
      ctx.textBaseline = "middle";
      ctx.fillStyle = blackHex;
      ctx.font = "2em Arial";
      winner = wheel.segments[i] || 'Choose at least 1 Venue';
      ctx.fillText(winner, centerSize + 20, centerY);
    },

    drawSegment: function(key, lastAngle, angle) {
      var ctx = wheel.canvasContext,
        centerX = wheel.centerX,
        centerY = wheel.centerY,
        size = wheel.size,
        colors = wheel.seg_color,
        value = wheel.segments[key];

      //ctx.save();
      ctx.beginPath();

      // Start in the centre
      ctx.moveTo(centerX, centerY);
      ctx.arc(centerX, centerY, size, lastAngle, angle, false); // Draw an arc around the edge
      ctx.lineTo(centerX, centerY); // Now draw a line back to the center

      // Clip anything that follows to this area
      //ctx.clip(); // It would be best to clip, but we can double performance without it
      ctx.closePath();

      ctx.fillStyle = colors[key];
      ctx.fill();
      ctx.stroke();

      // Now draw the text
      ctx.save(); // The save ensures this works on Android devices
      ctx.translate(centerX, centerY);
      ctx.rotate((lastAngle + angle) / 2);

      ctx.fillStyle = whiteHex;
      ctx.fillText(value.substr(0, 20), size - 15, 0);
      ctx.restore();
    },

    drawWheel: function() {
      var ctx = wheel.canvasContext,
        angleCurrent = wheel.angleCurrent,
        lastAngle = angleCurrent,
        len = wheel.segments.length,
        centerX = wheel.centerX,
        centerY = wheel.centerY,
        size = wheel.size,
        angle,
        i;

      ctx.lineWidth = 1;
      ctx.strokeStyle = blackHex;
      ctx.textBaseline = "middle";
      ctx.textAlign = "right";
      ctx.font = "1em Arial";

      for (i = 1; i <= len; i++) {
        angle = doublePI * (i / len) + angleCurrent;
        wheel.drawSegment(i - 1, lastAngle, angle);
        lastAngle = angle;
      }

      // Draw a center circle
      ctx.beginPath();
      ctx.arc(centerX, centerY, 20, 0, doublePI, false);
      ctx.closePath();

      ctx.fillStyle = whiteHex;
      //ctx.strokeStyle = blackHex;
      ctx.fill();
      ctx.stroke();

      // Draw outer circle
      ctx.beginPath();
      ctx.arc(centerX, centerY, size, 0, doublePI, false);
      ctx.closePath();

      ctx.lineWidth = 10;
      //ctx.strokeStyle = blackHex;
      ctx.stroke();
    }
  };
  $(function() {
    var $venues = $('#venues'),
      $venueName = $('#name'),
      $venueType = $('#types'),
      venueTypes = [],
      $list = $('<ul/>'),
      $types = $('<ul/>'),
      $filterToggler = $('#filterToggle'),
      arrayUnique = function(a) {
        return a.reduce(function(p, c) {
          if (p.indexOf(c) < 0) {
            p.push(c);
          }
          return p;
        }, []);
      };

    $.each(venues, function(index, venue) {
      $list.append(
        $("<li/>")
        .append(
          $("<input />").attr({
            id: 'venue-' + index,
            name: venue.name,
            value: venue.name,
            type: 'checkbox',
            checked: true
          })
          .change(function() {
            var cbox = this,
              segments = wheel.segments,
              i = segments.indexOf(cbox.value);

            if (cbox.checked && i === -1) {
              segments.push(cbox.value);
            } else if (!cbox.checked && i !== -1) {
              segments.splice(i, 1);
            }

            segments.sort();
            wheel.update();
          })

        ).append(
          $('<label />').attr({
            'for': 'venue-' + index
          })
          .text(venue.name)
        )
      );
      venueTypes.push(venue.type);
    });
    $.each(arrayUnique(venueTypes), function(index, venue) {
      $types.append(
        $("<li/>")
        .append(
          $("<input />").attr({
            id: 'venue-type-' + index,
            name: venue,
            value: venue,
            type: 'checkbox',
            checked: true
          })
          .change(function() {
            var $this = $(this),
              i;
            for (i = 0; i < venues.length; i++) {
              if (venues[i].type === $this.val()) {
                $('[name="' + venues[i].name + '"]').prop("checked", $this.prop('checked')).trigger('change');
              }
            }
          })

        ).append(
          $('<label />').attr({
            'for': 'venue-' + index
          })
          .text(venue)
        )
      )
    });

    $venueName.append($list);
    $venueType.append($types);
    // Uses the tinysort plugin, but our array is sorted for now.
    //$list.find('>li').tsort("input", {attr: "value"});

    wheel.init();

    $.each($venueName.find('ul input:checked'), function(key, cbox) {
      wheel.segments.push(cbox.value);
    });

    wheel.update();
    $venues.slideUp().data("open", false);
    $filterToggler.on("click", function() {
      if ($venues.data("open")) {
        $venues.slideUp().data("open", false);
      } else {
        $venues.slideDown().data("open", true);
      }
    });

    $('.checkAll').on("click", function() {
      $(this).parent().next('div').find('input').prop('checked', $(this).prop('checked')).trigger("change");
    });
  });
}(jQuery));
body {
  background: #fff;
  font-family: sans-serif;
  color: #666;
}

h1,
h2 {
  font-weight: 700;
  line-height: 2;
}

input[type='checkbox']+label {
  padding-left: .5em;
}

label,
#filterToggle {
  display: inline-block;
}

#venues,
#filterToggle {
  background: #fefefe;
  box-shadow: 0 1px 2px #efefef;
}

#venues {
  padding: .5em;
  overflow: hidden;
}

#venues ul,
#venues h2 {
  clear: both;
}

#venues li {
  float: left;
  width: 25%;
  line-height: 1.5;
  vertical-align: middle;
}

#filterToggle {
  border-radius: 0 0 3px 3px;
  cursor: pointer;
  margin-left: .5em;
  margin-top: -1px;
  padding: .5em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="venues">
  <h1>Venues <input type="checkbox" class="checkAll" checked /></h1>
  <div id="name"></div>
  <h2>Types <input type="checkbox" class="checkAll" checked /></h2>
  <div id="types"></div>
</div>
<div id="filterToggle">. . .</div>
<div id="wheel">
  <canvas id="canvas" width="1000" height="600"></canvas>
</div>
<div id="counter"></div>

How to play a sound when the above script gives the result?

Blye
  • 619
  • 4
  • 20
CrazyJack
  • 81
  • 1
  • 8
  • Playing sound has nothing to do with CSS so we can probably remove that tag? Also have you searched on the internet how to play a sound with JavaScript? StackOverflow has answers as well. – Peter Krebs Aug 09 '22 at 11:08
  • The sound has to be played exactly when the spin stops. – CrazyJack Aug 09 '22 at 13:10
  • You can create a function that plays sound, and then call that function when the spin stops. – Kokodoko Aug 09 '22 at 13:12
  • Auto-playing a sound is done via HTML5 – CrazyJack Aug 09 '22 at 13:15
  • //play audio with from html audio element - JS Code: document.getElementById('myAudioTagID').play(); //play audio with out html audio tag var myAudio = new Audio('my_great_song.mp3'); myAudio.play(); – CrazyJack Aug 09 '22 at 13:16
  • See the answer I linked above. Just call `myAudio.play();` however many times you wannt after you have initialized it. – Peter Krebs Aug 09 '22 at 13:56

0 Answers0