diff --git a/01 - JavaScript Drum Kit/index-START.html b/01 - JavaScript Drum Kit/index-START.html index 4070d32767..91ce666a1f 100644 --- a/01 - JavaScript Drum Kit/index-START.html +++ b/01 - JavaScript Drum Kit/index-START.html @@ -57,10 +57,6 @@ - - - + diff --git a/01 - JavaScript Drum Kit/index.js b/01 - JavaScript Drum Kit/index.js new file mode 100644 index 0000000000..14f4c1d69d --- /dev/null +++ b/01 - JavaScript Drum Kit/index.js @@ -0,0 +1,26 @@ +(function(){ + +document.addEventListener("DOMContentLoaded", function(event) { + // play sound on key down + window.addEventListener('keydown', function(e){ + const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`); + if (!audio) return; + + audio.currentTime=0; + audio.play(); + + const key = document.querySelector(`.key[data-key="${e.keyCode}"]`); + key.classList.add('playing'); + }); + + // remove class after transition happens + const keys = document.querySelectorAll('.key'); + keys.forEach(key => key.addEventListener('transitionend',function removeTransition(e) { + if (e.propertyName !== 'transform') return; + this.classList.remove('playing'); + })); +}); + +}()); + + diff --git a/02 - JS + CSS Clock/index-START.html b/02 - JS + CSS Clock/index-START.html index 2712384201..4b06971e8b 100644 --- a/02 - JS + CSS Clock/index-START.html +++ b/02 - JS + CSS Clock/index-START.html @@ -61,13 +61,14 @@ background:black; position: absolute; top:50%; + transform-origin: 100%; + transform: rotate(90deg); + transition: all 0.05s; + transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1); } - + diff --git a/02 - JS + CSS Clock/index.js b/02 - JS + CSS Clock/index.js new file mode 100644 index 0000000000..fedc867d08 --- /dev/null +++ b/02 - JS + CSS Clock/index.js @@ -0,0 +1,27 @@ +(function(){ + +document.addEventListener("DOMContentLoaded", function(event) { + const hourHand = document.querySelector('.hour-hand'); + const minuteHand = document.querySelector('.min-hand'); + const secondHand = document.querySelector('.second-hand'); + + function rotoateHand(el, degrees) { + el.style.transform = `rotate(${degrees}deg)`; + } + + function setTime() { + const now = new Date(); + + const minutesAsPercentOfHour = now.getMinutes()/60; + + rotoateHand(hourHand, (((now.getHours() + minutesAsPercentOfHour)/12) * 360)+90); + rotoateHand(minuteHand, (minutesAsPercentOfHour * 360)+90); + rotoateHand(secondHand, ((now.getSeconds()/60) * 360)+90); + } + + setInterval(setTime, 1000); + setTime(); +}); +}()); + + diff --git a/03 - CSS Variables/index-START.html b/03 - CSS Variables/index-START.html index 7171607a8b..1e648925ae 100644 --- a/03 - CSS Variables/index-START.html +++ b/03 - CSS Variables/index-START.html @@ -21,7 +21,22 @@

Update CSS Variables with JS

- + diff --git a/03 - CSS Variables/index.js b/03 - CSS Variables/index.js new file mode 100644 index 0000000000..f64ec6532d --- /dev/null +++ b/03 - CSS Variables/index.js @@ -0,0 +1,13 @@ +(function(){ + +document.addEventListener("DOMContentLoaded", function(event) { + function handleUpdate() { + const suffix = this.dataset.sizing || ''; + document.documentElement.style.setProperty(`--${this.name}`, `${this.value}${suffix}`); + } + + const inputs = document.querySelectorAll('input'); + inputs.forEach(input => input.addEventListener('change', handleUpdate)); + inputs.forEach(input => input.addEventListener('mousemove', handleUpdate)); +}); +}()); \ No newline at end of file diff --git a/04 - Array Cardio Day 1/index-START.html b/04 - Array Cardio Day 1/index-START.html index 4162bce339..571e0342cc 100644 --- a/04 - Array Cardio Day 1/index-START.html +++ b/04 - Array Cardio Day 1/index-START.html @@ -31,31 +31,65 @@ const people = ['Beck, Glenn', 'Becker, Carl', 'Beckett, Samuel', 'Beddoes, Mick', 'Beecher, Henry', 'Beethoven, Ludwig', 'Begin, Menachem', 'Belloc, Hilaire', 'Bellow, Saul', 'Benchley, Robert', 'Benenson, Peter', 'Ben-Gurion, David', 'Benjamin, Walter', 'Benn, Tony', 'Bennington, Chester', 'Benson, Leana', 'Bent, Silas', 'Bentsen, Lloyd', 'Berger, Ric', 'Bergman, Ingmar', 'Berio, Luciano', 'Berle, Milton', 'Berlin, Irving', 'Berne, Eric', 'Bernhard, Sandra', 'Berra, Yogi', 'Berry, Halle', 'Berry, Wendell', 'Bethea, Erin', 'Bevan, Aneurin', 'Bevel, Ken', 'Biden, Joseph', 'Bierce, Ambrose', 'Biko, Steve', 'Billings, Josh', 'Biondo, Frank', 'Birrell, Augustine', 'Black Elk', 'Blair, Robert', 'Blair, Tony', 'Blake, William']; + const name = inventor => `${inventor.first} ${inventor.last}`; + const nameAndYear = inventor => `${name(inventor)} : ${inventor.year}`; + const nameYearAndAge = inventor => `${nameAndYear(inventor)} : ${inventor.passed - inventor.year}`; + const printArray = (results, format) => console.log(results.map(format).join('\n')); + // Array.prototype.filter() // 1. Filter the list of inventors for those who were born in the 1500's + + printArray(inventors.filter(inventor => inventor.year >=1500 && inventor.year < 1600), nameAndYear); // Array.prototype.map() // 2. Give us an array of the inventors' first and last names + printArray(inventors, name); + // Array.prototype.sort() // 3. Sort the inventors by birthdate, oldest to youngest + printArray(inventors.sort((a, b) => a.year - b.year), nameAndYear); + // Array.prototype.reduce() // 4. How many years did all the inventors live? + console.log(inventors.reduce((sum, curr) => sum + curr.passed - curr.year, 0)); + // 5. Sort the inventors by years lived + printArray(inventors.sort((a, b) => (a.passed - a.year) - (b.passed - b.year)), nameYearAndAge); + // 6. create a list of Boulevards in Paris that contain 'de' anywhere in the name // https://en.wikipedia.org/wiki/Category:Boulevards_in_Paris + const titles = []; + document.querySelectorAll('.mw-category-group a').forEach(i => titles.push(i.title)); + console.log(titles.filter(i => i.indexOf(' de ') > -1).length); // 7. sort Exercise // Sort the people alphabetically by last name + printArray(people.sort((a, b) => { + if (a.toUpperCase() < b.toUpperCase()) { + return -1; + } + if (a.toUpperCase() > b.toUpperCase()) { + return 1; + } + return 0; + }), i => i ); + // 8. Reduce Exercise // Sum up the instances of each of these const data = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 'walk', 'car', 'van', 'car', 'truck' ]; + console.log(data.reduce((all, current) => { + let counter = all.get(current) || 0; + all.set(current, counter+1); + return all; + }, new Map())); + diff --git a/05 - Flex Panel Gallery/index-START.html b/05 - Flex Panel Gallery/index-START.html index e1d643ad5c..da2e58811d 100644 --- a/05 - Flex Panel Gallery/index-START.html +++ b/05 - Flex Panel Gallery/index-START.html @@ -24,6 +24,7 @@ .panels { min-height:100vh; overflow: hidden; + display:flex; } .panel { @@ -41,6 +42,11 @@ font-size: 20px; background-size:cover; background-position:center; + flex:1; + justify-content: center; + align-items: center; + display: flex; + flex-direction: column; } @@ -54,8 +60,17 @@ margin:0; width: 100%; transition:transform 0.5s; + flex: 1 0 auto; + display: flex; + justify-content: center; + align-items: center; } + .panel > *:first-child { transform: translateY(-100%); } + .panel.open-active > *:first-child { transform: translateY(0); } + .panel > *:last-child { transform: translateY(100%); } + .panel.open-active > *:last-child { transform: translateY(0); } + .panel p { text-transform: uppercase; font-family: 'Amatic SC', cursive; @@ -68,6 +83,7 @@ .panel.open { font-size:40px; + flex: 5; } .cta { @@ -107,6 +123,15 @@ diff --git a/06 - Type Ahead/index-START.html b/06 - Type Ahead/index-START.html index 1436886918..68812e1386 100644 --- a/06 - Type Ahead/index-START.html +++ b/06 - Type Ahead/index-START.html @@ -17,6 +17,30 @@ diff --git a/07 - Array Cardio Day 2/index-START.html b/07 - Array Cardio Day 2/index-START.html index 206ec31aa0..eb09dde38c 100644 --- a/07 - Array Cardio Day 2/index-START.html +++ b/07 - Array Cardio Day 2/index-START.html @@ -26,16 +26,38 @@ // Some and Every Checks // Array.prototype.some() // is at least one person 19? + + const today = new Date(); + + console.log(people.some(p => { + return (today.getFullYear() - p.year) > 19 + })); + // Array.prototype.every() // is everyone 19? + console.log(people.every(p => { + return (today.getFullYear() - p.year) > 19 + })); + // Array.prototype.find() // Find is like filter, but instead returns just the one you are looking for // find the comment with the ID of 823423 + console.log(comments.find(c => c.id === 823423)); + // Array.prototype.findIndex() // Find the comment with this ID // delete the comment with the ID of 823423 + const foundIndex = comments.findIndex(c => c.id === 823423) + + const result = [ + ...comments.slice(0, foundIndex), + ...comments.slice(foundIndex + 1) + ]; + + console.log(result); + diff --git a/10 - Hold Shift and Check Checkboxes/index-START.html b/10 - Hold Shift and Check Checkboxes/index-START.html index eb7ed310bb..e6c803b0dd 100644 --- a/10 - Hold Shift and Check Checkboxes/index-START.html +++ b/10 - Hold Shift and Check Checkboxes/index-START.html @@ -104,6 +104,35 @@ diff --git a/11 - Custom Video Player/scripts.js b/11 - Custom Video Player/scripts.js index e69de29bb2..dcb4a8d5ba 100644 --- a/11 - Custom Video Player/scripts.js +++ b/11 - Custom Video Player/scripts.js @@ -0,0 +1,58 @@ +(function(){ + const player = document.querySelector('.player'); + const video = player.querySelector('.viewer'); + const progress = player.querySelector('.progress'); + const progressBar = player.querySelector('.progress__filled'); + const toggle = player.querySelector('.toggle'); + const skipButtons = player.querySelectorAll('[data-skip]'); + const ranges = player.querySelectorAll('.player__slider'); + + function togglePlay() { + const action = video.paused ? 'play' : 'pause'; + video[action](); + } + + function updateButton() { + const icon = this.paused ? '►' : '❚ ❚'; + toggle.textContent = icon; + } + + function handleProgress() { + const percent = (video.currentTime / video.duration) * 100; + progressBar.style.flexBasis = `${percent}%`; + } + + function handleRangeUpdate() { + video[this.name] = this.value; + } + + function handleSkip() { + video.currentTime += parseFloat(this.dataset.skip); + } + + function scrub(e) { + const scrubTime = (e.offsetX / progress.offsetWidth) * video.duration; + video.currentTime = scrubTime; + } + + toggle.addEventListener('click', togglePlay); + + video.addEventListener('click', togglePlay); + video.addEventListener('play', updateButton); + video.addEventListener('pause', updateButton); + video.addEventListener('timeupdate', handleProgress); + + ranges.forEach(range => range.addEventListener('change', handleRangeUpdate)); + ranges.forEach(range => range.addEventListener('mousemove', handleRangeUpdate)); + + skipButtons.forEach(skip => skip.addEventListener('click', handleSkip)); + + let mousedown = false; + progress.addEventListener('click', scrub); + progress.addEventListener('mousemove', (e) => mousedown && scrub(e)); + progress.addEventListener('mousedown', () => mousedown = true); + progress.addEventListener('mouseup', () => mousedown = false); + +}()); + + diff --git a/package.json b/package.json new file mode 100644 index 0000000000..72d8b66552 --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "js30", + "version": "1.0.0", + "description": "![](https://javascript30.com/images/JS3-social-share.png)", + "main": "index.js", + "scripts": { + "start": "http-server ./ -o -c-1" + }, + "repository": { + "type": "git", + "url": "git@github.com:stickmanblue/JavaScript30.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/stickmanblue/JavaScript30/issues" + }, + "homepage": "https://github.com/wesbos/JavaScript30#readme", + "devDependencies": { + "http-server": "^0.9.0" + } +} diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000000..0359569f95 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,41 @@ +module.exports = { + entry: './index.js', + output: { + path: './build', + filename: 'bundle.js', + publicPath: '' + }, + module: { + loaders: [ + { + test: /\.jsx?/, + loaders: [ + 'babel' + ], + include: './index.js', + query: { + presets: [ + 'es2015' + ] + } + }, + { + test: /\.scss$/, + loaders: [ + 'style', + 'css', + 'sass' + ] + }, + { + test: /\.(png|jpg)$/, + loaders: [ + 'url' + ], + query: { + limit: 8192 + } + } + ] + } +} \ No newline at end of file