diff --git a/.vscode/settings.json b/.vscode/settings.json index 4749c3b..5c1b550 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,7 @@ { "cSpell.words": [ "audioshowkit", - "linebreak" + "linebreak", + "songplayer" ] } \ No newline at end of file diff --git a/src/audioshowkit.js b/src/audioshowkit.js index a4a545e..46de58a 100644 --- a/src/audioshowkit.js +++ b/src/audioshowkit.js @@ -1,4 +1,10 @@ -"use strict"; - +import "./styles/songplayer.css"; +// TODO: Finish playlist, and basic music playback functionality. +// TODO: function to easily bind element styling to frequency bin. +// TODO: adjust frequency bin interactively resulting in change in output. +// TODO: Set up global scope audioshowkit object. +// TODO: Animation function to calculate transition rates. +// TODO: Demo functions. +// TODO: basic playlist display. // TODO: Detect annotated elements. -// TODO: Set up global scoping. \ No newline at end of file +// TODO: Create writeup. \ No newline at end of file diff --git a/src/player/SongPlayer.js b/src/player/SongPlayer.js index 6bf3c35..6ba4d96 100644 --- a/src/player/SongPlayer.js +++ b/src/player/SongPlayer.js @@ -116,6 +116,17 @@ export default class SongPlayer { this._playing = true; } + /** + * Toggles whether or not the current song is playing. + */ + togglePlay() { + if (this._playing) { + this.pauseCurrent(); + } else { + this.playCurrent(); + } + } + /** * * @param {number} volume a number between 0 to 1 inclusive representing the volume of the player. @@ -153,32 +164,45 @@ export default class SongPlayer { return this.getCurrentSong().getAudio().duration; } - generatePlayElement(size = 64) { + /** + * + * @returns {HTMLElement} the play button element that can be added to a DOM. + */ + generatePlayElement() { const playButton = document.createElement("button"); playButton.classList.add("player-ctrl"); - playButton.classList.add("play"); - playButton.style.width = size + "px"; - playButton.style.height = size + "px"; - playButton.style.borderLeftWidth = size + "px"; - playButton.style.borderTopWidth = Math.floor(size / 2) + "px"; - playButton.style.borderBottomWidth = Math.ceil(size / 2) + "px"; - // TODO: Finish this play button with event listeners. + playButton.classList.add("play-btn"); + if (!this._playing) playButton.classList.add("paused"); + + playButton.addEventListener("click", (e) => { + this.togglePlay(); + if (this._playing) { + e.currentTarget.classList.remove("paused"); + } else { + e.currentTarget.classList.add("paused"); + } + }); + return playButton; } generateNextElement() { - // TODO: generate a next button in html. + const nextButton = document.createElement("button"); + nextButton.classList.add("player-ctrl"); + nextButton.classList.add("next"); + nextButton.addEventListener("click", () => { + this.next(); + }); + return nextButton; } generatePreviousElement() { - // TODO: generate a previous button in html. - } - - generateSeeker() { - // TODO: generate a seeker in html. - } - - generateVolumeSlider() { - // TODO: generate a volume slider in html. + const previousButton = document.createElement("button"); + previousButton.classList.add("player-ctrl"); + previousButton.classList.add("previous"); + previousButton.addEventListener("click", () => { + this.previous(); + }); + return previousButton; } getCurrentSong() { diff --git a/src/styles/songplayer.css b/src/styles/songplayer.css new file mode 100644 index 0000000..df932ff --- /dev/null +++ b/src/styles/songplayer.css @@ -0,0 +1,25 @@ +.player-ctrl.play-btn { + box-sizing: border-box; + width: 60px; + height: 60px; + transition: 80ms all ease; + will-change: border-width; + cursor: pointer; + border-color: transparent transparent transparent white; + + border-style: solid; + border-width: 60px 0px 30px 30px; +} + +.player-ctrl.play-btn.paused { + border-style: double; + border-width: 0px 0px 0px 60px; +} + +.player-ctrl.next { + border-style: none; +} + +.player-ctrl.previous { + border-style: none; +} \ No newline at end of file