From e9493c968872fea89ef77462924b902c99596ac5 Mon Sep 17 00:00:00 2001 From: Aanchi-glitch2744 Date: Sun, 22 Oct 2023 12:58:31 +0530 Subject: [PATCH] Created a Drum Player Machine --- Fronted Projects/DrumMachine/index.html | 28 +++ Fronted Projects/DrumMachine/scripts.js | 306 ++++++++++++++++++++++++ Fronted Projects/DrumMachine/styles.css | 274 +++++++++++++++++++++ 3 files changed, 608 insertions(+) create mode 100644 Fronted Projects/DrumMachine/index.html create mode 100644 Fronted Projects/DrumMachine/scripts.js create mode 100644 Fronted Projects/DrumMachine/styles.css diff --git a/Fronted Projects/DrumMachine/index.html b/Fronted Projects/DrumMachine/index.html new file mode 100644 index 00000000..e3e8c0c3 --- /dev/null +++ b/Fronted Projects/DrumMachine/index.html @@ -0,0 +1,28 @@ + + + + + + Document + + + + + + + + +
+ + +
+
+ + + + + + + + + \ No newline at end of file diff --git a/Fronted Projects/DrumMachine/scripts.js b/Fronted Projects/DrumMachine/scripts.js new file mode 100644 index 00000000..1414e454 --- /dev/null +++ b/Fronted Projects/DrumMachine/scripts.js @@ -0,0 +1,306 @@ +/** + * Javascript Drum Machine + * @author Sebastian Inman + * @version 1.0.0 + * @desc This is a javascript experiment created + * to demonstrate music patterns in the web browser. + * I started this project just for fun and intend on + * adding more to it and keeping this pen updated. + * All drum samples were provided by 99Samples: + * http://99sounds.org/drum-samples/ + */ + +(function(DrummerJS, $, undefined) { + + 'use strict'; + + // ====================================== + // establish public variables and methods + // ====================================== + + DrummerJS.title = 'Javascript Drum Machine'; + DrummerJS.description = 'Create audio loops using drum samples.' + DrummerJS.author = 'Sebastian Inman'; + + var $_container = $('.player'); + var $_containerWidth = $_container.width(); + var $_containerHeight = $_container.height(); + + var $_setBPM = $('#set-bpm'); + var $_playPauseBtn = $('#play-pause'); + var $_setSamplesBtn = $('#set-samples'); + + var $_toggleRowBtn; + var $_sampleBtn; + + var _urlHash; + + var _sampleList = 'default'; + + var _totalSteps = 16; + var _totalRows = 5; + + var _currentStep = 1; + + var _sampleRate = 44100; + var _minuteInSeconds = 60; + var _beatsPerMinute = 90; + + var _stepDelay; + + var calculateBPM = function() { + + _stepDelay = Math.round(((_sampleRate * _minuteInSeconds) / (_beatsPerMinute * _totalSteps)) / _totalSteps); + + return _stepDelay; + + }; + + // ======================================================= + // creates namespace provider which helps isolate + // implementated code from the global namespace, providing + // a single point of access for functions and methods. + // ======================================================= + // this keeps the code more organized and allows the code + // to be combined into more logical sections. + // ======================================================= + + DrummerJS.handler = (function() { + + function _handler() { + + /** + * @var _this + * @desc in a 'non-strict' environment, 'this' is bound to + * the global scope (if it hasn't been bound to anything else). + * in 'strict' mode it is set to undefined. we store it in a + * variable to avoid scope conflicts. + */ + + var _this = this; + + var _isPlaying; + + this.playPauseHandler = function(button) { + + calculateBPM(); + + var status = button.data('playing'); + + if(status === 'true') { + + button.data('playing', 'false').html(''); + + _this.stopAudio(); + + }else { + + button.data('playing', 'true').html(''); + + _this.startAudio(); + + } + + }; + + this.pageLoad = function() { + + if(!window.location.hash) { + + window.location.hash = '!/'; + + } + + _urlHash = window.location.hash.split('/'); + + }; + + this.toggleSample = function(sample) { + + sample.toggleClass('active'); + + }; + + this.toggleSampleHandler = function() { + + $('.sample').on('click', function() { + + _this.toggleSample($(this)); + + }); + + }; + + this.updateSampleList = function(samples) { + + _sampleList = samples; + + console.log(_sampleList); + + }; + + this.updateBPM = function(bpm) { + + _beatsPerMinute = bpm; + + calculateBPM(); + + _this.stopAudio(); + _this.startAudio(); + + }; + + this.stopAudio = function() { + + $_sampleBtn.removeClass('hit'); + + clearInterval(_isPlaying); + + }; + + this.startAudio = function() { + + _isPlaying = window.setInterval(function() { + + _this.playAudio() + + }, _stepDelay); + + } + + this.playAudio = function() { + + if(_currentStep < _totalSteps) { + + _currentStep++; + + }else if(_currentStep >= _totalSteps){ + + _currentStep = 1; + + } + + $_sampleBtn.removeClass('hit'); + + for(var i = 1; i < _totalRows + 1; i++) { + + var $_newSample = $('.sample[data-row="' + i + '"][data-column="' + _currentStep + '"]'); + + if($_newSample.hasClass('active')) { + + $('#' + i)[0].currentTime = 0; + + if(!$_newSample.hasClass('disabled')) { + + $('#' + i)[0].play(); + + }else{ + + $('#' + i)[0].pause(); + + } + + $_newSample.addClass('hit'); + + } + + } + + }; + + this.createMatrix = function(rows, columns) { + + var sampleSize = $_containerWidth / columns; + + for(var i = 1; i < rows + 1; i++) { + + $('
').appendTo('.container'); + + $('').prependTo('#row-' + i); + + for(var k = 1; k < columns + 1; k++) { + + $('
').appendTo('#row-' + i); + + } + + } + + $_toggleRowBtn = $('.enable-disable-row'); + $_sampleBtn = $('.sample'); + + calculateBPM(); + + }; + + this.toggleRowBtnHandler = function(button) { + + button.toggleClass('disabled'); + + var rowID = button.attr('id').replace('toggle-row-', ''); + + $('.sample[data-row="' + rowID + '"]').toggleClass('disabled'); + + }; + + + /** + * @function init() + * @desc initiates the DrummerJS global function + * creating an active instance of the script on the + * current site. + */ + + this.init = function() { + + // run functions here + + _this.pageLoad(); + + _this.createMatrix(_totalRows, _totalSteps); + _this.toggleSampleHandler(); + + $_playPauseBtn.on('click', function() { + + _this.playPauseHandler($(this)); + + }); + + $_toggleRowBtn.on('click', function() { + + _this.toggleRowBtnHandler($(this)); + + }); + + $_setBPM.on('change', function() { + + _this.updateBPM($(this).val()); + + }); + + $_setSamplesBtn.on('change', function() { + + _this.updateSampleList($(this).val()); + + }); + + // start the drum machine + + $_playPauseBtn.click(); + + return this; + + }; + + // initiate the script! + return this.init(); + + } + + // create a new handler object + return new _handler(); + + }()); + +// assign DrummerJS to the global namespace +}(window.DrummerJS = window.DrummerJS || {}, jQuery)); diff --git a/Fronted Projects/DrumMachine/styles.css b/Fronted Projects/DrumMachine/styles.css new file mode 100644 index 00000000..7a32b7a2 --- /dev/null +++ b/Fronted Projects/DrumMachine/styles.css @@ -0,0 +1,274 @@ +*, *::before, *::after { + + -webkit-box-sizing: border-box; + box-sizing: border-box; + + } + + *:before, *:after { + + content: ''; + + } + + html, body { + + margin: 0px; + padding: 0px; + + } + + body { + + background: #16181C; + font-family: 'Open Sans', sans-serif; + + } + + div { + + display: block; + position: relative; + + } + + header { + + width: 1300px; + height: auto; + padding: 50px 0px; + margin: 0px auto; + position: relative; + + } + + header label { + + color: white; + font-size: 12px; + margin-left: 20px; + + } + + header label a { + + color: #60B5D1; + + } + + .container { + + left: 50%; + z-index: 0; + float: left; + width: 1100px; + height: auto; + margin-left: 100px; + max-height: 100vh; + position: relative; + border: 8px solid #16181C; + transform: translateX(-50%); + + } + + .row { + + float: left; + clear: both; + width: 100%; + height: auto; + max-width: 100%; + border-bottom: 8px solid #16181C; + + } + + .row::before { + + top: 0px; + left: -208px; + width: 200px; + height: 100%; + position: absolute; + letter-spacing: 1px; + border-radius: 2px; + background: rgba(0, 0, 0, 0.025); + border-right: 8px solid #16181C; + box-shadow: inset 0px 0px 0px 1px rgba(0, 0, 0, 0.65), + inset 0px 0px 0px 2px rgba(255, 255, 255, 0.035), + inset 0px 5px 20px -10px rgba(255, 255, 255, 0.25), + inset 0px -5px 20px -10px black; + + } + + .row::after { + + top: 15%; + left: -198px; + width: 172px; + height: 70%; + z-index: 1; + padding: 15px; + position: absolute; + font-family: 'Open Sans'; + font-weight: 300; + text-transform: uppercase; + color: rgba(255,255,255,0.35); + font-size: 11px; + border-radius: 2px; + background: #101114; + border: 1px solid rgba(0, 0, 0, 0.5); + box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.035), + inset 0px -20px 20px -20px rgba(0, 0, 0, 0.5), + inset 0px 20px 20px -20px rgba(255, 255, 255, 0.05); + + } + + .row:nth-child(1)::after { + + content: 'Drum Kick'; + + } + + .row:nth-child(2)::after { + + content: 'Drum Snare'; + + } + + .row:nth-child(3)::after { + + content: 'Drum Hi-Hat'; + + } + + .row:nth-child(4)::after { + + content: 'Drum Hi-Hat 2'; + + } + + .row:nth-child(5)::after { + + content: 'Drum Tom'; + + } + + .sample { + + float: left; + border-radius: 2px; + display: inline-block; + background: rgba(0, 0, 0, 0.025); + border-right: 8px solid #16181C; + box-shadow: inset 0px 0px 0px 1px rgba(0, 0, 0, 0.65), + inset 0px 0px 0px 2px rgba(255, 255, 255, 0.035), + inset 0px 5px 20px -10px rgba(255, 255, 255, 0.25), + inset 0px -5px 20px -10px black; + + } + + .sample:nth-child(8n+6)::after { + + top: 1px; + left: 1px; + z-index: -1; + opacity: 0.05; + border-radius: 2px; + background: #FF7B5F; + position: absolute; + width: calc(400% + 22px); + height: calc(100% + 0px); + + } + + .sample::before { + + top: 15%; + left: 15%; + width: 70%; + height: 70%; + z-index: 1; + position: absolute; + border-radius: 2px; + background: #101114; + border: 1px solid rgba(0, 0, 0, 0.5); + box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.035), + inset 0px -20px 20px -20px rgba(0, 0, 0, 0.5), + inset 0px 20px 20px -20px rgba(255, 255, 255, 0.05); + + } + + .sample:active::before, + .sample:focus::before { + + background: #0C0D0F; + box-shadow: inset 0px 0px 0px 1px rgba(255, 255, 255, 0.035), + inset 0px 20px 20px -20px rgba(0, 0, 0, 0.5), + inset 0px 20px 20px -20px rgba(255, 255, 255, 0.05); + + } + + .sample.active::before { + + background: #DB6B53; + border: 1px solid rgba(255, 255, 255, 0.035); + box-shadow: inset 0px 0px 0px 1px rgba(0, 0, 0, 0.05), + inset 0px -20px 20px -20px rgba(0, 0, 0, 0.85), + inset 0px 20px 20px -20px rgba(255, 255, 255, 0.05); + + } + + .sample.active.hit::before { + + background: #DB6B53; + border: 1px solid rgba(255, 255, 255, 0.15); + box-shadow: 0px 0px 20px 1px #DB7E53, + inset 0px 0px 0px 1px rgba(0, 0, 0, 0.05), + inset 0px -20px 20px -20px rgba(0, 0, 0, 1), + inset 0px 20px 20px -20px rgba(255, 255, 255, 1); + + } + + .sample.active.disabled.hit::before { + + background: #DBBBB0; + border: 1px solid rgba(255, 255, 255, 0.035); + box-shadow: inset 0px 0px 0px 1px rgba(0, 0, 0, 0.05), + inset 0px -20px 20px -20px rgba(0, 0, 0, 0.85), + inset 0px 20px 20px -20px rgba(255, 255, 255, 0.05); + + } + + .sample.active.disabled::before { + + opacity: 0.35; + background: #DBBBB0; + + } + + .enable-disable-row { + + top: 50%; + left: -60px; + width: 14px; + height: 14px; + outline: none; + border: none; + z-index: 2; + margin-top: -7px; + background: #81B55B; + position: absolute; + border-radius: 50%; + box-shadow: 0px 0px 0px 2px rgba(0, 0, 0, 0.5), + 0px 0px 0px 3px rgba(255, 255, 255, 0.15), + 0px 0px 0px 4px rgba(0, 0, 0, 0.5), + inset 0px 0px 5px -1px white; + + } + + .enable-disable-row.disabled { + + background: #CF472F; + + } + \ No newline at end of file