Showing preview only (230K chars total). Download the full file or copy to clipboard to get everything.
Repository: wesbos/JavaScript30
Branch: master
Commit: a23f7ec27479
Files: 83
Total size: 209.4 KB
Directory structure:
gitextract_awdz6csi/
├── .gitignore
├── 01 - JavaScript Drum Kit/
│ ├── index-FINISHED.html
│ ├── index-START.html
│ └── style.css
├── 02 - JS and CSS Clock/
│ ├── index-FINISHED.html
│ └── index-START.html
├── 03 - CSS Variables/
│ ├── index-FINISHED.html
│ └── index-START.html
├── 04 - Array Cardio Day 1/
│ ├── index-FINISHED.html
│ └── index-START.html
├── 05 - Flex Panel Gallery/
│ ├── index-FINISHED.html
│ └── index-START.html
├── 06 - Type Ahead/
│ ├── index-FINISHED.html
│ ├── index-START.html
│ └── style.css
├── 07 - Array Cardio Day 2/
│ ├── index-FINISHED.html
│ └── index-START.html
├── 08 - Fun with HTML5 Canvas/
│ ├── index-FINISHED.html
│ └── index-START.html
├── 09 - Dev Tools Domination/
│ ├── index-FINISHED.html
│ └── index-START.html
├── 10 - Hold Shift and Check Checkboxes/
│ ├── index-FINISHED.html
│ └── index-START.html
├── 11 - Custom Video Player/
│ ├── index.html
│ ├── scripts-FINISHED.js
│ ├── scripts.js
│ └── style.css
├── 12 - Key Sequence Detection/
│ ├── cornify.js
│ ├── index-FINISHED.html
│ └── index-START.html
├── 13 - Slide in on Scroll/
│ ├── index-FINISHED.html
│ └── index-START.html
├── 14 - JavaScript References VS Copying/
│ ├── index-FINISHED.html
│ └── index-START.html
├── 15 - LocalStorage/
│ ├── index-FINISHED.html
│ ├── index-START.html
│ └── style.css
├── 16 - Mouse Move Shadow/
│ ├── index-FINISHED.html
│ └── index-START.html
├── 17 - Sort Without Articles/
│ ├── index-FINISHED.html
│ └── index-START.html
├── 18 - Adding Up Times with Reduce/
│ ├── index-FINISHED.html
│ └── index-START.html
├── 19 - Webcam Fun/
│ ├── index.html
│ ├── package.json
│ ├── scripts-FINISHED.js
│ ├── scripts.js
│ └── style.css
├── 20 - Speech Detection/
│ ├── index-FINISHED.html
│ ├── index-START.html
│ └── package.json
├── 21 - Geolocation/
│ ├── index-FINISHED.html
│ ├── index-START.html
│ └── package.json
├── 22 - Follow Along Link Highlighter/
│ ├── index-FINISHED.html
│ ├── index-START.html
│ └── style.css
├── 23 - Speech Synthesis/
│ ├── index-FINISHED.html
│ ├── index-START.html
│ └── style.css
├── 24 - Sticky Nav/
│ ├── index-FINISHED.html
│ ├── index-START.html
│ ├── style-FINISHED.css
│ └── style-START.css
├── 25 - Event Capture, Propagation, Bubbling and Once/
│ ├── index-FINISHED.html
│ └── index-START.html
├── 26 - Stripe Follow Along Nav/
│ ├── index-FINISHED.html
│ └── index-START.html
├── 27 - Click and Drag/
│ ├── index-FINISHED.html
│ ├── index-START.html
│ └── style.css
├── 28 - Video Speed Controller/
│ ├── index-FINISHED.html
│ ├── index-START.html
│ └── style.css
├── 29 - Countdown Timer/
│ ├── index.html
│ ├── scripts-FINISHED.js
│ ├── scripts-START.js
│ └── style.css
├── 30 - Whack A Mole/
│ ├── index-FINISHED.html
│ ├── index-START.html
│ └── style.css
├── PULL_REQUEST_TEMPLATE.md
└── readme.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
.DS_Store
node_modules/
*.log
haters/
.idea/
================================================
FILE: 01 - JavaScript Drum Kit/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS Drum Kit</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<div class="keys">
<div data-key="65" class="key">
<kbd>A</kbd>
<span class="sound">clap</span>
</div>
<div data-key="83" class="key">
<kbd>S</kbd>
<span class="sound">hihat</span>
</div>
<div data-key="68" class="key">
<kbd>D</kbd>
<span class="sound">kick</span>
</div>
<div data-key="70" class="key">
<kbd>F</kbd>
<span class="sound">openhat</span>
</div>
<div data-key="71" class="key">
<kbd>G</kbd>
<span class="sound">boom</span>
</div>
<div data-key="72" class="key">
<kbd>H</kbd>
<span class="sound">ride</span>
</div>
<div data-key="74" class="key">
<kbd>J</kbd>
<span class="sound">snare</span>
</div>
<div data-key="75" class="key">
<kbd>K</kbd>
<span class="sound">tom</span>
</div>
<div data-key="76" class="key">
<kbd>L</kbd>
<span class="sound">tink</span>
</div>
</div>
<audio data-key="65" src="sounds/clap.wav"></audio>
<audio data-key="83" src="sounds/hihat.wav"></audio>
<audio data-key="68" src="sounds/kick.wav"></audio>
<audio data-key="70" src="sounds/openhat.wav"></audio>
<audio data-key="71" src="sounds/boom.wav"></audio>
<audio data-key="72" src="sounds/ride.wav"></audio>
<audio data-key="74" src="sounds/snare.wav"></audio>
<audio data-key="75" src="sounds/tom.wav"></audio>
<audio data-key="76" src="sounds/tink.wav"></audio>
<script>
function removeTransition(e) {
if (e.propertyName !== 'transform') return;
e.target.classList.remove('playing');
}
function playSound(e) {
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
const key = document.querySelector(`div[data-key="${e.keyCode}"]`);
if (!audio) return;
key.classList.add('playing');
audio.currentTime = 0;
audio.play();
}
const keys = Array.from(document.querySelectorAll('.key'));
keys.forEach(key => key.addEventListener('transitionend', removeTransition));
window.addEventListener('keydown', playSound);
</script>
</body>
</html>
================================================
FILE: 01 - JavaScript Drum Kit/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS Drum Kit</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<div class="keys">
<div data-key="65" class="key">
<kbd>A</kbd>
<span class="sound">clap</span>
</div>
<div data-key="83" class="key">
<kbd>S</kbd>
<span class="sound">hihat</span>
</div>
<div data-key="68" class="key">
<kbd>D</kbd>
<span class="sound">kick</span>
</div>
<div data-key="70" class="key">
<kbd>F</kbd>
<span class="sound">openhat</span>
</div>
<div data-key="71" class="key">
<kbd>G</kbd>
<span class="sound">boom</span>
</div>
<div data-key="72" class="key">
<kbd>H</kbd>
<span class="sound">ride</span>
</div>
<div data-key="74" class="key">
<kbd>J</kbd>
<span class="sound">snare</span>
</div>
<div data-key="75" class="key">
<kbd>K</kbd>
<span class="sound">tom</span>
</div>
<div data-key="76" class="key">
<kbd>L</kbd>
<span class="sound">tink</span>
</div>
</div>
<audio data-key="65" src="sounds/clap.wav"></audio>
<audio data-key="83" src="sounds/hihat.wav"></audio>
<audio data-key="68" src="sounds/kick.wav"></audio>
<audio data-key="70" src="sounds/openhat.wav"></audio>
<audio data-key="71" src="sounds/boom.wav"></audio>
<audio data-key="72" src="sounds/ride.wav"></audio>
<audio data-key="74" src="sounds/snare.wav"></audio>
<audio data-key="75" src="sounds/tom.wav"></audio>
<audio data-key="76" src="sounds/tink.wav"></audio>
<script>
</script>
</body>
</html>
================================================
FILE: 01 - JavaScript Drum Kit/style.css
================================================
html {
font-size: 10px;
background: url('./background.jpg') bottom center;
background-size: cover;
}
body,html {
margin: 0;
padding: 0;
font-family: sans-serif;
}
.keys {
display: flex;
flex: 1;
min-height: 100vh;
align-items: center;
justify-content: center;
}
.key {
border: .4rem solid black;
border-radius: .5rem;
margin: 1rem;
font-size: 1.5rem;
padding: 1rem .5rem;
transition: all .07s ease;
width: 10rem;
text-align: center;
color: white;
background: rgba(0,0,0,0.4);
text-shadow: 0 0 .5rem black;
}
.playing {
transform: scale(1.1);
border-color: #ffc600;
box-shadow: 0 0 1rem #ffc600;
}
kbd {
display: block;
font-size: 4rem;
}
.sound {
font-size: 1.2rem;
text-transform: uppercase;
letter-spacing: .1rem;
color: #ffc600;
}
================================================
FILE: 02 - JS and CSS Clock/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS + CSS Clock</title>
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<div class="clock">
<div class="clock-face">
<div class="hand hour-hand"></div>
<div class="hand min-hand"></div>
<div class="hand second-hand"></div>
</div>
</div>
<style>
html {
background: #018DED url(https://unsplash.it/1500/1000?image=881&blur=5);
background-size: cover;
font-family: 'helvetica neue';
text-align: center;
font-size: 10px;
}
body {
margin: 0;
font-size: 2rem;
display: flex;
flex: 1;
min-height: 100vh;
align-items: center;
}
.clock {
width: 30rem;
height: 30rem;
border: 20px solid white;
border-radius: 50%;
margin: 50px auto;
position: relative;
padding: 2rem;
box-shadow:
0 0 0 4px rgba(0,0,0,0.1),
inset 0 0 0 3px #EFEFEF,
inset 0 0 10px black,
0 0 10px rgba(0,0,0,0.2);
}
.clock-face {
position: relative;
width: 100%;
height: 100%;
transform: translateY(-3px); /* account for the height of the clock hands */
}
.hand {
width: 50%;
height: 6px;
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);
}
</style>
<script>
const secondHand = document.querySelector('.second-hand');
const minsHand = document.querySelector('.min-hand');
const hourHand = document.querySelector('.hour-hand');
function setDate() {
const now = new Date();
const seconds = now.getSeconds();
const secondsDegrees = ((seconds / 60) * 360) + 90;
secondHand.style.transform = `rotate(${secondsDegrees}deg)`;
const mins = now.getMinutes();
const minsDegrees = ((mins / 60) * 360) + ((seconds/60)*6) + 90;
minsHand.style.transform = `rotate(${minsDegrees}deg)`;
const hour = now.getHours();
const hourDegrees = ((hour / 12) * 360) + ((mins/60)*30) + 90;
hourHand.style.transform = `rotate(${hourDegrees}deg)`;
}
setInterval(setDate, 1000);
setDate();
</script>
</body>
</html>
================================================
FILE: 02 - JS and CSS Clock/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS + CSS Clock</title>
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<div class="clock">
<div class="clock-face">
<div class="hand hour-hand"></div>
<div class="hand min-hand"></div>
<div class="hand second-hand"></div>
</div>
</div>
<style>
html {
background: #018DED url(https://unsplash.it/1500/1000?image=881&blur=5);
background-size: cover;
font-family: 'helvetica neue';
text-align: center;
font-size: 10px;
}
body {
margin: 0;
font-size: 2rem;
display: flex;
flex: 1;
min-height: 100vh;
align-items: center;
}
.clock {
width: 30rem;
height: 30rem;
border: 20px solid white;
border-radius: 50%;
margin: 50px auto;
position: relative;
padding: 2rem;
box-shadow:
0 0 0 4px rgba(0,0,0,0.1),
inset 0 0 0 3px #EFEFEF,
inset 0 0 10px black,
0 0 10px rgba(0,0,0,0.2);
}
.clock-face {
position: relative;
width: 100%;
height: 100%;
transform: translateY(-3px); /* account for the height of the clock hands */
}
.hand {
width: 50%;
height: 6px;
background: black;
position: absolute;
top: 50%;
}
</style>
<script>
</script>
</body>
</html>
================================================
FILE: 03 - CSS Variables/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Scoped CSS Variables and JS</title>
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<h2>Update CSS Variables with <span class='hl'>JS</span></h2>
<div class="controls">
<label for="spacing">Spacing:</label>
<input id="spacing" type="range" name="spacing" min="10" max="200" value="10" data-sizing="px">
<label for="blur">Blur:</label>
<input id="blur" type="range" name="blur" min="0" max="25" value="10" data-sizing="px">
<label for="base">Base Color</label>
<input id="base" type="color" name="base" value="#ffc600">
</div>
<img src="https://source.unsplash.com/7bwQXzbF6KE/800x500">
<style>
:root {
--base: #ffc600;
--spacing: 10px;
--blur: 10px;
}
img {
padding: var(--spacing);
background: var(--base);
filter: blur(var(--blur));
}
.hl {
color: var(--base);
}
/*
misc styles, nothing to do with CSS variables
*/
body {
text-align: center;
background: #193549;
color: white;
font-family: 'helvetica neue', sans-serif;
font-weight: 100;
font-size: 50px;
}
.controls {
margin-bottom: 50px;
}
input {
width: 100px;
}
</style>
<script>
const inputs = document.querySelectorAll('.controls input');
function handleUpdate() {
const suffix = this.dataset.sizing || '';
document.documentElement.style.setProperty(`--${this.name}`, this.value + suffix);
}
inputs.forEach(input => input.addEventListener('change', handleUpdate));
inputs.forEach(input => input.addEventListener('mousemove', handleUpdate));
</script>
</body>
</html>
================================================
FILE: 03 - CSS Variables/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Scoped CSS Variables and JS</title>
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<h2>Update CSS Variables with <span class='hl'>JS</span></h2>
<div class="controls">
<label for="spacing">Spacing:</label>
<input id="spacing" type="range" name="spacing" min="10" max="200" value="10" data-sizing="px">
<label for="blur">Blur:</label>
<input id="blur" type="range" name="blur" min="0" max="25" value="10" data-sizing="px">
<label for="base">Base Color</label>
<input id="base" type="color" name="base" value="#ffc600">
</div>
<img src="https://source.unsplash.com/7bwQXzbF6KE/800x500">
<style>
/*
misc styles, nothing to do with CSS variables
*/
body {
text-align: center;
background: #193549;
color: white;
font-family: 'helvetica neue', sans-serif;
font-weight: 100;
font-size: 50px;
}
.controls {
margin-bottom: 50px;
}
input {
width: 100px;
}
</style>
<script>
</script>
</body>
</html>
================================================
FILE: 04 - Array Cardio Day 1/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Array Cardio 💪</title>
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<p><em>Psst: have a look at the JavaScript Console</em> 💁</p>
<script>
// Get your shorts on - this is an array workout!
// ## Array Cardio Day 1
// Some data we can work with
const inventors = [
{ first: 'Albert', last: 'Einstein', year: 1879, passed: 1955 },
{ first: 'Isaac', last: 'Newton', year: 1643, passed: 1727 },
{ first: 'Galileo', last: 'Galilei', year: 1564, passed: 1642 },
{ first: 'Marie', last: 'Curie', year: 1867, passed: 1934 },
{ first: 'Johannes', last: 'Kepler', year: 1571, passed: 1630 },
{ first: 'Nicolaus', last: 'Copernicus', year: 1473, passed: 1543 },
{ first: 'Max', last: 'Planck', year: 1858, passed: 1947 },
{ first: 'Katherine', last: 'Blodgett', year: 1898, passed: 1979 },
{ first: 'Ada', last: 'Lovelace', year: 1815, passed: 1852 },
{ first: 'Sarah E.', last: 'Goode', year: 1855, passed: 1905 },
{ first: 'Lise', last: 'Meitner', year: 1878, passed: 1968 },
{ first: 'Hanna', last: 'Hammarström', year: 1829, passed: 1909 }
];
const people = [
'Bernhard, Sandra', 'Bethea, Erin', 'Becker, Carl', 'Bentsen, Lloyd', 'Beckett, Samuel', 'Blake, William', 'Berger, Ric', 'Beddoes, Mick', 'Beethoven, Ludwig',
'Belloc, Hilaire', 'Begin, Menachem', 'Bellow, Saul', 'Benchley, Robert', 'Blair, Robert', 'Benenson, Peter', 'Benjamin, Walter', 'Berlin, Irving',
'Benn, Tony', 'Benson, Leana', 'Bent, Silas', 'Berle, Milton', 'Berry, Halle', 'Biko, Steve', 'Beck, Glenn', 'Bergman, Ingmar', 'Black, Elk', 'Berio, Luciano',
'Berne, Eric', 'Berra, Yogi', 'Berry, Wendell', 'Bevan, Aneurin', 'Ben-Gurion, David', 'Bevel, Ken', 'Biden, Joseph', 'Bennington, Chester', 'Bierce, Ambrose',
'Billings, Josh', 'Birrell, Augustine', 'Blair, Tony', 'Beecher, Henry', 'Biondo, Frank'
];
// Array.prototype.filter()
// 1. Filter the list of inventors for those who were born in the 1500's
const fifteen = inventors.filter(inventor => (inventor.year >= 1500 && inventor.year < 1600));
console.table(fifteen);
// Array.prototype.map()
// 2. Give us an array of the inventor first and last names
const fullNames = inventors.map(inventor => `${inventor.first} ${inventor.last}`);
console.log(fullNames);
// Array.prototype.sort()
// 3. Sort the inventors by birthdate, oldest to youngest
// const ordered = inventors.sort(function(a, b) {
// if(a.year > b.year) {
// return 1;
// } else {
// return -1;
// }
// });
const ordered = inventors.sort((a, b) => a.year > b.year ? 1 : -1);
console.table(ordered);
// Array.prototype.reduce()
// 4. How many years did all the inventors live?
const totalYears = inventors.reduce((total, inventor) => {
return total + (inventor.passed - inventor.year);
}, 0);
console.log(totalYears);
// 5. Sort the inventors by years lived
const oldest = inventors.sort(function(a, b) {
const lastInventor = a.passed - a.year;
const nextInventor = b.passed - b.year;
return lastInventor > nextInventor ? -1 : 1;
});
console.table(oldest);
// 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 category = document.querySelector('.mw-category');
// const links = Array.from(category.querySelectorAll('a'));
// const de = links
// .map(link => link.textContent)
// .filter(streetName => streetName.includes('de'));
// 7. sort Exercise
// Sort the people alphabetically by last name
const alpha = people.sort((lastOne, nextOne) => {
const [aLast, aFirst] = lastOne.split(', ');
const [bLast, bFirst] = nextOne.split(', ');
return aLast > bLast ? 1 : -1;
});
console.log(alpha);
// 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', 'pogostick'];
const transportation = data.reduce(function(obj, item) {
if (!obj[item]) {
obj[item] = 0;
}
obj[item]++;
return obj;
}, {});
console.log(transportation);
</script>
</body>
</html>
================================================
FILE: 04 - Array Cardio Day 1/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Array Cardio 💪</title>
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<p><em>Psst: have a look at the JavaScript Console</em> 💁</p>
<script>
// Get your shorts on - this is an array workout!
// ## Array Cardio Day 1
// Some data we can work with
const inventors = [
{ first: 'Albert', last: 'Einstein', year: 1879, passed: 1955 },
{ first: 'Isaac', last: 'Newton', year: 1643, passed: 1727 },
{ first: 'Galileo', last: 'Galilei', year: 1564, passed: 1642 },
{ first: 'Marie', last: 'Curie', year: 1867, passed: 1934 },
{ first: 'Johannes', last: 'Kepler', year: 1571, passed: 1630 },
{ first: 'Nicolaus', last: 'Copernicus', year: 1473, passed: 1543 },
{ first: 'Max', last: 'Planck', year: 1858, passed: 1947 },
{ first: 'Katherine', last: 'Blodgett', year: 1898, passed: 1979 },
{ first: 'Ada', last: 'Lovelace', year: 1815, passed: 1852 },
{ first: 'Sarah E.', last: 'Goode', year: 1855, passed: 1905 },
{ first: 'Lise', last: 'Meitner', year: 1878, passed: 1968 },
{ first: 'Hanna', last: 'Hammarström', year: 1829, passed: 1909 }
];
const people = [
'Bernhard, Sandra', 'Bethea, Erin', 'Becker, Carl', 'Bentsen, Lloyd', 'Beckett, Samuel', 'Blake, William', 'Berger, Ric', 'Beddoes, Mick', 'Beethoven, Ludwig',
'Belloc, Hilaire', 'Begin, Menachem', 'Bellow, Saul', 'Benchley, Robert', 'Blair, Robert', 'Benenson, Peter', 'Benjamin, Walter', 'Berlin, Irving',
'Benn, Tony', 'Benson, Leana', 'Bent, Silas', 'Berle, Milton', 'Berry, Halle', 'Biko, Steve', 'Beck, Glenn', 'Bergman, Ingmar', 'Black, Elk', 'Berio, Luciano',
'Berne, Eric', 'Berra, Yogi', 'Berry, Wendell', 'Bevan, Aneurin', 'Ben-Gurion, David', 'Bevel, Ken', 'Biden, Joseph', 'Bennington, Chester', 'Bierce, Ambrose',
'Billings, Josh', 'Birrell, Augustine', 'Blair, Tony', 'Beecher, Henry', 'Biondo, Frank'
];
// Array.prototype.filter()
// 1. Filter the list of inventors for those who were born in the 1500's
// Array.prototype.map()
// 2. Give us an array of the inventors first and last names
// Array.prototype.sort()
// 3. Sort the inventors by birthdate, oldest to youngest
// Array.prototype.reduce()
// 4. How many years did all the inventors live all together?
// 5. Sort the inventors by years lived
// 6. create a list of Boulevards in Paris that contain 'de' anywhere in the name
// https://en.wikipedia.org/wiki/Category:Boulevards_in_Paris
// 7. sort Exercise
// Sort the people alphabetically by last name
// 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' ];
</script>
</body>
</html>
================================================
FILE: 05 - Flex Panel Gallery/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flex Panels 💪</title>
<link href='https://fonts.googleapis.com/css?family=Amatic+SC' rel='stylesheet' type='text/css'>
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<style>
html {
box-sizing: border-box;
background: #ffc600;
font-family: 'helvetica neue';
font-size: 20px;
font-weight: 200;
}
body {
margin: 0;
}
*, *:before, *:after {
box-sizing: inherit;
}
.panels {
min-height: 100vh;
overflow: hidden;
display: flex;
}
.panel {
background: #6B0F9C;
box-shadow: inset 0 0 0 5px rgba(255,255,255,0.1);
color: white;
text-align: center;
align-items: center;
/* Safari transitionend event.propertyName === flex */
/* Chrome + FF transitionend event.propertyName === flex-grow */
transition:
font-size 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
flex 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
background 0.2s;
font-size: 20px;
background-size: cover;
background-position: center;
flex: 1;
justify-content: center;
display: flex;
flex-direction: column;
}
.panel1 { background-image:url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500); }
.panel2 { background-image:url(https://source.unsplash.com/rFKUFzjPYiQ/1500x1500); }
.panel3 { background-image:url(https://images.unsplash.com/photo-1465188162913-8fb5709d6d57?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&w=1500&h=1500&fit=crop&s=967e8a713a4e395260793fc8c802901d); }
.panel4 { background-image:url(https://source.unsplash.com/ITjiVXcwVng/1500x1500); }
.panel5 { background-image:url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500); }
/* Flex Items */
.panel > * {
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;
text-shadow: 0 0 4px rgba(0, 0, 0, 0.72), 0 0 14px rgba(0, 0, 0, 0.45);
font-size: 2em;
}
.panel p:nth-child(2) {
font-size: 4em;
}
.panel.open {
flex: 5;
font-size: 40px;
}
@media only screen and (max-width: 600px) {
.panel p {
font-size: 1em;
}
}
</style>
<div class="panels">
<div class="panel panel1">
<p>Hey</p>
<p>Let's</p>
<p>Dance</p>
</div>
<div class="panel panel2">
<p>Give</p>
<p>Take</p>
<p>Receive</p>
</div>
<div class="panel panel3">
<p>Experience</p>
<p>It</p>
<p>Today</p>
</div>
<div class="panel panel4">
<p>Give</p>
<p>All</p>
<p>You can</p>
</div>
<div class="panel panel5">
<p>Life</p>
<p>In</p>
<p>Motion</p>
</div>
</div>
<script>
const panels = document.querySelectorAll('.panel');
function toggleOpen() {
console.log('Hello');
this.classList.toggle('open');
}
function toggleActive(e) {
console.log(e.propertyName);
if (e.propertyName.includes('flex')) {
this.classList.toggle('open-active');
}
}
panels.forEach(panel => panel.addEventListener('click', toggleOpen));
panels.forEach(panel => panel.addEventListener('transitionend', toggleActive));
</script>
</body>
</html>
================================================
FILE: 05 - Flex Panel Gallery/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flex Panels 💪</title>
<link href='https://fonts.googleapis.com/css?family=Amatic+SC' rel='stylesheet' type='text/css'>
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<style>
html {
box-sizing: border-box;
background: #ffc600;
font-family: 'helvetica neue';
font-size: 20px;
font-weight: 200;
}
body {
margin: 0;
}
*, *:before, *:after {
box-sizing: inherit;
}
.panels {
min-height: 100vh;
overflow: hidden;
}
.panel {
background: #6B0F9C;
box-shadow: inset 0 0 0 5px rgba(255,255,255,0.1);
color: white;
text-align: center;
align-items: center;
/* Safari transitionend event.propertyName === flex */
/* Chrome + FF transitionend event.propertyName === flex-grow */
transition:
font-size 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
flex 0.7s cubic-bezier(0.61,-0.19, 0.7,-0.11),
background 0.2s;
font-size: 20px;
background-size: cover;
background-position: center;
}
.panel1 { background-image:url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500); }
.panel2 { background-image:url(https://source.unsplash.com/rFKUFzjPYiQ/1500x1500); }
.panel3 { background-image:url(https://images.unsplash.com/photo-1465188162913-8fb5709d6d57?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&w=1500&h=1500&fit=crop&s=967e8a713a4e395260793fc8c802901d); }
.panel4 { background-image:url(https://source.unsplash.com/ITjiVXcwVng/1500x1500); }
.panel5 { background-image:url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500); }
/* Flex Children */
.panel > * {
margin: 0;
width: 100%;
transition: transform 0.5s;
}
.panel p {
text-transform: uppercase;
font-family: 'Amatic SC', cursive;
text-shadow: 0 0 4px rgba(0, 0, 0, 0.72), 0 0 14px rgba(0, 0, 0, 0.45);
font-size: 2em;
}
.panel p:nth-child(2) {
font-size: 4em;
}
.panel.open {
font-size: 40px;
}
</style>
<div class="panels">
<div class="panel panel1">
<p>Hey</p>
<p>Let's</p>
<p>Dance</p>
</div>
<div class="panel panel2">
<p>Give</p>
<p>Take</p>
<p>Receive</p>
</div>
<div class="panel panel3">
<p>Experience</p>
<p>It</p>
<p>Today</p>
</div>
<div class="panel panel4">
<p>Give</p>
<p>All</p>
<p>You can</p>
</div>
<div class="panel panel5">
<p>Life</p>
<p>In</p>
<p>Motion</p>
</div>
</div>
<script>
</script>
</body>
</html>
================================================
FILE: 06 - Type Ahead/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Type Ahead 👀</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<form class="search-form">
<input type="text" class="search" placeholder="City or State">
<ul class="suggestions">
<li>Filter for a city</li>
<li>or a state</li>
</ul>
</form>
<script>
const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
const cities = [];
fetch(endpoint)
.then(blob => blob.json())
.then(data => cities.push(...data));
function findMatches(wordToMatch, cities) {
return cities.filter(place => {
// here we need to figure out if the city or state matches what was searched
const regex = new RegExp(wordToMatch, 'gi');
return place.city.match(regex) || place.state.match(regex)
});
}
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
function displayMatches() {
const matchArray = findMatches(this.value, cities);
const html = matchArray.map(place => {
const regex = new RegExp(this.value, 'gi');
const cityName = place.city.replace(regex, `<span class="hl">${this.value}</span>`);
const stateName = place.state.replace(regex, `<span class="hl">${this.value}</span>`);
return `
<li>
<span class="name">${cityName}, ${stateName}</span>
<span class="population">${numberWithCommas(place.population)}</span>
</li>
`;
}).join('');
suggestions.innerHTML = html;
}
const searchInput = document.querySelector('.search');
const suggestions = document.querySelector('.suggestions');
searchInput.addEventListener('change', displayMatches);
searchInput.addEventListener('keyup', displayMatches);
</script>
</body>
</html>
================================================
FILE: 06 - Type Ahead/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Type Ahead 👀</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<form class="search-form">
<input type="text" class="search" placeholder="City or State">
<ul class="suggestions">
<li>Filter for a city</li>
<li>or a state</li>
</ul>
</form>
<script>
const endpoint = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
</script>
</body>
</html>
================================================
FILE: 06 - Type Ahead/style.css
================================================
html {
box-sizing: border-box;
background: #ffc600;
font-family: 'helvetica neue';
font-size: 20px;
font-weight: 200;
}
*, *:before, *:after {
box-sizing: inherit;
}
input {
width: 100%;
padding: 20px;
}
.search-form {
max-width: 400px;
margin: 50px auto;
}
input.search {
margin: 0;
text-align: center;
outline: 0;
border: 10px solid #F7F7F7;
width: 120%;
left: -10%;
position: relative;
top: 10px;
z-index: 2;
border-radius: 5px;
font-size: 40px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.12), inset 0 0 2px rgba(0, 0, 0, 0.19);
}
.suggestions {
margin: 0;
padding: 0;
position: relative;
/*perspective: 20px;*/
}
.suggestions li {
background: white;
list-style: none;
border-bottom: 1px solid #D8D8D8;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.14);
margin: 0;
padding: 20px;
transition: background 0.2s;
display: flex;
justify-content: space-between;
text-transform: capitalize;
}
.suggestions li:nth-child(even) {
transform: perspective(100px) rotateX(3deg) translateY(2px) scale(1.001);
background: linear-gradient(to bottom, #ffffff 0%,#EFEFEF 100%);
}
.suggestions li:nth-child(odd) {
transform: perspective(100px) rotateX(-3deg) translateY(3px);
background: linear-gradient(to top, #ffffff 0%,#EFEFEF 100%);
}
span.population {
font-size: 15px;
}
.hl {
background: #ffc600;
}
================================================
FILE: 07 - Array Cardio Day 2/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Array Cardio 💪💪</title>
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<p><em>Psst: have a look at the JavaScript Console</em> 💁</p>
<script>
// ## Array Cardio Day 2
const people = [
{ name: 'Wes', year: 1988 },
{ name: 'Kait', year: 1986 },
{ name: 'Irv', year: 1970 },
{ name: 'Lux', year: 2015 }
];
const comments = [
{ text: 'Love this!', id: 523423 },
{ text: 'Super good', id: 823423 },
{ text: 'You are the best', id: 2039842 },
{ text: 'Ramen is my fav food ever', id: 123523 },
{ text: 'Nice Nice Nice!', id: 542328 }
];
// Some and Every Checks
// Array.prototype.some() // is at least one person 19?
// const isAdult = people.some(function(person) {
// const currentYear = (new Date()).getFullYear();
// if(currentYear - person.year >= 19) {
// return true;
// }
// });
const isAdult = people.some(person => ((new Date()).getFullYear()) - person.year >= 19);
console.log({isAdult});
// Array.prototype.every() // is everyone 19?
const allAdults = people.every(person => ((new Date()).getFullYear()) - person.year >= 19);
console.log({allAdults});
// 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
const comment = comments.find(comment => comment.id === 823423);
console.log(comment);
// Array.prototype.findIndex()
// Find the comment with this ID
// delete the comment with the ID of 823423
const index = comments.findIndex(comment => comment.id === 823423);
console.log(index);
// comments.splice(index, 1);
const newComments = [
...comments.slice(0, index),
...comments.slice(index + 1)
];
</script>
</body>
</html>
================================================
FILE: 07 - Array Cardio Day 2/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Array Cardio 💪💪</title>
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<p><em>Psst: have a look at the JavaScript Console</em> 💁</p>
<script>
// ## Array Cardio Day 2
const people = [
{ name: 'Wes', year: 1988 },
{ name: 'Kait', year: 1986 },
{ name: 'Irv', year: 1970 },
{ name: 'Lux', year: 2015 }
];
const comments = [
{ text: 'Love this!', id: 523423 },
{ text: 'Super good', id: 823423 },
{ text: 'You are the best', id: 2039842 },
{ text: 'Ramen is my fav food ever', id: 123523 },
{ text: 'Nice Nice Nice!', id: 542328 }
];
// Some and Every Checks
// Array.prototype.some() // is at least one person 19 or older?
// Array.prototype.every() // is everyone 19 or older?
// 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
// Array.prototype.findIndex()
// Find the comment with this ID
// delete the comment with the ID of 823423
</script>
</body>
</html>
================================================
FILE: 08 - Fun with HTML5 Canvas/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HTML5 Canvas</title>
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<canvas id="draw" width="800" height="800"></canvas>
<script>
const canvas = document.querySelector('#draw');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
ctx.strokeStyle = '#BADA55';
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.lineWidth = 100;
// ctx.globalCompositeOperation = 'multiply';
let isDrawing = false;
let lastX = 0;
let lastY = 0;
let hue = 0;
let direction = true;
function draw(e) {
if (!isDrawing) return; // stop the fn from running when they are not moused down
console.log(e);
ctx.strokeStyle = `hsl(${hue}, 100%, 50%)`;
ctx.beginPath();
// start from
ctx.moveTo(lastX, lastY);
// go to
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
[lastX, lastY] = [e.offsetX, e.offsetY];
hue++;
if (hue >= 360) {
hue = 0;
}
if (ctx.lineWidth >= 100 || ctx.lineWidth <= 1) {
direction = !direction;
}
if(direction) {
ctx.lineWidth++;
} else {
ctx.lineWidth--;
}
}
canvas.addEventListener('mousedown', (e) => {
isDrawing = true;
[lastX, lastY] = [e.offsetX, e.offsetY];
});
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', () => isDrawing = false);
canvas.addEventListener('mouseout', () => isDrawing = false);
</script>
<style>
html, body {
margin: 0;
}
</style>
</body>
</html>
================================================
FILE: 08 - Fun with HTML5 Canvas/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HTML5 Canvas</title>
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<canvas id="draw" width="800" height="800"></canvas>
<script>
</script>
<style>
html, body {
margin: 0;
}
</style>
</body>
</html>
================================================
FILE: 09 - Dev Tools Domination/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Console Tricks!</title>
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<p onClick="makeGreen()">×BREAK×DOWN×</p>
<script>
const dogs = [{ name: 'Snickers', age: 2 }, { name: 'hugo', age: 8 }];
function makeGreen() {
const p = document.querySelector('p');
p.style.color = '#BADA55';
p.style.fontSize = '50px';
}
// Regular
console.log('hello');
// Interpolated
console.log('Hello I am a %s string!', '💩');
// Styled
// console.log('%c I am some great text', 'font-size:50px; background:red; text-shadow: 10px 10px 0 blue')
// warning!
console.warn('OH NOOO');
// Error :|
console.error('Shit!');
// Info
console.info('Crocodiles eat 3-4 people per year');
// Testing
const p = document.querySelector('p');
console.assert(p.classList.contains('ouch'), 'That is wrong!');
// clearing
console.clear();
// Viewing DOM Elements
console.log(p);
console.dir(p);
console.clear();
// Grouping together
dogs.forEach(dog => {
console.groupCollapsed(`${dog.name}`);
console.log(`This is ${dog.name}`);
console.log(`${dog.name} is ${dog.age} years old`);
console.log(`${dog.name} is ${dog.age * 7} dog years old`);
console.groupEnd(`${dog.name}`);
});
// counting
console.count('Wes');
console.count('Wes');
console.count('Steve');
console.count('Steve');
console.count('Wes');
console.count('Steve');
console.count('Wes');
console.count('Steve');
console.count('Steve');
console.count('Steve');
console.count('Steve');
console.count('Steve');
// timing
console.time('fetching data');
fetch('https://api.github.com/users/wesbos')
.then(data => data.json())
.then(data => {
console.timeEnd('fetching data');
console.log(data);
});
console.table(dogs);
</script>
</body>
</html>
================================================
FILE: 09 - Dev Tools Domination/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Console Tricks!</title>
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<p onClick="makeGreen()">×BREAK×DOWN×</p>
<script>
const dogs = [{ name: 'Snickers', age: 2 }, { name: 'hugo', age: 8 }];
function makeGreen() {
const p = document.querySelector('p');
p.style.color = '#BADA55';
p.style.fontSize = '50px';
}
// Regular
// Interpolated
// Styled
// warning!
// Error :|
// Info
// Testing
// clearing
// Viewing DOM Elements
// Grouping together
// counting
// timing
</script>
</body>
</html>
================================================
FILE: 10 - Hold Shift and Check Checkboxes/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hold Shift to Check Multiple Checkboxes</title>
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<style>
html {
font-family: sans-serif;
background: #ffc600;
}
.inbox {
max-width: 400px;
margin: 50px auto;
background: white;
border-radius: 5px;
box-shadow: 10px 10px 0 rgba(0,0,0,0.1);
}
.item {
display: flex;
align-items: center;
border-bottom: 1px solid #F1F1F1;
}
.item:last-child {
border-bottom: 0;
}
input:checked + p {
background: #F9F9F9;
text-decoration: line-through;
}
input[type="checkbox"] {
margin: 20px;
}
p {
margin: 0;
padding: 20px;
transition: background 0.2s;
flex: 1;
font-family: 'helvetica neue';
font-size: 20px;
font-weight: 200;
border-left: 1px solid #D1E2FF;
}
</style>
<!--
The following is a common layout you would see in an email client.
When a user clicks a checkbox, holds Shift, and then clicks another checkbox a few rows down, all the checkboxes in-between those two checkboxes should be checked.
-->
<div class="inbox">
<div class="item">
<input type="checkbox">
<p>This is an inbox layout.</p>
</div>
<div class="item">
<input type="checkbox">
<p>Check one item</p>
</div>
<div class="item">
<input type="checkbox">
<p>Hold down your Shift key</p>
</div>
<div class="item">
<input type="checkbox">
<p>Check a lower item</p>
</div>
<div class="item">
<input type="checkbox">
<p>Everything in between should also be set to checked</p>
</div>
<div class="item">
<input type="checkbox">
<p>Try do it without any libraries</p>
</div>
<div class="item">
<input type="checkbox">
<p>Just regular JavaScript</p>
</div>
<div class="item">
<input type="checkbox">
<p>Good Luck!</p>
</div>
<div class="item">
<input type="checkbox">
<p>Don't forget to tweet your result!</p>
</div>
</div>
<script>
const checkboxes = document.querySelectorAll('.inbox input[type="checkbox"]');
let lastChecked;
function handleCheck(e) {
// Check if they had the shift key down
// AND check that they are checking it
let inBetween = false;
if (e.shiftKey && this.checked) {
// go ahead and do what we please
// loop over every single checkbox
checkboxes.forEach(checkbox => {
console.log(checkbox);
if (checkbox === this || checkbox === lastChecked) {
inBetween = !inBetween;
console.log('Starting to check them in between!');
}
if (inBetween) {
checkbox.checked = true;
}
});
}
lastChecked = this;
}
checkboxes.forEach(checkbox => checkbox.addEventListener('click', handleCheck));
</script>
</body>
</html>
================================================
FILE: 10 - Hold Shift and Check Checkboxes/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hold Shift to Check Multiple Checkboxes</title>
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<style>
html {
font-family: sans-serif;
background: #ffc600;
}
.inbox {
max-width: 400px;
margin: 50px auto;
background: white;
border-radius: 5px;
box-shadow: 10px 10px 0 rgba(0,0,0,0.1);
}
.item {
display: flex;
align-items: center;
border-bottom: 1px solid #F1F1F1;
}
.item:last-child {
border-bottom: 0;
}
input:checked + p {
background: #F9F9F9;
text-decoration: line-through;
}
input[type="checkbox"] {
margin: 20px;
}
p {
margin: 0;
padding: 20px;
transition: background 0.2s;
flex: 1;
font-family:'helvetica neue';
font-size: 20px;
font-weight: 200;
border-left: 1px solid #D1E2FF;
}
</style>
<!--
The following is a common layout you would see in an email client.
When a user clicks a checkbox, holds Shift, and then clicks another checkbox a few rows down, all the checkboxes inbetween those two checkboxes should be checked.
-->
<div class="inbox">
<div class="item">
<input type="checkbox">
<p>This is an inbox layout.</p>
</div>
<div class="item">
<input type="checkbox">
<p>Check one item</p>
</div>
<div class="item">
<input type="checkbox">
<p>Hold down your Shift key</p>
</div>
<div class="item">
<input type="checkbox">
<p>Check a lower item</p>
</div>
<div class="item">
<input type="checkbox">
<p>Everything in between should also be set to checked</p>
</div>
<div class="item">
<input type="checkbox">
<p>Try to do it without any libraries</p>
</div>
<div class="item">
<input type="checkbox">
<p>Just regular JavaScript</p>
</div>
<div class="item">
<input type="checkbox">
<p>Good Luck!</p>
</div>
<div class="item">
<input type="checkbox">
<p>Don't forget to tweet your result!</p>
</div>
</div>
<script>
</script>
</body>
</html>
================================================
FILE: 11 - Custom Video Player/index.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HTML Video Player</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<div class="player">
<video class="player__video viewer" src="652333414.mp4"></video>
<div class="player__controls">
<div class="progress">
<div class="progress__filled"></div>
</div>
<button class="player__button toggle" title="Toggle Play">►</button>
<input type="range" name="volume" class="player__slider" min="0" max="1" step="0.05" value="1">
<input type="range" name="playbackRate" class="player__slider" min="0.5" max="2" step="0.1" value="1">
<button data-skip="-10" class="player__button">« 10s</button>
<button data-skip="25" class="player__button">25s »</button>
</div>
</div>
<script src="scripts.js"></script>
</body>
</html>
================================================
FILE: 11 - Custom Video Player/scripts-FINISHED.js
================================================
/* Get Our Elements */
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');
/* Build out functions */
function togglePlay() {
const method = video.paused ? 'play' : 'pause';
video[method]();
}
function updateButton() {
const icon = this.paused ? '►' : '❚ ❚';
console.log(icon);
toggle.textContent = icon;
}
function skip() {
video.currentTime += parseFloat(this.dataset.skip);
}
function handleRangeUpdate() {
video[this.name] = this.value;
}
function handleProgress() {
const percent = (video.currentTime / video.duration) * 100;
progressBar.style.flexBasis = `${percent}%`;
}
function scrub(e) {
const scrubTime = (e.offsetX / progress.offsetWidth) * video.duration;
video.currentTime = scrubTime;
}
/* Hook up the event listeners */
video.addEventListener('click', togglePlay);
video.addEventListener('play', updateButton);
video.addEventListener('pause', updateButton);
video.addEventListener('timeupdate', handleProgress);
toggle.addEventListener('click', togglePlay);
skipButtons.forEach(button => button.addEventListener('click', skip));
ranges.forEach(range => range.addEventListener('change', handleRangeUpdate));
ranges.forEach(range => range.addEventListener('mousemove', handleRangeUpdate));
let mousedown = false;
progress.addEventListener('click', scrub);
progress.addEventListener('mousemove', (e) => mousedown && scrub(e));
progress.addEventListener('mousedown', () => mousedown = true);
progress.addEventListener('mouseup', () => mousedown = false);
================================================
FILE: 11 - Custom Video Player/scripts.js
================================================
================================================
FILE: 11 - Custom Video Player/style.css
================================================
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
margin: 0;
padding: 0;
display: flex;
background: #7A419B;
min-height: 100vh;
background: linear-gradient(135deg, #7c1599 0%,#921099 48%,#7e4ae8 100%);
background-size: cover;
align-items: center;
justify-content: center;
}
.player {
max-width: 750px;
border: 5px solid rgba(0,0,0,0.2);
box-shadow: 0 0 20px rgba(0,0,0,0.2);
position: relative;
font-size: 0;
overflow: hidden;
}
/* This css is only applied when fullscreen is active. */
.player:fullscreen {
max-width: none;
width: 100%;
}
.player:-webkit-full-screen {
max-width: none;
width: 100%;
}
.player__video {
width: 100%;
}
.player__button {
background: none;
border: 0;
line-height: 1;
color: white;
text-align: center;
outline: 0;
padding: 0;
cursor: pointer;
max-width: 50px;
}
.player__button:focus {
border-color: #ffc600;
}
.player__slider {
width: 10px;
height: 30px;
}
.player__controls {
display: flex;
position: absolute;
bottom: 0;
width: 100%;
transform: translateY(100%) translateY(-5px);
transition: all .3s;
flex-wrap: wrap;
background: rgba(0,0,0,0.1);
}
.player:hover .player__controls {
transform: translateY(0);
}
.player:hover .progress {
height: 15px;
}
.player__controls > * {
flex: 1;
}
.progress {
flex: 10;
position: relative;
display: flex;
flex-basis: 100%;
height: 5px;
transition: height 0.3s;
background: rgba(0,0,0,0.5);
cursor: ew-resize;
}
.progress__filled {
width: 50%;
background: #ffc600;
flex: 0;
flex-basis: 50%;
}
/* unholy css to style input type="range" */
input[type=range] {
-webkit-appearance: none;
background: transparent;
width: 100%;
margin: 0 5px;
}
input[type=range]:focus {
outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 8.4px;
cursor: pointer;
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0), 0 0 1px rgba(13, 13, 13, 0);
background: rgba(255,255,255,0.8);
border-radius: 1.3px;
border: 0.2px solid rgba(1, 1, 1, 0);
}
input[type=range]::-webkit-slider-thumb {
height: 15px;
width: 15px;
border-radius: 50px;
background: #ffc600;
cursor: pointer;
-webkit-appearance: none;
margin-top: -3.5px;
box-shadow:0 0 2px rgba(0,0,0,0.2);
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #bada55;
}
input[type=range]::-moz-range-track {
width: 100%;
height: 8.4px;
cursor: pointer;
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0), 0 0 1px rgba(13, 13, 13, 0);
background: #ffffff;
border-radius: 1.3px;
border: 0.2px solid rgba(1, 1, 1, 0);
}
input[type=range]::-moz-range-thumb {
box-shadow: 0 0 0 rgba(0, 0, 0, 0), 0 0 0 rgba(13, 13, 13, 0);
height: 15px;
width: 15px;
border-radius: 50px;
background: #ffc600;
cursor: pointer;
}
================================================
FILE: 12 - Key Sequence Detection/cornify.js
================================================
/*
_______ ,-----. .-------. ,---. .--..-./`) ________ ____ __
/ __ \ .' .-, '. | _ _ \ | \ | |\ .-.')| | \ \ / /
| ,_/ \__) / ,-.| \ _ \ | ( ' ) | | , \ | |/ `-' \| .----' \ _. / '
,-./ ) ; \ '_ / | :|(_ o _) / | |\_ \| | `-'`"`| _|____ _( )_ .'
\ '_ '`) | _`,/ \ _/ || (_,_).' __ | _( )_\ | .---. |_( )_ | ___(_ o _)'
> (_) ) __: ( '\_/ \ ;| |\ \ | || (_ o _) | | | (_ o._)__|| |(_,_)'
( . .-'_/ )\ `"/ \ ) / | | \ `' /| (_,_)\ | | | |(_,_) | `-' /
`-'`-' / '. \_/``".' | | \ / | | | | | | | | \ /
`._____.' '-----' ''-' `'-' '--' '--' '---' '---' `-..-'
This script has been modified by @wesbos because
https://twitter.com/wesbos/status/1657012836403388416
*/
var cornify_count = 0;
var cornify_add = function (options) {
// Track how often we cornified.
cornify_count += 1;
// Prepare our lovely variables.
var cornify_url = "https://www.cornify.com/";
var numType = "px";
var heightRandom = Math.random() * 0.75;
var windowHeight = 768;
var windowWidth = 1024;
var height = 0;
var width = 0;
var de = document.documentElement;
var transform = "translate(-50%, -50%)";
var showGrandUnicorn = cornify_count == 15;
// Create a container for our 'corn or 'bow.
var div = document.createElement("div");
div.style.position = "fixed";
div.className = "__cornify_unicorn";
div.style.zIndex = 143143;
div.style.outline = 0;
div.onclick = cornify_add; // Click for more magic.
// Get the window width and height - requires some cross browser checking.
if (typeof window.innerHeight == "number") {
windowHeight = window.innerHeight;
windowWidth = window.innerWidth;
} else if (de && de.clientHeight) {
windowHeight = de.clientHeight;
windowWidth = de.clientWidth;
} else {
numType = "%";
height = Math.round(height * 100) + "%";
}
if (showGrandUnicorn) {
// Clicking 15 times summons the grand unicorn - which is centered on the screen.
div.style.top = "50%";
div.style.left = "50%";
div.style.zIndex = 143143143;
} else {
// Otherwise we randomize the position.
div.style.top = Math.round(Math.random() * 100) + "%";
div.style.left = Math.round(Math.random() * 100) + "%";
transform += " rotate(" + Math.round(Math.random() * 10 - 5) + "deg)";
}
// Create the image element.
var img = document.createElement("img");
img.style.opacity = 0;
img.style.transition = "all .1s linear";
img.alt = "A lovely unicorn or rainbow";
img.onload = function () {
img.style.opacity = 1;
};
// Used as a cache buster so the browser makes a new request every time instead of usign the previous, cached one.
var currentTime = new Date();
var submitTime = currentTime.getTime();
if (showGrandUnicorn) {
// Caching doesn't matter for the Grand Unicorn.
submitTime = 0;
}
// Construct our unicorn & rainbow request.
var url = `https://www.cornify.com/corns/${
Math.random() > 0.5 ? "r" : "u"
}${Math.ceil(Math.random() * 7)}.gif`;
// Add younicorns if requested.
if (options && (options.y || options.younicorns)) {
url += "&y=" + (options.y ? options.y : options.younicorns);
if (Math.random() > 0.5) {
// Flip horizontally at random.
if (transform.length > 0) {
transform += " scaleX(-1)";
}
}
}
div.style.transform = transform;
div.style.MozTransform = transform;
div.style.webkitTransform = transform;
img.setAttribute("src", url);
// Add a nice hover wigggle.
img.style.transition = "all .1s linear";
div.onmouseover = function () {
var size = 1 + Math.round(Math.random() * 10) / 100;
var angle = Math.round(Math.random() * 20 - 10);
var result = "rotate(" + angle + "deg) scale(" + size + "," + size + ")";
img.style.transform = result;
img.style.MozTransform = result;
img.style.webkitTransform = result;
};
div.onmouseout = function () {
var size = 0.9 + Math.round(Math.random() * 10) / 100;
var angle = Math.round(Math.random() * 6 - 3);
var result = "rotate(" + angle + "deg) scale(" + size + "," + size + ")";
img.style.transform = result;
img.style.MozTransform = result;
img.style.webkitTransform = result;
};
// Append our container DIV to the page.
var body = document.getElementsByTagName("body")[0];
body.appendChild(div);
div.appendChild(img);
// Hooray - now we have a sparkly unicorn (or rainbow) on the page. Another cornification well done. Congrats!
// When clicking 5 times, add a custom stylesheet to make the page look awesome.
if (cornify_count == 5) {
var cssExisting = document.getElementById("__cornify_css");
if (!cssExisting) {
var head = document.getElementsByTagName("head")[0];
var css = document.createElement("link");
css.id = "__cornify_css";
css.type = "text/css";
css.rel = "stylesheet";
css.href = "https://www.cornify.com/css/cornify.css";
css.media = "screen";
head.appendChild(css);
}
cornify_replace();
}
cornify_updatecount();
// Trigger an event on the document.
var event = new Event("cornify");
document.dispatchEvent(event);
};
// Tracks how often we cornified.
var cornify_updatecount = function () {
var id = "__cornify_count";
var p = document.getElementById(id);
if (p == null) {
var p = document.createElement("p");
p.id = id;
p.style.position = "fixed";
p.style.bottom = "5px";
p.style.left = "0px";
p.style.right = "0px";
p.style.zIndex = "1000000000";
p.style.color = "#ff00ff";
p.style.textAlign = "center";
p.style.fontSize = "24px";
p.style.fontFamily = "'Comic Sans MS', 'Comic Sans', 'Marker Felt', serif"; // Only the best!
p.style.textTransform = "uppercase";
var body = document.getElementsByTagName("body")[0];
body.appendChild(p);
}
if (cornify_count == 1) {
p.innerHTML = "You cornified!";
} else {
p.innerHTML = "You cornified " + cornify_count + " times!";
}
// Stores our count in a cookie for our next session.
cornify_setcookie("cornify", cornify_count + "", 1000);
};
var cornify_setcookie = function (name, value, days) {
var d = new Date();
d.setTime(d.getTime() + days * 24 * 60 * 60 * 1000);
var expires = "expires=" + d.toGMTString();
document.cookie = name + "=" + value + "; " + expires;
};
var cornify_getcookie = function (cname) {
var name = cname + "=";
var ca = document.cookie.split(";");
for (var i = 0; i < ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
};
// Retrieve our click count from the cookie when we start up.
cornify_count = parseInt(cornify_getcookie("cornify"));
if (isNaN(cornify_count)) {
cornify_count = 0;
}
// Adds happy words at the beginning of all headers on the page.
var cornify_replace = function () {
// Replace text.
var hc = 6;
var hs;
var h;
var k;
var words = [
"Happy",
"Sparkly",
"Glittery",
"Fun",
"Magical",
"Lovely",
"Cute",
"Charming",
"Amazing",
"Wonderful",
];
while (hc >= 1) {
hs = document.getElementsByTagName("h" + hc);
for (k = 0; k < hs.length; k++) {
h = hs[k];
h.innerHTML =
words[Math.floor(Math.random() * words.length)] + " " + h.innerHTML;
}
hc -= 1;
}
};
// Adds happy words at the beginning of all headers on the page.
var cornify_replace = function () {
var headerTypeIndex = 6;
var headerElements;
var headerElement;
var i;
var magicalWords = [
"Happy",
"Sparkly",
"Glittery",
"Fun",
"Magical",
"Lovely",
"Cute",
"Charming",
"Amazing",
"Wonderful",
];
while (headerTypeIndex >= 1) {
headerElements = document.getElementsByTagName("h" + headerTypeIndex);
for (i = 0; i < headerElements.length; i++) {
headerElement = headerElements[i];
headerElement.innerHTML =
magicalWords[Math.floor(Math.random() * magicalWords.length)] +
" " +
headerElement.innerHTML;
}
headerTypeIndex -= 1;
}
};
// Clicking the rainbow cupcake button makes all the unicorns
// disappear (should only be used in an emergency, since it's sad).
var cornify_click_cupcake_button = function () {
var doc = document;
var corns = doc.getElementsByClassName("__cornify_unicorn");
if (corns) {
for (var i = 0; i < corns.length; i++) {
corns[i].parentNode.removeChild(corns[i]);
}
}
// Remove our counter.
var button = doc.getElementById("__cornify_count");
if (button) {
button.parentNode.removeChild(button);
}
// Remove the cupcake button.
var button = doc.getElementById("__cornify_cupcake_button");
if (button) {
button.parentNode.removeChild(button);
}
var event = new Event("cornify-clear");
document.dispatchEvent(event);
};
// Add the rainbow cupcake button to the page.
var cornify_add_cupcake_button = function () {
var id = "__cornify_cupcake_button";
var doc = document;
var button = doc.getElementById(id);
if (!button) {
button = doc.createElement("div");
button.id = id;
button.onclick = cornify_click_cupcake_button;
button.style.position = "fixed";
button.style.top = "10px";
button.style.right = "10px";
button.style.zIndex = 2147483640;
button.setAttribute("aria-label", "Hide unicorns and rainbows");
var image = document.createElement("img");
image.src = "https://www.cornify.com/assets/cornify-cupcake-button.png";
image.alt = "Cupcake button";
image.width = 50;
image.height = 50;
image.style.width = "50px !important";
image.style.height = "50px !important";
image.style.display = "block !important";
image.style.cursor = "pointer !important";
image.style.margin = "0 !important";
image.style.padding = "0 !important";
button.appendChild(image);
doc.getElementsByTagName("body")[0].appendChild(button);
}
};
// Adapted from http://www.snaptortoise.com/konami-js/
var cornami = {
input: "",
pattern: "38384040373937396665",
clear: setTimeout("cornami.clear_input()", 5000),
load: function () {
window.document.onkeydown = function (event) {
if (cornami.input == cornami.pattern) {
cornify_add();
clearTimeout(cornami.clear);
return;
} else {
cornami.input += event.keyCode;
if (cornami.input == cornami.pattern) {
cornify_add();
}
clearTimeout(cornami.clear);
cornami.clear = setTimeout("cornami.clear_input()", 5000);
}
};
},
clear_input: function () {
cornami.input = "";
clearTimeout(cornami.clear);
},
};
cornami.load();
================================================
FILE: 12 - Key Sequence Detection/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Key Detection</title>
<script type="text/javascript" src="./cornify.js"></script>
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<script>
const pressed = [];
const secretCode = "wesbos";
window.addEventListener("keyup", (e) => {
console.log(e.key);
pressed.push(e.key);
pressed.splice(
-secretCode.length - 1,
pressed.length - secretCode.length
);
if (pressed.join("").includes(secretCode)) {
console.log("DING DING!");
cornify_add();
}
console.log(pressed);
});
</script>
</body>
</html>
================================================
FILE: 12 - Key Sequence Detection/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Key Detection</title>
<script type="text/javascript" src="./cornify.js"></script>
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<script></script>
</body>
</html>
================================================
FILE: 13 - Slide in on Scroll/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<div class="site-wrap">
<h1>Slide in on Scroll</h1>
<p>Consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariaturlores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Adipisicing elit. Tempore tempora rerum..</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<img src="http://unsplash.it/400/400" class="align-left slide-in">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates, deserunt facilis et iste corrupti omnis tenetur est. Iste ut est dicta dolor itaque adipisci, dolorum minima, veritatis earum provident error molestias. Ratione magni illo sint vel velit ut excepturi consectetur suscipit, earum modi accusamus voluptatem nostrum, praesentium numquam, reiciendis voluptas sit id quisquam. Consequatur in quis reprehenderit modi perspiciatis necessitatibus saepe, quidem, suscipit iure natus dignissimos ipsam, eligendi deleniti accusantium, rerum quibusdam fugit perferendis et optio recusandae sed ratione. Culpa, dolorum reprehenderit harum ab voluptas fuga, nisi eligendi natus maiores illum quas quos et aperiam aut doloremque optio maxime fugiat doloribus. Eum dolorum expedita quam, nesciunt</p>
<img src="http://unsplash.it/400/401" class="align-right slide-in">
<p> at provident praesentium atque quas rerum optio dignissimos repudiandae ullam illum quibusdam. Vel ad error quibusdam, illo ex totam placeat. Quos excepturi fuga, molestiae ea quisquam minus, ratione dicta consectetur officia omnis, doloribus voluptatibus? Veniam ipsum veritatis architecto, provident quas consequatur doloremque quam quidem earum expedita, ad delectus voluptatum, omnis praesentium nostrum qui aspernatur ea eaque adipisci et cumque ab? Ea voluptatum dolore itaque odio. Eius minima distinctio harum, officia ab nihil exercitationem. Tempora rem nemo nam temporibus molestias facilis minus ipsam quam doloribus consequatur debitis nesciunt tempore officiis aperiam quisquam, molestiae voluptates cum, fuga culpa. Distinctio accusamus quibusdam, tempore perspiciatis dolorum optio facere consequatur quidem ullam beatae architecto, ipsam sequi officiis dignissimos amet impedit natus necessitatibus tenetur repellendus dolor rem! Dicta dolorem, iure, facilis illo ex nihil ipsa amet officia, optio temporibus eum autem odit repellendus nisi. Possimus modi, corrupti error debitis doloribus dicta libero earum, sequi porro ut excepturi nostrum ea voluptatem nihil culpa? Ullam expedita eligendi obcaecati reiciendis velit provident omnis quas qui in corrupti est dolore facere ad hic, animi soluta assumenda consequuntur reprehenderit! Voluptate dolor nihil veniam laborum voluptas nisi pariatur sed optio accusantium quam consectetur, corrupti, sequi et consequuntur, excepturi doloremque. Tempore quis velit corporis neque fugit non sequi eaque rem hic. Facere, inventore, aspernatur. Accusantium modi atque, asperiores qui nobis soluta cumque suscipit excepturi possimus doloremque odit saepe perferendis temporibus molestiae nostrum voluptatum quis id sint quidem nesciunt culpa. Rerum labore dolor beatae blanditiis praesentium explicabo velit optio esse aperiam similique, voluptatem cum, maiores ipsa tempore. Reiciendis sed culpa atque inventore, nam ullam enim expedita consectetur id velit iusto alias vitae explicabo nemo neque odio reprehenderit soluta sint eaque. Aperiam, qui ut tenetur, voluptate doloremque officiis dicta quaerat voluptatem rerum natus magni. Eum amet autem dolor ullam.</p>
<img src="http://unsplash.it/200/500" class="align-left slide-in">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet <img src="http://unsplash.it/200/200" class="align-right slide-in"> temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis</p>
<p>laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>
<img src="http://unsplash.it/400/400" class="align-right slide-in">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>
</div>
<script>
function debounce(func, wait = 20, immediate = true) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
const sliderImages = document.querySelectorAll('.slide-in');
function checkSlide() {
sliderImages.forEach(sliderImage => {
// half way through the image
const slideInAt = (window.scrollY + window.innerHeight) - sliderImage.height / 2;
// bottom of the image
const imageBottom = sliderImage.offsetTop + sliderImage.height;
const isHalfShown = slideInAt > sliderImage.offsetTop;
const isNotScrolledPast = window.scrollY < imageBottom;
if (isHalfShown && isNotScrolledPast) {
sliderImage.classList.add('active');
} else {
sliderImage.classList.remove('active');
}
});
}
window.addEventListener('scroll', debounce(checkSlide));
</script>
<style>
html {
box-sizing: border-box;
background: #ffc600;
font-family: 'helvetica neue';
font-size: 20px;
font-weight: 200;
}
body {
margin: 0;
}
*, *:before, *:after {
box-sizing: inherit;
}
h1 {
margin-top: 0;
}
.site-wrap {
max-width: 700px;
margin: 100px auto;
background: white;
padding: 40px;
text-align: justify;
}
.align-left {
float: left;
margin-right: 20px;
}
.align-right {
float: right;
margin-left: 20px;
}
.slide-in {
opacity: 0;
transition: all .5s;
}
.align-left.slide-in {
transform: translateX(-30%) scale(0.95);
}
.align-right.slide-in {
transform: translateX(30%) scale(0.95);
}
.slide-in.active {
opacity: 1;
transform: translateX(0%) scale(1);
}
</style>
</body>
</html>
================================================
FILE: 13 - Slide in on Scroll/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<div class="site-wrap">
<h1>Slide in on Scroll</h1>
<p>Consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariaturlores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Adipisicing elit. Tempore tempora rerum..</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<img src="http://unsplash.it/400/400" class="align-left slide-in">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates, deserunt facilis et iste corrupti omnis tenetur est. Iste ut est dicta dolor itaque adipisci, dolorum minima, veritatis earum provident error molestias. Ratione magni illo sint vel velit ut excepturi consectetur suscipit, earum modi accusamus voluptatem nostrum, praesentium numquam, reiciendis voluptas sit id quisquam. Consequatur in quis reprehenderit modi perspiciatis necessitatibus saepe, quidem, suscipit iure natus dignissimos ipsam, eligendi deleniti accusantium, rerum quibusdam fugit perferendis et optio recusandae sed ratione. Culpa, dolorum reprehenderit harum ab voluptas fuga, nisi eligendi natus maiores illum quas quos et aperiam aut doloremque optio maxime fugiat doloribus. Eum dolorum expedita quam, nesciunt</p>
<img src="http://unsplash.it/400/401" class="align-right slide-in">
<p> at provident praesentium atque quas rerum optio dignissimos repudiandae ullam illum quibusdam. Vel ad error quibusdam, illo ex totam placeat. Quos excepturi fuga, molestiae ea quisquam minus, ratione dicta consectetur officia omnis, doloribus voluptatibus? Veniam ipsum veritatis architecto, provident quas consequatur doloremque quam quidem earum expedita, ad delectus voluptatum, omnis praesentium nostrum qui aspernatur ea eaque adipisci et cumque ab? Ea voluptatum dolore itaque odio. Eius minima distinctio harum, officia ab nihil exercitationem. Tempora rem nemo nam temporibus molestias facilis minus ipsam quam doloribus consequatur debitis nesciunt tempore officiis aperiam quisquam, molestiae voluptates cum, fuga culpa. Distinctio accusamus quibusdam, tempore perspiciatis dolorum optio facere consequatur quidem ullam beatae architecto, ipsam sequi officiis dignissimos amet impedit natus necessitatibus tenetur repellendus dolor rem! Dicta dolorem, iure, facilis illo ex nihil ipsa amet officia, optio temporibus eum autem odit repellendus nisi. Possimus modi, corrupti error debitis doloribus dicta libero earum, sequi porro ut excepturi nostrum ea voluptatem nihil culpa? Ullam expedita eligendi obcaecati reiciendis velit provident omnis quas qui in corrupti est dolore facere ad hic, animi soluta assumenda consequuntur reprehenderit! Voluptate dolor nihil veniam laborum voluptas nisi pariatur sed optio accusantium quam consectetur, corrupti, sequi et consequuntur, excepturi doloremque. Tempore quis velit corporis neque fugit non sequi eaque rem hic. Facere, inventore, aspernatur. Accusantium modi atque, asperiores qui nobis soluta cumque suscipit excepturi possimus doloremque odit saepe perferendis temporibus molestiae nostrum voluptatum quis id sint quidem nesciunt culpa. Rerum labore dolor beatae blanditiis praesentium explicabo velit optio esse aperiam similique, voluptatem cum, maiores ipsa tempore. Reiciendis sed culpa atque inventore, nam ullam enim expedita consectetur id velit iusto alias vitae explicabo nemo neque odio reprehenderit soluta sint eaque. Aperiam, qui ut tenetur, voluptate doloremque officiis dicta quaerat voluptatem rerum natus magni. Eum amet autem dolor ullam.</p>
<img src="http://unsplash.it/200/500" class="align-left slide-in">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet <img src="http://unsplash.it/200/200" class="align-right slide-in"> temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis</p>
<p>laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>
<img src="http://unsplash.it/400/400" class="align-right slide-in">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>
</div>
<script>
function debounce(func, wait = 20, immediate = true) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
</script>
<style>
html {
box-sizing: border-box;
background: #ffc600;
font-family: 'helvetica neue';
font-size: 20px;
font-weight: 200;
}
body {
margin: 0;
}
*, *:before, *:after {
box-sizing: inherit;
}
h1 {
margin-top: 0;
}
.site-wrap {
max-width: 700px;
margin: 100px auto;
background: white;
padding: 40px;
text-align: justify;
}
.align-left {
float: left;
margin-right: 20px;
}
.align-right {
float: right;
margin-left: 20px;
}
.slide-in {
opacity: 0;
transition: all .5s;
}
.align-left.slide-in {
transform: translateX(-30%) scale(0.95);
}
.align-right.slide-in {
transform: translateX(30%) scale(0.95);
}
.slide-in.active {
opacity: 1;
transform: translateX(0%) scale(1);
}
</style>
</body>
</html>
================================================
FILE: 14 - JavaScript References VS Copying/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS Reference VS Copy</title>
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<script>
// start with strings, numbers and booleans
// let age = 100;
// let age2 = age;
// console.log(age, age2);
// age = 200;
// console.log(age, age2);
// let name = 'Wes';
// let name2 = name;
// console.log(name, name2);
// name = 'wesley';
// console.log(name, name2);
// Let's say we have an array
const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];
// and we want to make a copy of it.
const team = players;
console.log(players, team);
// You might think we can just do something like this:
// team[3] = 'Lux';
// however what happens when we update that array?
// now here is the problem!
// oh no - we have edited the original array too!
// Why? It's because that is an array reference, not an array copy. They both point to the same array!
// So, how do we fix this? We take a copy instead!
const team2 = players.slice();
// one way
// or create a new array and concat the old one in
const team3 = [].concat(players);
// or use the new ES6 Spread
const team4 = [...players];
team4[3] = 'heeee hawww';
console.log(team4);
const team5 = Array.from(players);
// now when we update it, the original one isn't changed
// The same thing goes for objects, let's say we have a person object
// with Objects
const person = {
name: 'Wes Bos',
age: 80
};
// and think we make a copy:
// const captain = person;
// captain.number = 99;
// how do we take a copy instead?
const cap2 = Object.assign({}, person, { number: 99, age: 12 });
console.log(cap2);
// We will hopefully soon see the object ...spread
// const cap3 = {...person};
// Things to note - this is only 1 level deep - both for Arrays and Objects. lodash has a cloneDeep method, but you should think twice before using it.
const wes = {
name: 'Wes',
age: 100,
social: {
twitter: '@wesbos',
facebook: 'wesbos.developer'
}
};
console.clear();
console.log(wes);
const dev = Object.assign({}, wes);
const dev2 = JSON.parse(JSON.stringify(wes));
</script>
</body>
</html>
================================================
FILE: 14 - JavaScript References VS Copying/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JS Reference VS Copy</title>
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<script>
// start with strings, numbers and booleans
// Let's say we have an array
const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];
// and we want to make a copy of it.
// You might think we can just do something like this:
// however what happens when we update that array?
// now here is the problem!
// oh no - we have edited the original array too!
// Why? It's because that is an array reference, not an array copy. They both point to the same array!
// So, how do we fix this? We take a copy instead!
// one way
// or create a new array and concat the old one in
// or use the new ES6 Spread
// now when we update it, the original one isn't changed
// The same thing goes for objects, let's say we have a person object
// with Objects
const person = {
name: 'Wes Bos',
age: 80
};
// and think we make a copy:
// how do we take a copy instead?
// We will hopefully soon see the object ...spread
// Things to note - this is only 1 level deep - both for Arrays and Objects. lodash has a cloneDeep method, but you should think twice before using it.
</script>
</body>
</html>
================================================
FILE: 15 - LocalStorage/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>LocalStorage</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<!--
Fish SVG Cred:
https://thenounproject.com/search/?q=fish&i=589236
-->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve"><g><path d="M495.9,425.3H16.1c-5.2,0-10.1,2.9-12.5,7.6c-2.4,4.7-2.1,10.3,0.9,14.6l39,56.4c2.6,3.8,7,6.1,11.6,6.1h401.7 c4.6,0,9-2.3,11.6-6.1l39-56.4c3-4.3,3.3-9.9,0.9-14.6C506,428.2,501.1,425.3,495.9,425.3z M449.4,481.8H62.6L43,453.6H469 L449.4,481.8z"/><path d="M158.3,122c7.8,0,14.1-6.3,14.1-14.1V43.4c0-7.8-6.3-14.1-14.1-14.1c-7.8,0-14.1,6.3-14.1,14.1v64.5 C144.2,115.7,150.5,122,158.3,122z"/><path d="M245.1,94.7c7.8,0,14.1-6.3,14.1-14.1V16.1c0-7.8-6.3-14.1-14.1-14.1C237.3,2,231,8.3,231,16.1v64.5 C231,88.4,237.3,94.7,245.1,94.7z"/><path d="M331.9,122c7.8,0,14.1-6.3,14.1-14.1V43.4c0-7.8-6.3-14.1-14.1-14.1s-14.1,6.3-14.1,14.1v64.5 C317.8,115.7,324.1,122,331.9,122z"/><path d="M9.6,385.2c5.3,2.8,11.8,1.9,16.2-2.2l50.6-47.7c56.7,46.5,126.6,71.9,198.3,71.9c0,0,0,0,0,0 c87.5,0,169.7-36.6,231.4-103.2c5-5.4,5-13.8,0-19.2c-61.8-66.5-144-103.2-231.4-103.2c-72,0-142.2,25.6-199,72.5l-50-47.1 c-4.4-4.1-10.9-5-16.2-2.2c-5.3,2.8-8.3,8.7-7.4,14.6l11.6,75L2.2,370.6C1.3,376.5,4.2,382.4,9.6,385.2z M380.9,230.8 c34.9,14.3,67.2,35.7,95.3,63.6c-10.1,10-20.8,19.2-31.9,27.5c-22.4-3.3-29.6-8.8-30.7-9.7c-4-5.7-11.8-7.7-18.1-4.4 c-6.9,3.6-9.5,12.2-5.9,19.1c1.9,3.5,7.3,10.3,22.4,16c-10.1,5.7-20.5,10.7-31.1,15.1C352.4,320.2,352.4,268.6,380.9,230.8z M36.3,255.6l29.4,27.7c5.3,5,13.6,5.1,19.1,0.3c53.2-47.6,120.7-73.7,190-73.7c26.9,0,53.2,3.9,78.5,11.3 c-29.3,44.6-29.3,102,0,146.6c-25.3,7.4-51.6,11.3-78.5,11.3c-69,0-136.3-26-189.4-73.2c-2.7-2.4-13.4-6.3-19.1,0.3l-30.1,28.3 l5.7-40C42.2,293,36.3,255.6,36.3,255.6z"/><circle cx="398.8" cy="273.8" r="14.1"/></g></svg>
<div class="wrapper">
<h2>LOCAL TAPAS</h2>
<p></p>
<ul class="plates">
<li>Loading Tapas...</li>
</ul>
<form class="add-items">
<input type="text" name="item" placeholder="Item Name" required>
<input type="submit" value="+ Add Item">
</form>
</div>
<script>
const addItems = document.querySelector('.add-items');
const itemsList = document.querySelector('.plates');
const items = JSON.parse(localStorage.getItem('items')) || [];
function addItem(e) {
e.preventDefault();
const text = (this.querySelector('[name=item]')).value;
const item = {
text,
done: false
};
items.push(item);
populateList(items, itemsList);
localStorage.setItem('items', JSON.stringify(items));
this.reset();
}
function populateList(plates = [], platesList) {
platesList.innerHTML = plates.map((plate, i) => {
return `
<li>
<input type="checkbox" data-index=${i} id="item${i}" ${plate.done ? 'checked' : ''} />
<label for="item${i}">${plate.text}</label>
</li>
`;
}).join('');
}
function toggleDone(e) {
if (!e.target.matches('input')) return; // skip this unless it's an input
const el = e.target;
const index = el.dataset.index;
items[index].done = !items[index].done;
localStorage.setItem('items', JSON.stringify(items));
populateList(items, itemsList);
}
addItems.addEventListener('submit', addItem);
itemsList.addEventListener('click', toggleDone);
populateList(items, itemsList);
</script>
</body>
</html>
================================================
FILE: 15 - LocalStorage/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>LocalStorage</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<!--
Fish SVG Cred:
https://thenounproject.com/search/?q=fish&i=589236
-->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve"><g><path d="M495.9,425.3H16.1c-5.2,0-10.1,2.9-12.5,7.6c-2.4,4.7-2.1,10.3,0.9,14.6l39,56.4c2.6,3.8,7,6.1,11.6,6.1h401.7 c4.6,0,9-2.3,11.6-6.1l39-56.4c3-4.3,3.3-9.9,0.9-14.6C506,428.2,501.1,425.3,495.9,425.3z M449.4,481.8H62.6L43,453.6H469 L449.4,481.8z"/><path d="M158.3,122c7.8,0,14.1-6.3,14.1-14.1V43.4c0-7.8-6.3-14.1-14.1-14.1c-7.8,0-14.1,6.3-14.1,14.1v64.5 C144.2,115.7,150.5,122,158.3,122z"/><path d="M245.1,94.7c7.8,0,14.1-6.3,14.1-14.1V16.1c0-7.8-6.3-14.1-14.1-14.1C237.3,2,231,8.3,231,16.1v64.5 C231,88.4,237.3,94.7,245.1,94.7z"/><path d="M331.9,122c7.8,0,14.1-6.3,14.1-14.1V43.4c0-7.8-6.3-14.1-14.1-14.1s-14.1,6.3-14.1,14.1v64.5 C317.8,115.7,324.1,122,331.9,122z"/><path d="M9.6,385.2c5.3,2.8,11.8,1.9,16.2-2.2l50.6-47.7c56.7,46.5,126.6,71.9,198.3,71.9c0,0,0,0,0,0 c87.5,0,169.7-36.6,231.4-103.2c5-5.4,5-13.8,0-19.2c-61.8-66.5-144-103.2-231.4-103.2c-72,0-142.2,25.6-199,72.5l-50-47.1 c-4.4-4.1-10.9-5-16.2-2.2c-5.3,2.8-8.3,8.7-7.4,14.6l11.6,75L2.2,370.6C1.3,376.5,4.2,382.4,9.6,385.2z M380.9,230.8 c34.9,14.3,67.2,35.7,95.3,63.6c-10.1,10-20.8,19.2-31.9,27.5c-22.4-3.3-29.6-8.8-30.7-9.7c-4-5.7-11.8-7.7-18.1-4.4 c-6.9,3.6-9.5,12.2-5.9,19.1c1.9,3.5,7.3,10.3,22.4,16c-10.1,5.7-20.5,10.7-31.1,15.1C352.4,320.2,352.4,268.6,380.9,230.8z M36.3,255.6l29.4,27.7c5.3,5,13.6,5.1,19.1,0.3c53.2-47.6,120.7-73.7,190-73.7c26.9,0,53.2,3.9,78.5,11.3 c-29.3,44.6-29.3,102,0,146.6c-25.3,7.4-51.6,11.3-78.5,11.3c-69,0-136.3-26-189.4-73.2c-2.7-2.4-13.4-6.3-19.1,0.3l-30.1,28.3 l5.7-40C42.2,293,36.3,255.6,36.3,255.6z"/><circle cx="398.8" cy="273.8" r="14.1"/></g></svg>
<div class="wrapper">
<h2>LOCAL TAPAS</h2>
<p></p>
<ul class="plates">
<li>Loading Tapas...</li>
</ul>
<form class="add-items">
<input type="text" name="item" placeholder="Item Name" required>
<input type="submit" value="+ Add Item">
</form>
</div>
<script>
const addItems = document.querySelector('.add-items');
const itemsList = document.querySelector('.plates');
const items = [];
</script>
</body>
</html>
================================================
FILE: 15 - LocalStorage/style.css
================================================
html {
box-sizing: border-box;
background: url("oh-la-la.jpeg") center no-repeat;
background-size: cover;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
font-family: Futura, "Trebuchet MS", Arial, sans-serif;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
svg {
fill: white;
background: rgba(0, 0, 0, 0.1);
padding: 20px;
border-radius: 50%;
width: 200px;
margin-bottom: 50px;
}
.wrapper {
padding: 20px;
max-width: 350px;
background: rgba(255, 255, 255, 0.95);
box-shadow: 0 0 0 10px rgba(0, 0, 0, 0.1);
}
h2 {
text-align: center;
margin: 0;
font-weight: 200;
}
.plates {
margin: 0;
padding: 0;
text-align: left;
list-style: none;
}
.plates li {
border-bottom: 1px solid rgba(0, 0, 0, 0.2);
padding: 10px 0;
font-weight: 100;
display: flex;
}
.plates label {
flex: 1;
cursor: pointer;
}
.plates input {
display: none;
}
.plates input + label:before {
content: "⬜️";
margin-right: 10px;
}
.plates input:checked + label:before {
content: "🌮";
}
.add-items {
margin-top: 20px;
}
.add-items input {
padding: 10px;
outline: 0;
border: 1px solid rgba(0, 0, 0, 0.1);
}
================================================
FILE: 16 - Mouse Move Shadow/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Mouse Shadow</title>
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<div class="hero">
<h1 contenteditable>🔥WOAH!</h1>
</div>
<style>
html {
color: black;
font-family: sans-serif;
}
body {
margin: 0;
}
.hero {
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
color: black;
}
h1 {
text-shadow: 10px 10px 0 rgba(0,0,0,1);
font-size: 100px;
}
</style>
<script>
const hero = document.querySelector('.hero');
const text = hero.querySelector('h1');
const walk = 500; // 500px
function shadow(e) {
const { offsetWidth: width, offsetHeight: height } = hero;
let { offsetX: x, offsetY: y } = e;
if (this !== e.target) {
x = x + e.target.offsetLeft;
y = y + e.target.offsetTop;
}
const xWalk = Math.round((x / width * walk) - (walk / 2));
const yWalk = Math.round((y / height * walk) - (walk / 2));
text.style.textShadow = `
${xWalk}px ${yWalk}px 0 rgba(255,0,255,0.7),
${xWalk * -1}px ${yWalk}px 0 rgba(0,255,255,0.7),
${yWalk}px ${xWalk * -1}px 0 rgba(0,255,0,0.7),
${yWalk * -1}px ${xWalk}px 0 rgba(0,0,255,0.7)
`;
}
hero.addEventListener('mousemove', shadow);
</script>
</body>
</html>
================================================
FILE: 16 - Mouse Move Shadow/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Mouse Shadow</title>
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<div class="hero">
<h1 contenteditable>🔥WOAH!</h1>
</div>
<style>
html {
color: black;
font-family: sans-serif;
}
body {
margin: 0;
}
.hero {
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
color: black;
}
h1 {
text-shadow: 10px 10px 0 rgba(0,0,0,1);
font-size: 100px;
}
</style>
<script>
</script>
</body>
</html>
================================================
FILE: 17 - Sort Without Articles/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sort Without Articles</title>
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<style>
body {
margin: 0;
font-family: sans-serif;
background: url("https://source.unsplash.com/nDqA4d5NL0k/2000x2000");
background-size: cover;
display: flex;
align-items: center;
min-height: 100vh;
}
#bands {
list-style: inside square;
font-size: 20px;
background: white;
width: 500px;
margin: auto;
padding: 0;
box-shadow: 0 0 0 20px rgba(0, 0, 0, 0.05);
}
#bands li {
border-bottom: 1px solid #efefef;
padding: 20px;
}
#bands li:last-child {
border-bottom: 0;
}
a {
color: #ffc600;
text-decoration: none;
}
</style>
<ul id="bands"></ul>
<script>
const bands = ['The Plot in You', 'The Devil Wears Prada', 'Pierce the Veil', 'Norma Jean', 'The Bled', 'Say Anything', 'The Midway State', 'We Came as Romans', 'Counterparts', 'Oh, Sleeper', 'A Skylit Drive', 'Anywhere But Here', 'An Old Dog'];
function strip(bandName) {
return bandName.replace(/^(a |the |an )/i, '').trim();
}
const sortedBands = bands.sort((a, b) => strip(a) > strip(b) ? 1 : -1);
document.querySelector('#bands').innerHTML =
sortedBands
.map(band => `<li>${band}</li>`)
.join('');
console.log(sortedBands);
</script>
</body>
</html>
================================================
FILE: 17 - Sort Without Articles/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sort Without Articles</title>
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<style>
body {
margin: 0;
font-family: sans-serif;
background: url("https://source.unsplash.com/nDqA4d5NL0k/2000x2000");
background-size: cover;
display: flex;
align-items: center;
min-height: 100vh;
}
#bands {
list-style: inside square;
font-size: 20px;
background: white;
width: 500px;
margin: auto;
padding: 0;
box-shadow: 0 0 0 20px rgba(0, 0, 0, 0.05);
}
#bands li {
border-bottom: 1px solid #efefef;
padding: 20px;
}
#bands li:last-child {
border-bottom: 0;
}
a {
color: #ffc600;
text-decoration: none;
}
</style>
<ul id="bands"></ul>
<script>
const bands = ['The Plot in You', 'The Devil Wears Prada', 'Pierce the Veil', 'Norma Jean', 'The Bled', 'Say Anything', 'The Midway State', 'We Came as Romans', 'Counterparts', 'Oh, Sleeper', 'A Skylit Drive', 'Anywhere But Here', 'An Old Dog'];
</script>
</body>
</html>
================================================
FILE: 18 - Adding Up Times with Reduce/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Videos</title>
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<ul class="videos">
<li data-time="5:43">
Video 1
</li>
<li data-time="2:33">
Video 2
</li>
<li data-time="3:45">
Video 3
</li>
<li data-time="0:47">
Video 4
</li>
<li data-time="5:21">
Video 5
</li>
<li data-time="6:56">
Video 6
</li>
<li data-time="3:46">
Video 7
</li>
<li data-time="5:25">
Video 8
</li>
<li data-time="3:14">
Video 9
</li>
<li data-time="3:31">
Video 10
</li>
<li data-time="5:59">
Video 11
</li>
<li data-time="3:07">
Video 12
</li>
<li data-time="11:29">
Video 13
</li>
<li data-time="8:57">
Video 14
</li>
<li data-time="5:49">
Video 15
</li>
<li data-time="5:52">
Video 16
</li>
<li data-time="5:50">
Video 17
</li>
<li data-time="9:13">
Video 18
</li>
<li data-time="11:51">
Video 19
</li>
<li data-time="7:58">
Video 20
</li>
<li data-time="4:40">
Video 21
</li>
<li data-time="4:45">
Video 22
</li>
<li data-time="6:46">
Video 23
</li>
<li data-time="7:24">
Video 24
</li>
<li data-time="7:12">
Video 25
</li>
<li data-time="5:23">
Video 26
</li>
<li data-time="3:34">
Video 27
</li>
<li data-time="8:22">
Video 28
</li>
<li data-time="5:17">
Video 29
</li>
<li data-time="3:10">
Video 30
</li>
<li data-time="4:43">
Video 31
</li>
<li data-time="19:43">
Video 32
</li>
<li data-time="0:47">
Video 33
</li>
<li data-time="0:47">
Video 34
</li>
<li data-time="3:14">
Video 35
</li>
<li data-time="3:59">
Video 36
</li>
<li data-time="2:43">
Video 37
</li>
<li data-time="4:17">
Video 38
</li>
<li data-time="6:56">
Video 39
</li>
<li data-time="3:05">
Video 40
</li>
<li data-time="2:06">
Video 41
</li>
<li data-time="1:59">
Video 42
</li>
<li data-time="1:49">
Video 43
</li>
<li data-time="3:36">
Video 44
</li>
<li data-time="7:10">
Video 45
</li>
<li data-time="3:44">
Video 46
</li>
<li data-time="3:44">
Video 47
</li>
<li data-time="4:36">
Video 48
</li>
<li data-time="3:16">
Video 49
</li>
<li data-time="1:10">
Video 50
</li>
<li data-time="6:10">
Video 51
</li>
<li data-time="2:14">
Video 52
</li>
<li data-time="3:44">
Video 53
</li>
<li data-time="5:05">
Video 54
</li>
<li data-time="6:03">
Video 55
</li>
<li data-time="12:39">
Video 56
</li>
<li data-time="1:56">
Video 57
</li>
<li data-time="4:04">
Video 58
</li>
</ul>
<script>
const timeNodes = Array.from(document.querySelectorAll('[data-time]'));
const seconds = timeNodes
.map(node => node.dataset.time)
.map(timeCode => {
const [mins, secs] = timeCode.split(':').map(parseFloat);
return (mins * 60) + secs;
})
.reduce((total, vidSeconds) => total + vidSeconds);
let secondsLeft = seconds;
const hours = Math.floor(secondsLeft / 3600);
secondsLeft = secondsLeft % 3600;
const mins = Math.floor(secondsLeft / 60);
secondsLeft = secondsLeft % 60;
console.log(hours, mins, secondsLeft);
</script>
</body>
</html>
================================================
FILE: 18 - Adding Up Times with Reduce/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Videos</title>
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<ul class="videos">
<li data-time="5:43">
Video 1
</li>
<li data-time="2:33">
Video 2
</li>
<li data-time="3:45">
Video 3
</li>
<li data-time="0:47">
Video 4
</li>
<li data-time="5:21">
Video 5
</li>
<li data-time="6:56">
Video 6
</li>
<li data-time="3:46">
Video 7
</li>
<li data-time="5:25">
Video 8
</li>
<li data-time="3:14">
Video 9
</li>
<li data-time="3:31">
Video 10
</li>
<li data-time="5:59">
Video 11
</li>
<li data-time="3:07">
Video 12
</li>
<li data-time="11:29">
Video 13
</li>
<li data-time="8:57">
Video 14
</li>
<li data-time="5:49">
Video 15
</li>
<li data-time="5:52">
Video 16
</li>
<li data-time="5:50">
Video 17
</li>
<li data-time="9:13">
Video 18
</li>
<li data-time="11:51">
Video 19
</li>
<li data-time="7:58">
Video 20
</li>
<li data-time="4:40">
Video 21
</li>
<li data-time="4:45">
Video 22
</li>
<li data-time="6:46">
Video 23
</li>
<li data-time="7:24">
Video 24
</li>
<li data-time="7:12">
Video 25
</li>
<li data-time="5:23">
Video 26
</li>
<li data-time="3:34">
Video 27
</li>
<li data-time="8:22">
Video 28
</li>
<li data-time="5:17">
Video 29
</li>
<li data-time="3:10">
Video 30
</li>
<li data-time="4:43">
Video 31
</li>
<li data-time="19:43">
Video 32
</li>
<li data-time="0:47">
Video 33
</li>
<li data-time="0:47">
Video 34
</li>
<li data-time="3:14">
Video 35
</li>
<li data-time="3:59">
Video 36
</li>
<li data-time="2:43">
Video 37
</li>
<li data-time="4:17">
Video 38
</li>
<li data-time="6:56">
Video 39
</li>
<li data-time="3:05">
Video 40
</li>
<li data-time="2:06">
Video 41
</li>
<li data-time="1:59">
Video 42
</li>
<li data-time="1:49">
Video 43
</li>
<li data-time="3:36">
Video 44
</li>
<li data-time="7:10">
Video 45
</li>
<li data-time="3:44">
Video 46
</li>
<li data-time="3:44">
Video 47
</li>
<li data-time="4:36">
Video 48
</li>
<li data-time="3:16">
Video 49
</li>
<li data-time="1:10">
Video 50
</li>
<li data-time="6:10">
Video 51
</li>
<li data-time="2:14">
Video 52
</li>
<li data-time="3:44">
Video 53
</li>
<li data-time="5:05">
Video 54
</li>
<li data-time="6:03">
Video 55
</li>
<li data-time="12:39">
Video 56
</li>
<li data-time="1:56">
Video 57
</li>
<li data-time="4:04">
Video 58
</li>
</ul>
<script>
</script>
</body>
</html>
================================================
FILE: 19 - Webcam Fun/index.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Get User Media Code Along!</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<div class="photobooth">
<div class="controls">
<button onClick="takePhoto()">Take Photo</button>
<!-- <div class="rgb">
<label for="rmin">Red Min:</label>
<input type="range" min=0 max=255 name="rmin">
<label for="rmax">Red Max:</label>
<input type="range" min=0 max=255 name="rmax">
<br>
<label for="gmin">Green Min:</label>
<input type="range" min=0 max=255 name="gmin">
<label for="gmax">Green Max:</label>
<input type="range" min=0 max=255 name="gmax">
<br>
<label for="bmin">Blue Min:</label>
<input type="range" min=0 max=255 name="bmin">
<label for="bmax">Blue Max:</label>
<input type="range" min=0 max=255 name="bmax">
</div> -->
</div>
<canvas class="photo"></canvas>
<video class="player"></video>
<div class="strip"></div>
</div>
<audio class="snap" src="./snap.mp3" hidden></audio>
<script src="scripts.js"></script>
</body>
</html>
================================================
FILE: 19 - Webcam Fun/package.json
================================================
{
"name": "gum",
"version": "1.0.0",
"description": "",
"main": "scripts.js",
"scripts": {
"start": "browser-sync start --server --files \"*.css, *.html, *.js\""
},
"author": "",
"license": "ISC",
"devDependencies": {
"browser-sync": "^2.12.5 <2.23.2"
}
}
================================================
FILE: 19 - Webcam Fun/scripts-FINISHED.js
================================================
const video = document.querySelector('.player');
const canvas = document.querySelector('.photo');
const ctx = canvas.getContext('2d');
const strip = document.querySelector('.strip');
const snap = document.querySelector('.snap');
function getVideo() {
navigator.mediaDevices.getUserMedia({ video: true, audio: false })
.then(localMediaStream => {
console.log(localMediaStream);
// DEPRECIATION :
// The following has been depreceated by major browsers as of Chrome and Firefox.
// video.src = window.URL.createObjectURL(localMediaStream);
// Please refer to these:
// Deprecated - https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL
// Newer Syntax - https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/srcObject
video.srcObject = localMediaStream;
video.play();
})
.catch(err => {
console.error(`OH NO!!!`, err);
});
}
function paintToCanvas() {
const width = video.videoWidth;
const height = video.videoHeight;
canvas.width = width;
canvas.height = height;
return setInterval(() => {
ctx.drawImage(video, 0, 0, width, height);
// take the pixels out
let pixels = ctx.getImageData(0, 0, width, height);
// mess with them
// pixels = redEffect(pixels);
pixels = rgbSplit(pixels);
// ctx.globalAlpha = 0.8;
// pixels = greenScreen(pixels);
// put them back
ctx.putImageData(pixels, 0, 0);
}, 16);
}
function takePhoto() {
// played the sound
snap.currentTime = 0;
snap.play();
// take the data out of the canvas
const data = canvas.toDataURL('image/jpeg');
const link = document.createElement('a');
link.href = data;
link.setAttribute('download', 'handsome');
link.innerHTML = `<img src="${data}" alt="Handsome Man" />`;
strip.insertBefore(link, strip.firstChild);
}
function redEffect(pixels) {
for (let i = 0; i < pixels.data.length; i+=4) {
pixels.data[i + 0] = pixels.data[i + 0] + 200; // RED
pixels.data[i + 1] = pixels.data[i + 1] - 50; // GREEN
pixels.data[i + 2] = pixels.data[i + 2] * 0.5; // Blue
}
return pixels;
}
function rgbSplit(pixels) {
for (let i = 0; i < pixels.data.length; i+=4) {
pixels.data[i - 150] = pixels.data[i + 0]; // RED
pixels.data[i + 500] = pixels.data[i + 1]; // GREEN
pixels.data[i - 550] = pixels.data[i + 2]; // Blue
}
return pixels;
}
function greenScreen(pixels) {
const levels = {};
document.querySelectorAll('.rgb input').forEach((input) => {
levels[input.name] = input.value;
});
for (i = 0; i < pixels.data.length; i = i + 4) {
red = pixels.data[i + 0];
green = pixels.data[i + 1];
blue = pixels.data[i + 2];
alpha = pixels.data[i + 3];
if (red >= levels.rmin
&& green >= levels.gmin
&& blue >= levels.bmin
&& red <= levels.rmax
&& green <= levels.gmax
&& blue <= levels.bmax) {
// take it out!
pixels.data[i + 3] = 0;
}
}
return pixels;
}
getVideo();
video.addEventListener('canplay', paintToCanvas);
================================================
FILE: 19 - Webcam Fun/scripts.js
================================================
const video = document.querySelector('.player');
const canvas = document.querySelector('.photo');
const ctx = canvas.getContext('2d');
const strip = document.querySelector('.strip');
const snap = document.querySelector('.snap');
================================================
FILE: 19 - Webcam Fun/style.css
================================================
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
html {
font-size: 10px;
background: #ffc600;
}
.photobooth {
background: white;
max-width: 150rem;
margin: 2rem auto;
border-radius: 2px;
}
/*clearfix*/
.photobooth:after {
content: '';
display: block;
clear: both;
}
.photo {
width: 100%;
float: left;
}
.player {
position: absolute;
top: 20px;
right: 20px;
width:200px;
}
/*
Strip!
*/
.strip {
padding: 2rem;
}
.strip img {
width: 100px;
overflow-x: scroll;
padding: 0.8rem 0.8rem 2.5rem 0.8rem;
box-shadow: 0 0 3px rgba(0,0,0,0.2);
background: white;
}
.strip a:nth-child(5n+1) img { transform: rotate(10deg); }
.strip a:nth-child(5n+2) img { transform: rotate(-2deg); }
.strip a:nth-child(5n+3) img { transform: rotate(8deg); }
.strip a:nth-child(5n+4) img { transform: rotate(-11deg); }
.strip a:nth-child(5n+5) img { transform: rotate(12deg); }
================================================
FILE: 20 - Speech Detection/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Speech Detection</title>
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<div class="words" contenteditable>
</div>
<script>
window.SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
const recognition = new SpeechRecognition();
recognition.interimResults = true;
recognition.lang = 'en-US';
let p = document.createElement('p');
const words = document.querySelector('.words');
words.appendChild(p);
recognition.addEventListener('result', e => {
const transcript = Array.from(e.results)
.map(result => result[0])
.map(result => result.transcript)
.join('');
const poopScript = transcript.replace(/poop|poo|shit|dump/gi, '💩');
p.textContent = poopScript;
if (e.results[0].isFinal) {
p = document.createElement('p');
words.appendChild(p);
}
});
recognition.addEventListener('end', recognition.start);
recognition.start();
</script>
<style>
html {
font-size: 10px;
}
body {
background: #ffc600;
font-family: 'helvetica neue';
font-weight: 200;
font-size: 20px;
}
.words {
max-width: 500px;
margin: 50px auto;
background: white;
border-radius: 5px;
box-shadow: 10px 10px 0 rgba(0,0,0,0.1);
padding: 1rem 2rem 1rem 5rem;
background: -webkit-gradient(linear, 0 0, 0 100%, from(#d9eaf3), color-stop(4%, #fff)) 0 4px;
background-size: 100% 3rem;
position: relative;
line-height: 3rem;
}
p {
margin: 0 0 3rem;
}
.words:before {
content: '';
position: absolute;
width: 4px;
top: 0;
left: 30px;
bottom: 0;
border: 1px solid;
border-color: transparent #efe4e4;
}
</style>
</body>
</html>
================================================
FILE: 20 - Speech Detection/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Speech Detection</title>
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<div class="words" contenteditable>
</div>
<script>
window.SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
</script>
<style>
html {
font-size: 10px;
}
body {
background: #ffc600;
font-family: 'helvetica neue';
font-weight: 200;
font-size: 20px;
}
.words {
max-width: 500px;
margin: 50px auto;
background: white;
border-radius: 5px;
box-shadow: 10px 10px 0 rgba(0,0,0,0.1);
padding: 1rem 2rem 1rem 5rem;
background: -webkit-gradient(linear, 0 0, 0 100%, from(#d9eaf3), color-stop(4%, #fff)) 0 4px;
background-size: 100% 3rem;
position: relative;
line-height: 3rem;
}
p {
margin: 0 0 3rem;
}
.words:before {
content: '';
position: absolute;
width: 4px;
top: 0;
left: 30px;
bottom: 0;
border: 1px solid;
border-color: transparent #efe4e4;
}
</style>
</body>
</html>
================================================
FILE: 20 - Speech Detection/package.json
================================================
{
"name": "gum",
"version": "1.0.0",
"description": "",
"main": "scripts.js",
"scripts": {
"start": "browser-sync start --directory --server --files \"*.css, *.html, *.js\""
},
"author": "",
"license": "ISC",
"devDependencies": {
"browser-sync": "^2.12.5 <2.23.2"
}
}
================================================
FILE: 21 - Geolocation/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<meta name="viewport" content="width=device-width">
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<svg class="arrow" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve"><g><path fill="#ffffff" d="M32,1.824C15.361,1.824,1.825,15.361,1.825,32c0,16.639,13.537,30.176,30.175,30.176 S62.175,48.639,62.175,32C62.175,15.361,48.639,1.824,32,1.824z M29.715,3.988h1.12l2.333,3.807V3.988h1.069v5.701h-1.155 l-2.298-3.718v3.718h-1.069V3.988z M9.323,33.917H8.102l-1.136-4.262l-1.132,4.262H4.587l-1.361-5.701h1.178l0.859,3.916 l1.042-3.916h1.369l0.999,3.982l0.875-3.982h1.159L9.323,33.917z M33.995,59.828c-0.181,0.285-0.438,0.497-0.77,0.636 c-0.332,0.139-0.745,0.208-1.241,0.208c-0.721,0-1.274-0.167-1.661-0.5c-0.386-0.333-0.617-0.819-0.692-1.456l1.12-0.109 c0.067,0.376,0.204,0.652,0.41,0.828c0.206,0.176,0.484,0.264,0.834,0.264c0.371,0,0.65-0.078,0.838-0.235 c0.188-0.157,0.282-0.34,0.282-0.55c0-0.135-0.04-0.25-0.119-0.344c-0.079-0.095-0.217-0.177-0.414-0.247 c-0.135-0.047-0.442-0.13-0.922-0.249c-0.617-0.153-1.05-0.341-1.299-0.564c-0.35-0.314-0.525-0.696-0.525-1.147 c0-0.29,0.082-0.562,0.247-0.815c0.165-0.253,0.402-0.445,0.712-0.577c0.31-0.132,0.684-0.198,1.122-0.198 c0.716,0,1.254,0.157,1.616,0.471c0.362,0.314,0.552,0.733,0.57,1.256l-1.151,0.051c-0.049-0.293-0.155-0.504-0.317-0.632 c-0.162-0.128-0.405-0.193-0.729-0.193c-0.334,0-0.596,0.069-0.786,0.206c-0.122,0.088-0.183,0.206-0.183,0.354 c0,0.135,0.057,0.25,0.171,0.346c0.145,0.122,0.498,0.249,1.058,0.381c0.56,0.132,0.974,0.269,1.243,0.41 c0.268,0.141,0.478,0.334,0.63,0.58c0.152,0.245,0.227,0.548,0.227,0.908C34.267,59.237,34.176,59.543,33.995,59.828z M32,52.795 c-11.466,0-20.795-9.329-20.795-20.795c0-11.466,9.329-20.795,20.795-20.795S52.795,20.534,52.795,32 C52.795,43.466,43.466,52.795,32,52.795z M55.014,33.917v-5.701h4.227v0.965h-3.076v1.264h2.862v0.96h-2.862v1.552h3.185v0.961 H55.014z"/><g><path fill="#000000" d="M48.904,31.863c-4.074-1.358-8.148-2.717-12.226-4.066c-0.265-0.087-0.399-0.223-0.486-0.486 c-1.349-4.077-2.708-8.151-4.066-12.226c-0.029-0.087-0.074-0.169-0.132-0.3c-0.054,0.152-0.09,0.245-0.122,0.34 c-1.352,4.053-2.707,8.104-4.048,12.161c-0.096,0.292-0.246,0.428-0.532,0.522c-4.056,1.342-8.108,2.696-12.16,4.049 c-0.097,0.032-0.189,0.074-0.344,0.137c0.172,0.06,0.267,0.093,0.362,0.125c4.074,1.358,8.148,2.717,12.224,4.072 c0.204,0.068,0.337,0.158,0.412,0.386c1.243,3.757,2.498,7.511,3.75,11.265c0.144,0.432,0.291,0.862,0.463,1.373 c0.068-0.185,0.108-0.285,0.142-0.386c1.349-4.042,2.701-8.083,4.04-12.128c0.094-0.284,0.231-0.438,0.523-0.534 c4.056-1.341,8.108-2.696,12.161-4.048c0.099-0.033,0.195-0.076,0.347-0.137C49.067,31.925,48.987,31.891,48.904,31.863z M37.475,32.038c-1.316,0.439-2.631,0.879-3.947,1.314c-0.095,0.031-0.139,0.081-0.17,0.173c-0.434,1.313-0.873,2.625-1.311,3.937 c-0.012,0.033-0.024,0.066-0.046,0.126c-0.056-0.166-0.104-0.306-0.15-0.446c-0.407-1.219-0.814-2.437-1.218-3.657 c-0.025-0.074-0.068-0.104-0.134-0.125c-1.323-0.44-2.646-0.881-3.968-1.322c-0.031-0.01-0.062-0.022-0.118-0.041 c0.05-0.02,0.081-0.034,0.112-0.045c1.315-0.439,2.631-0.879,3.947-1.314c0.093-0.03,0.142-0.075,0.173-0.17 c0.435-1.316,0.875-2.632,1.314-3.947c0.01-0.031,0.022-0.062,0.039-0.11c0.019,0.042,0.033,0.069,0.043,0.097 c0.441,1.323,0.882,2.645,1.321,3.969c0.028,0.085,0.072,0.129,0.158,0.158c1.324,0.438,2.646,0.879,3.969,1.32 c0.027,0.009,0.053,0.02,0.1,0.038C37.538,32.013,37.507,32.027,37.475,32.038z"/><path fill="#000000" d="M24.436,27.633c-1.069-2.137-2.119-4.237-3.216-6.43c2.189,1.094,4.292,2.145,6.433,3.216 c-0.359,0.713-0.706,1.404-1.057,2.091c-0.023,0.045-0.078,0.082-0.127,0.106C25.807,26.949,25.143,27.28,24.436,27.633z"/><path fill="#000000" d="M39.573,27.632c-0.696-0.348-1.351-0.673-2.002-1.005c-0.076-0.038-0.155-0.104-0.193-0.177 c-0.338-0.661-0.666-1.326-1.019-2.033c2.121-1.061,4.228-2.115,6.43-3.217C41.69,23.399,40.635,25.509,39.573,27.632z"/><path fill="#000000" d="M24.436,36.339c0.712,0.357,1.394,0.698,2.074,1.043c0.046,0.024,0.088,0.073,0.113,0.121 c0.339,0.671,0.674,1.345,1.028,2.051c-2.126,1.063-4.232,2.117-6.43,3.216C22.317,40.577,23.37,38.472,24.436,36.339z"/><path fill="#000000" d="M36.358,39.555c0.354-0.707,0.688-1.38,1.028-2.05c0.028-0.056,0.084-0.111,0.14-0.139 c0.67-0.339,1.343-0.674,2.047-1.026c1.066,2.131,2.118,4.235,3.215,6.43C40.601,41.676,38.503,40.628,36.358,39.555z"/></g></g></svg>
<h1 class="speed">
<span class="speed-value">0</span>
<span class="units">KM/H</span>
</h1>
<style>
html {
font-size: 100px;
}
body {
margin: 0;
font-family: sans-serif;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background:
radial-gradient(black 15%, transparent 16%) 0 0,
radial-gradient(black 15%, transparent 16%) 8px 8px,
radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 0 1px,
radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 8px 9px;
background-color: #282828;
background-size: 16px 16px;
background-attachment: fixed;
}
.arrow {
width: 250px;
overflow: hidden;
transition: all 0.2s;
transform: rotate(0deg);
display: inline-block;
}
h1 {
color: white;
font-weight: 100;
font-size: 60px;
display: flex;
align-items: center;
}
.units {
font-size: 15px;
}
/*Compass: https://thenounproject.com/search/?q=compass&i=592352*/
</style>
<script>
const arrow = document.querySelector('.arrow');
const speed = document.querySelector('.speed-value');
navigator.geolocation.watchPosition((data) => {
console.log(data);
speed.textContent = data.coords.speed;
arrow.style.transform = `rotate(${data.coords.heading}deg)`;
}, (err) => {
console.error(err);
});
</script>
</body>
</html>
================================================
FILE: 21 - Geolocation/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<meta name="viewport" content="width=device-width">
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<svg class="arrow" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve"><g><path fill="#ffffff" d="M32,1.824C15.361,1.824,1.825,15.361,1.825,32c0,16.639,13.537,30.176,30.175,30.176 S62.175,48.639,62.175,32C62.175,15.361,48.639,1.824,32,1.824z M29.715,3.988h1.12l2.333,3.807V3.988h1.069v5.701h-1.155 l-2.298-3.718v3.718h-1.069V3.988z M9.323,33.917H8.102l-1.136-4.262l-1.132,4.262H4.587l-1.361-5.701h1.178l0.859,3.916 l1.042-3.916h1.369l0.999,3.982l0.875-3.982h1.159L9.323,33.917z M33.995,59.828c-0.181,0.285-0.438,0.497-0.77,0.636 c-0.332,0.139-0.745,0.208-1.241,0.208c-0.721,0-1.274-0.167-1.661-0.5c-0.386-0.333-0.617-0.819-0.692-1.456l1.12-0.109 c0.067,0.376,0.204,0.652,0.41,0.828c0.206,0.176,0.484,0.264,0.834,0.264c0.371,0,0.65-0.078,0.838-0.235 c0.188-0.157,0.282-0.34,0.282-0.55c0-0.135-0.04-0.25-0.119-0.344c-0.079-0.095-0.217-0.177-0.414-0.247 c-0.135-0.047-0.442-0.13-0.922-0.249c-0.617-0.153-1.05-0.341-1.299-0.564c-0.35-0.314-0.525-0.696-0.525-1.147 c0-0.29,0.082-0.562,0.247-0.815c0.165-0.253,0.402-0.445,0.712-0.577c0.31-0.132,0.684-0.198,1.122-0.198 c0.716,0,1.254,0.157,1.616,0.471c0.362,0.314,0.552,0.733,0.57,1.256l-1.151,0.051c-0.049-0.293-0.155-0.504-0.317-0.632 c-0.162-0.128-0.405-0.193-0.729-0.193c-0.334,0-0.596,0.069-0.786,0.206c-0.122,0.088-0.183,0.206-0.183,0.354 c0,0.135,0.057,0.25,0.171,0.346c0.145,0.122,0.498,0.249,1.058,0.381c0.56,0.132,0.974,0.269,1.243,0.41 c0.268,0.141,0.478,0.334,0.63,0.58c0.152,0.245,0.227,0.548,0.227,0.908C34.267,59.237,34.176,59.543,33.995,59.828z M32,52.795 c-11.466,0-20.795-9.329-20.795-20.795c0-11.466,9.329-20.795,20.795-20.795S52.795,20.534,52.795,32 C52.795,43.466,43.466,52.795,32,52.795z M55.014,33.917v-5.701h4.227v0.965h-3.076v1.264h2.862v0.96h-2.862v1.552h3.185v0.961 H55.014z"/><g><path fill="#000000" d="M48.904,31.863c-4.074-1.358-8.148-2.717-12.226-4.066c-0.265-0.087-0.399-0.223-0.486-0.486 c-1.349-4.077-2.708-8.151-4.066-12.226c-0.029-0.087-0.074-0.169-0.132-0.3c-0.054,0.152-0.09,0.245-0.122,0.34 c-1.352,4.053-2.707,8.104-4.048,12.161c-0.096,0.292-0.246,0.428-0.532,0.522c-4.056,1.342-8.108,2.696-12.16,4.049 c-0.097,0.032-0.189,0.074-0.344,0.137c0.172,0.06,0.267,0.093,0.362,0.125c4.074,1.358,8.148,2.717,12.224,4.072 c0.204,0.068,0.337,0.158,0.412,0.386c1.243,3.757,2.498,7.511,3.75,11.265c0.144,0.432,0.291,0.862,0.463,1.373 c0.068-0.185,0.108-0.285,0.142-0.386c1.349-4.042,2.701-8.083,4.04-12.128c0.094-0.284,0.231-0.438,0.523-0.534 c4.056-1.341,8.108-2.696,12.161-4.048c0.099-0.033,0.195-0.076,0.347-0.137C49.067,31.925,48.987,31.891,48.904,31.863z M37.475,32.038c-1.316,0.439-2.631,0.879-3.947,1.314c-0.095,0.031-0.139,0.081-0.17,0.173c-0.434,1.313-0.873,2.625-1.311,3.937 c-0.012,0.033-0.024,0.066-0.046,0.126c-0.056-0.166-0.104-0.306-0.15-0.446c-0.407-1.219-0.814-2.437-1.218-3.657 c-0.025-0.074-0.068-0.104-0.134-0.125c-1.323-0.44-2.646-0.881-3.968-1.322c-0.031-0.01-0.062-0.022-0.118-0.041 c0.05-0.02,0.081-0.034,0.112-0.045c1.315-0.439,2.631-0.879,3.947-1.314c0.093-0.03,0.142-0.075,0.173-0.17 c0.435-1.316,0.875-2.632,1.314-3.947c0.01-0.031,0.022-0.062,0.039-0.11c0.019,0.042,0.033,0.069,0.043,0.097 c0.441,1.323,0.882,2.645,1.321,3.969c0.028,0.085,0.072,0.129,0.158,0.158c1.324,0.438,2.646,0.879,3.969,1.32 c0.027,0.009,0.053,0.02,0.1,0.038C37.538,32.013,37.507,32.027,37.475,32.038z"/><path fill="#000000" d="M24.436,27.633c-1.069-2.137-2.119-4.237-3.216-6.43c2.189,1.094,4.292,2.145,6.433,3.216 c-0.359,0.713-0.706,1.404-1.057,2.091c-0.023,0.045-0.078,0.082-0.127,0.106C25.807,26.949,25.143,27.28,24.436,27.633z"/><path fill="#000000" d="M39.573,27.632c-0.696-0.348-1.351-0.673-2.002-1.005c-0.076-0.038-0.155-0.104-0.193-0.177 c-0.338-0.661-0.666-1.326-1.019-2.033c2.121-1.061,4.228-2.115,6.43-3.217C41.69,23.399,40.635,25.509,39.573,27.632z"/><path fill="#000000" d="M24.436,36.339c0.712,0.357,1.394,0.698,2.074,1.043c0.046,0.024,0.088,0.073,0.113,0.121 c0.339,0.671,0.674,1.345,1.028,2.051c-2.126,1.063-4.232,2.117-6.43,3.216C22.317,40.577,23.37,38.472,24.436,36.339z"/><path fill="#000000" d="M36.358,39.555c0.354-0.707,0.688-1.38,1.028-2.05c0.028-0.056,0.084-0.111,0.14-0.139 c0.67-0.339,1.343-0.674,2.047-1.026c1.066,2.131,2.118,4.235,3.215,6.43C40.601,41.676,38.503,40.628,36.358,39.555z"/></g></g></svg>
<h1 class="speed">
<span class="speed-value">0</span>
<span class="units">KM/H</span>
</h1>
<style>
html {
font-size: 100px;
}
body {
margin: 0;
font-family: sans-serif;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
background:
radial-gradient(black 15%, transparent 16%) 0 0,
radial-gradient(black 15%, transparent 16%) 8px 8px,
radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 0 1px,
radial-gradient(rgba(255,255,255,.1) 15%, transparent 20%) 8px 9px;
background-color: #282828;
background-size: 16px 16px;
background-attachment: fixed;
}
.arrow {
width: 250px;
overflow: hidden;
transition: all 0.2s;
transform: rotate(0deg);
display: inline-block;
}
h1 {
color: white;
font-weight: 100;
font-size: 60px;
display: flex;
align-items: center;
}
.units {
font-size: 15px;
}
/*Compass: https://thenounproject.com/search/?q=compass&i=592352*/
</style>
<script>
</script>
</body>
</html>
================================================
FILE: 21 - Geolocation/package.json
================================================
{
"name": "gum",
"version": "1.0.0",
"description": "",
"main": "scripts.js",
"scripts": {
"start": "browser-sync start --directory --server --files \"*.css, *.html, *.js\" --https"
},
"author": "",
"license": "ISC",
"devDependencies": {
"browser-sync": "^2.12.5 <2.23.2"
}
}
================================================
FILE: 22 - Follow Along Link Highlighter/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>👀👀👀Follow Along Nav</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<nav>
<ul class="menu">
<li><a href="">Home</a></li>
<li><a href="">Order Status</a></li>
<li><a href="">Tweets</a></li>
<li><a href="">Read Our History</a></li>
<li><a href="">Contact Us</a></li>
</ul>
</nav>
<div class="wrapper">
<p>Lorem ipsum dolor sit amet, <a href="">consectetur</a> adipisicing elit. Est <a href="">explicabo</a> unde natus necessitatibus esse obcaecati distinctio, aut itaque, qui vitae!</p>
<p>Aspernatur sapiente quae sint <a href="">soluta</a> modi, atque praesentium laborum pariatur earum <a href="">quaerat</a> cupiditate consequuntur facilis ullam dignissimos, aperiam quam veniam.</p>
<p>Cum ipsam quod, incidunt sit ex <a href="">tempore</a> placeat maxime <a href="">corrupti</a> possimus <a href="">veritatis</a> ipsum fugit recusandae est doloremque? Hic, <a href="">quibusdam</a>, nulla.</p>
<p>Esse quibusdam, ad, ducimus cupiditate <a href="">nulla</a>, quae magni odit <a href="">totam</a> ut consequatur eveniet sunt quam provident sapiente dicta neque quod.</p>
<p>Aliquam <a href="">dicta</a> sequi culpa fugiat <a href="">consequuntur</a> pariatur optio ad minima, maxime <a href="">odio</a>, distinctio magni impedit tempore enim repellendus <a href="">repudiandae</a> quas!</p>
</div>
<script>
const triggers = document.querySelectorAll('a');
const highlight = document.createElement('span');
highlight.classList.add('highlight');
document.body.appendChild(highlight);
function highlightLink() {
const linkCoords = this.getBoundingClientRect();
console.log(linkCoords);
const coords = {
width: linkCoords.width,
height: linkCoords.height,
top: linkCoords.top + window.scrollY,
left: linkCoords.left + window.scrollX
};
highlight.style.width = `${coords.width}px`;
highlight.style.height = `${coords.height}px`;
highlight.style.transform = `translate(${coords.left}px, ${coords.top}px)`;
}
triggers.forEach(a => a.addEventListener('mouseenter', highlightLink));
</script>
</body>
</html>
================================================
FILE: 22 - Follow Along Link Highlighter/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>👀👀👀Follow Along Nav</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<nav>
<ul class="menu">
<li><a href="">Home</a></li>
<li><a href="">Order Status</a></li>
<li><a href="">Tweets</a></li>
<li><a href="">Read Our History</a></li>
<li><a href="">Contact Us</a></li>
</ul>
</nav>
<div class="wrapper">
<p>Lorem ipsum dolor sit amet, <a href="">consectetur</a> adipisicing elit. Est <a href="">explicabo</a> unde natus necessitatibus esse obcaecati distinctio, aut itaque, qui vitae!</p>
<p>Aspernatur sapiente quae sint <a href="">soluta</a> modi, atque praesentium laborum pariatur earum <a href="">quaerat</a> cupiditate consequuntur facilis ullam dignissimos, aperiam quam veniam.</p>
<p>Cum ipsam quod, incidunt sit ex <a href="">tempore</a> placeat maxime <a href="">corrupti</a> possimus <a href="">veritatis</a> ipsum fugit recusandae est doloremque? Hic, <a href="">quibusdam</a>, nulla.</p>
<p>Esse quibusdam, ad, ducimus cupiditate <a href="">nulla</a>, quae magni odit <a href="">totam</a> ut consequatur eveniet sunt quam provident sapiente dicta neque quod.</p>
<p>Aliquam <a href="">dicta</a> sequi culpa fugiat <a href="">consequuntur</a> pariatur optio ad minima, maxime <a href="">odio</a>, distinctio magni impedit tempore enim repellendus <a href="">repudiandae</a> quas!</p>
</div>
<script>
// 👀👀👀👀👀👀👀👀👀👀👀👀👀👀👀
</script>
</body>
</html>
================================================
FILE: 22 - Follow Along Link Highlighter/style.css
================================================
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
min-height: 100vh;
margin: 0; /* Important! */
font-family: sans-serif;
background:
linear-gradient(45deg, hsla(340, 100%, 55%, 1) 0%, hsla(340, 100%, 55%, 0) 70%),
linear-gradient(135deg, hsla(225, 95%, 50%, 1) 10%, hsla(225, 95%, 50%, 0) 80%),
linear-gradient(225deg, hsla(140, 90%, 50%, 1) 10%, hsla(140, 90%, 50%, 0) 80%),
linear-gradient(315deg, hsla(35, 95%, 55%, 1) 100%, hsla(35, 95%, 55%, 0) 70%);
}
.wrapper {
margin: 0 auto;
max-width: 500px;
font-size: 20px;
line-height: 2;
position: relative;
}
a {
text-decoration: none;
color: black;
background: rgba(0,0,0,0.05);
border-radius: 20px;
}
.highlight {
transition: all 0.2s;
border-bottom: 2px solid white;
position: absolute;
top: 0;
background: white;
left: 0;
z-index: -1;
border-radius: 20px;
display: block;
box-shadow: 0 0 10px rgba(0,0,0,0.2);
}
.menu {
padding: 0;
display: flex;
list-style: none;
justify-content: center;
margin:100px 0;
}
.menu a {
display: inline-block;
padding: 5px;
margin: 0 20px;
color: black;
}
================================================
FILE: 23 - Speech Synthesis/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Speech Synthesis</title>
<link href='https://fonts.googleapis.com/css?family=Pacifico' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<div class="voiceinator">
<h1>The Voiceinator 5000</h1>
<select name="voice" id="voices">
<option value="">Select A Voice</option>
</select>
<label for="rate">Rate:</label>
<input name="rate" type="range" min="0" max="3" value="1" step="0.1">
<label for="pitch">Pitch:</label>
<input name="pitch" type="range" min="0" max="2" step="0.1">
<textarea name="text">Hello! I love JavaScript 👍</textarea>
<button id="stop">Stop!</button>
<button id="speak">Speak</button>
</div>
<script>
const msg = new SpeechSynthesisUtterance();
let voices = [];
const voicesDropdown = document.querySelector('[name="voice"]');
const options = document.querySelectorAll('[type="range"], [name="text"]');
const speakButton = document.querySelector('#speak');
const stopButton = document.querySelector('#stop');
msg.text = document.querySelector('[name="text"]').value;
function populateVoices() {
voices = this.getVoices();
voicesDropdown.innerHTML = voices
.filter(voice => voice.lang.includes('en'))
.map(voice => `<option value="${voice.name}">${voice.name} (${voice.lang})</option>`)
.join('');
}
function setVoice() {
msg.voice = voices.find(voice => voice.name === this.value);
toggle();
}
function toggle(startOver = true) {
speechSynthesis.cancel();
if (startOver) {
speechSynthesis.speak(msg);
}
}
function setOption() {
console.log(this.name, this.value);
msg[this.name] = this.value;
toggle();
}
speechSynthesis.addEventListener('voiceschanged', populateVoices);
voicesDropdown.addEventListener('change', setVoice);
options.forEach(option => option.addEventListener('change', setOption));
speakButton.addEventListener('click', toggle);
stopButton.addEventListener('click', () => toggle(false));
</script>
</body>
</html>
================================================
FILE: 23 - Speech Synthesis/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Speech Synthesis</title>
<link href='https://fonts.googleapis.com/css?family=Pacifico' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<div class="voiceinator">
<h1>The Voiceinator 5000</h1>
<select name="voice" id="voices">
<option value="">Select A Voice</option>
</select>
<label for="rate">Rate:</label>
<input name="rate" type="range" min="0" max="3" value="1" step="0.1">
<label for="pitch">Pitch:</label>
<input name="pitch" type="range" min="0" max="2" step="0.1">
<textarea name="text">Hello! I love JavaScript 👍</textarea>
<button id="stop">Stop!</button>
<button id="speak">Speak</button>
</div>
<script>
const msg = new SpeechSynthesisUtterance();
let voices = [];
const voicesDropdown = document.querySelector('[name="voice"]');
const options = document.querySelectorAll('[type="range"], [name="text"]');
const speakButton = document.querySelector('#speak');
const stopButton = document.querySelector('#stop');
</script>
</body>
</html>
================================================
FILE: 23 - Speech Synthesis/style.css
================================================
html {
font-size: 10px;
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
margin: 0;
padding: 0;
font-family: sans-serif;
background-color: #3BC1AC;
display: flex;
min-height: 100vh;
align-items: center;
background-image:
radial-gradient(circle at 100% 150%, #3BC1AC 24%, #42D2BB 25%, #42D2BB 28%, #3BC1AC 29%, #3BC1AC 36%, #42D2BB 36%, #42D2BB 40%, transparent 40%, transparent),
radial-gradient(circle at 0 150%, #3BC1AC 24%, #42D2BB 25%, #42D2BB 28%, #3BC1AC 29%, #3BC1AC 36%, #42D2BB 36%, #42D2BB 40%, transparent 40%, transparent),
radial-gradient(circle at 50% 100%, #42D2BB 10%, #3BC1AC 11%, #3BC1AC 23%, #42D2BB 24%, #42D2BB 30%, #3BC1AC 31%, #3BC1AC 43%, #42D2BB 44%, #42D2BB 50%, #3BC1AC 51%, #3BC1AC 63%, #42D2BB 64%, #42D2BB 71%, transparent 71%, transparent),
radial-gradient(circle at 100% 50%, #42D2BB 5%, #3BC1AC 6%, #3BC1AC 15%, #42D2BB 16%, #42D2BB 20%, #3BC1AC 21%, #3BC1AC 30%, #42D2BB 31%, #42D2BB 35%, #3BC1AC 36%, #3BC1AC 45%, #42D2BB 46%, #42D2BB 49%, transparent 50%, transparent),
radial-gradient(circle at 0 50%, #42D2BB 5%, #3BC1AC 6%, #3BC1AC 15%, #42D2BB 16%, #42D2BB 20%, #3BC1AC 21%, #3BC1AC 30%, #42D2BB 31%, #42D2BB 35%, #3BC1AC 36%, #3BC1AC 45%, #42D2BB 46%, #42D2BB 49%, transparent 50%, transparent);
background-size:100px 50px;
}
.voiceinator {
padding: 2rem;
width: 50rem;
margin: 0 auto;
border-radius: 1rem;
position: relative;
background: white;
overflow: hidden;
z-index: 1;
box-shadow: 0 0 5px 5px rgba(0,0,0,0.1);
}
h1 {
width: calc(100% + 4rem);
margin: -2rem 0 2rem -2rem;
padding: .5rem;
background: #ffc600;
border-bottom: 5px solid #F3C010;
text-align: center;
font-size: 5rem;
font-weight: 100;
font-family: 'Pacifico', cursive;
text-shadow: 3px 3px 0 #F3C010;
}
.voiceinator input,
.voiceinator button,
.voiceinator select,
.voiceinator textarea {
width: 100%;
display: block;
margin: 10px 0;
padding: 10px;
border: 0;
font-size: 2rem;
background: #F7F7F7;
outline: 0;
}
textarea {
height: 20rem;
}
.voiceinator button {
background: #ffc600;
border: 0;
width: 49%;
float: left;
font-family: 'Pacifico', cursive;
margin-bottom: 0;
font-size: 2rem;
border-bottom: 5px solid #F3C010;
cursor: pointer;
position: relative;
}
.voiceinator button:active {
top: 2px;
}
.voiceinator button:nth-of-type(1) {
margin-right: 2%;
}
================================================
FILE: 24 - Sticky Nav/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="style-FINISHED.css">
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<header>
<h1>A story about getting lost.</h1>
</header>
<nav id="main">
<ul>
<li class="logo"><a href="#">LOST.</a></li>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Images</a></li>
<li><a href="#">Locations</a></li>
<li><a href="#">Maps</a></li>
</ul>
</nav>
<div class="site-wrap">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<img src="http://unsplash.it/400/400" class="align-left slide-in">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates, deserunt facilis et iste corrupti omnis tenetur est. Iste ut est dicta dolor itaque adipisci, dolorum minima, veritatis earum provident error molestias. Ratione magni illo sint vel velit ut excepturi consectetur suscipit, earum modi accusamus voluptatem nostrum, praesentium numquam, reiciendis voluptas sit id quisquam. Consequatur in quis reprehenderit modi perspiciatis necessitatibus saepe, quidem, suscipit iure natus dignissimos ipsam, eligendi deleniti accusantium, rerum quibusdam fugit perferendis et optio recusandae sed ratione. Culpa, dolorum reprehenderit harum ab voluptas fuga, nisi eligendi natus maiores illum quas quos et aperiam aut doloremque optio maxime fugiat doloribus. Eum dolorum expedita quam, nesciunt</p>
<img src="http://unsplash.it/400/400" class="align-right slide-in">
<p> at provident praesentium atque quas rerum optio dignissimos repudiandae ullam illum quibusdam. Vel ad error quibusdam, illo ex totam placeat. Quos excepturi fuga, molestiae ea quisquam minus, ratione dicta consectetur officia omnis, doloribus voluptatibus? Veniam ipsum veritatis architecto, provident quas consequatur doloremque quam quidem earum expedita, ad delectus voluptatum, omnis praesentium nostrum qui aspernatur ea eaque adipisci et cumque ab? Ea voluptatum dolore itaque odio. Eius minima distinctio harum, officia ab nihil exercitationem. Tempora rem nemo nam temporibus molestias facilis minus ipsam quam doloribus consequatur debitis nesciunt tempore officiis aperiam quisquam, molestiae voluptates cum, fuga culpa. Distinctio accusamus quibusdam, tempore perspiciatis dolorum optio facere consequatur quidem ullam beatae architecto, ipsam sequi officiis dignissimos amet impedit natus necessitatibus tenetur repellendus dolor rem! Dicta dolorem, iure, facilis illo ex nihil ipsa amet officia, optio temporibus eum autem odit repellendus nisi. Possimus modi, corrupti error debitis doloribus dicta libero earum, sequi porro ut excepturi nostrum ea voluptatem nihil culpa? Ullam expedita eligendi obcaecati reiciendis velit provident omnis quas qui in corrupti est dolore facere ad hic, animi soluta assumenda consequuntur reprehenderit! Voluptate dolor nihil veniam laborum voluptas nisi pariatur sed optio accusantium quam consectetur, corrupti, sequi et consequuntur, excepturi doloremque. Tempore quis velit corporis neque fugit non sequi eaque rem hic. Facere, inventore, aspernatur. Accusantium modi atque, asperiores qui nobis soluta cumque suscipit excepturi possimus doloremque odit saepe perferendis temporibus molestiae nostrum voluptatum quis id sint quidem nesciunt culpa. Rerum labore dolor beatae blanditiis praesentium explicabo velit optio esse aperiam similique, voluptatem cum, maiores ipsa tempore. Reiciendis sed culpa atque inventore, nam ullam enim expedita consectetur id velit iusto alias vitae explicabo nemo neque odio reprehenderit soluta sint eaque. Aperiam, qui ut tenetur, voluptate doloremque officiis dicta quaerat voluptatem rerum natus magni. Eum amet autem dolor ullam.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>
<img src="http://unsplash.it/400/400" class="align-right slide-in">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>
</div>
<script>
// Not a ton of code, but hard to
const nav = document.querySelector('#main');
let topOfNav = nav.offsetTop;
function fixNav() {
if (window.scrollY >= topOfNav) {
document.body.style.paddingTop = nav.offsetHeight + 'px';
document.body.classList.add('fixed-nav');
} else {
document.body.classList.remove('fixed-nav');
document.body.style.paddingTop = 0;
}
}
window.addEventListener('scroll', fixNav);
</script>
</body>
</html>
================================================
FILE: 24 - Sticky Nav/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sticky Nav</title>
<link rel="stylesheet" href="style-START.css">
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<header>
<h1>A story about getting lost.</h1>
</header>
<nav id="main">
<ul>
<li class="logo"><a href="#">LOST.</a></li>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Images</a></li>
<li><a href="#">Locations</a></li>
<li><a href="#">Maps</a></li>
</ul>
</nav>
<div class="site-wrap">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Tempore tempora rerum, est autem cupiditate, corporis a qui libero ipsum delectus quidem dolor at nulla, adipisci veniam in reiciendis aut asperiores omnis blanditiis quod quas laborum nam! Fuga ad tempora in aspernatur pariatur fugit quibusdam dolores sunt esse magni, ut, dignissimos.</p>
<img src="http://unsplash.it/400/400" class="align-left slide-in">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptates, deserunt facilis et iste corrupti omnis tenetur est. Iste ut est dicta dolor itaque adipisci, dolorum minima, veritatis earum provident error molestias. Ratione magni illo sint vel velit ut excepturi consectetur suscipit, earum modi accusamus voluptatem nostrum, praesentium numquam, reiciendis voluptas sit id quisquam. Consequatur in quis reprehenderit modi perspiciatis necessitatibus saepe, quidem, suscipit iure natus dignissimos ipsam, eligendi deleniti accusantium, rerum quibusdam fugit perferendis et optio recusandae sed ratione. Culpa, dolorum reprehenderit harum ab voluptas fuga, nisi eligendi natus maiores illum quas quos et aperiam aut doloremque optio maxime fugiat doloribus. Eum dolorum expedita quam, nesciunt</p>
<img src="http://unsplash.it/400/400" class="align-right slide-in">
<p> at provident praesentium atque quas rerum optio dignissimos repudiandae ullam illum quibusdam. Vel ad error quibusdam, illo ex totam placeat. Quos excepturi fuga, molestiae ea quisquam minus, ratione dicta consectetur officia omnis, doloribus voluptatibus? Veniam ipsum veritatis architecto, provident quas consequatur doloremque quam quidem earum expedita, ad delectus voluptatum, omnis praesentium nostrum qui aspernatur ea eaque adipisci et cumque ab? Ea voluptatum dolore itaque odio. Eius minima distinctio harum, officia ab nihil exercitationem. Tempora rem nemo nam temporibus molestias facilis minus ipsam quam doloribus consequatur debitis nesciunt tempore officiis aperiam quisquam, molestiae voluptates cum, fuga culpa. Distinctio accusamus quibusdam, tempore perspiciatis dolorum optio facere consequatur quidem ullam beatae architecto, ipsam sequi officiis dignissimos amet impedit natus necessitatibus tenetur repellendus dolor rem! Dicta dolorem, iure, facilis illo ex nihil ipsa amet officia, optio temporibus eum autem odit repellendus nisi. Possimus modi, corrupti error debitis doloribus dicta libero earum, sequi porro ut excepturi nostrum ea voluptatem nihil culpa? Ullam expedita eligendi obcaecati reiciendis velit provident omnis quas qui in corrupti est dolore facere ad hic, animi soluta assumenda consequuntur reprehenderit! Voluptate dolor nihil veniam laborum voluptas nisi pariatur sed optio accusantium quam consectetur, corrupti, sequi et consequuntur, excepturi doloremque. Tempore quis velit corporis neque fugit non sequi eaque rem hic. Facere, inventore, aspernatur. Accusantium modi atque, asperiores qui nobis soluta cumque suscipit excepturi possimus doloremque odit saepe perferendis temporibus molestiae nostrum voluptatum quis id sint quidem nesciunt culpa. Rerum labore dolor beatae blanditiis praesentium explicabo velit optio esse aperiam similique, voluptatem cum, maiores ipsa tempore. Reiciendis sed culpa atque inventore, nam ullam enim expedita consectetur id velit iusto alias vitae explicabo nemo neque odio reprehenderit soluta sint eaque. Aperiam, qui ut tenetur, voluptate doloremque officiis dicta quaerat voluptatem rerum natus magni. Eum amet autem dolor ullam.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>
<img src="http://unsplash.it/400/400" class="align-right slide-in">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Distinctio maiores adipisci quibusdam repudiandae dolor vero placeat esse sit! Quibusdam saepe aperiam explicabo placeat optio, consequuntur nihil voluptatibus expedita quia vero perferendis, deserunt et incidunt eveniet temporibus doloremque possimus facilis. Possimus labore, officia dolore! Eaque ratione saepe, alias harum laboriosam deserunt laudantium blanditiis eum explicabo placeat reiciendis labore iste sint. Consectetur expedita dignissimos, non quos distinctio, eos rerum facilis eligendi. Asperiores laudantium, rerum ratione consequatur, culpa consectetur possimus atque ab tempore illum non dolor nesciunt. Neque, rerum. A vel non incidunt, quod doloremque dignissimos necessitatibus aliquid laboriosam architecto at cupiditate commodi expedita in, quae blanditiis. Deserunt labore sequi, repellat laboriosam est, doloremque culpa reiciendis tempore excepturi. Enim nostrum fugit itaque vel corporis ullam sed tenetur ipsa qui rem quam error sint, libero. Laboriosam rem, ratione. Autem blanditiis laborum neque repudiandae quam, cumque, voluptate veritatis itaque, placeat veniam ad nisi. Expedita, laborum reprehenderit ratione soluta velit natus, odit mollitia. Corporis rerum minima fugiat in nostrum. Assumenda natus cupiditate hic quidem ex, quas, amet ipsum esse dolore facilis beatae maxime qui inventore, iste? Maiores dignissimos dolore culpa debitis voluptatem harum, excepturi enim reiciendis, tempora ab ipsam illum aspernatur quasi qui porro saepe iure sunt eligendi tenetur quaerat ducimus quas sequi omnis aperiam suscipit! Molestiae obcaecati officiis quo, ratione eveniet, provident pariatur. Veniam quasi expedita distinctio, itaque molestiae sequi, dolorum nisi repellendus quia facilis iusto dignissimos nam? Tenetur fugit quos autem nihil, perspiciatis expedita enim tempore, alias ab maiores quis necessitatibus distinctio molestias eum, quidem. Delectus impedit quidem laborum, fugit vel neque quo, ipsam, quasi aspernatur quas odio nihil? Veniam amet reiciendis blanditiis quis reprehenderit repudiandae neque, ab ducimus, odit excepturi voluptate saepe ipsam. Voluptatem eum error voluptas porro officiis, amet! Molestias, fugit, ut! Tempore non magnam, amet, facere ducimus accusantium eos veritatis neque.</p>
</div>
<script>
</script>
</body>
</html>
================================================
FILE: 24 - Sticky Nav/style-FINISHED.css
================================================
html {
box-sizing: border-box;
background: #eeeeee;
font-family: 'helvetica neue';
font-size: 20px;
font-weight: 200;
}
body {
margin: 0;
}
*, *:before, *:after {
box-sizing: inherit;
}
.site-wrap {
max-width: 700px;
margin: 70px auto;
background: white;
padding: 40px;
text-align: justify;
box-shadow: 0 0 10px 5px rgba(0, 0, 0, 0.05);
transform: scale(0.98);
transition: transform 0.5s;
}
body.fixed-nav .site-wrap {
transform: scale(1);
}
header {
text-align: center;
height: 50vh;
background: url(https://source.unsplash.com/GKN6rpDr0EI/960x640) bottom center no-repeat;
background-size: cover;
display: flex;
align-items: center;
justify-content: center;
}
h1 {
color: white;
font-size: 7vw;
text-shadow: 3px 4px 0 rgba(0,0,0,0.2);
}
nav {
background: black;
top: 0;
width: 100%;
transition:all 0.5s;
position: relative;
z-index: 1;
}
body.fixed-nav nav {
position: fixed;
box-shadow: 0 5px 0 rgba(0,0,0,0.1);
}
nav ul {
margin: 0;
padding: 0;
list-style: none;
display: flex;
}
nav li {
flex: 1;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
li.logo {
max-width: 0;
overflow: hidden;
background: white;
transition: all 0.5s;
font-weight: 600;
font-size: 30px;
}
li.logo a {
color: black;
}
.fixed-nav li.logo {
max-width: 500px;
}
nav a {
text-decoration: none;
padding: 20px;
display: inline-block;
color: white;
transition: all 0.2s;
text-transform: uppercase;
}
================================================
FILE: 24 - Sticky Nav/style-START.css
================================================
html {
box-sizing: border-box;
background: #eeeeee;
font-family: 'helvetica neue';
font-size: 20px;
font-weight: 200;
}
body {
margin: 0;
}
*, *:before, *:after {
box-sizing: inherit;
}
.site-wrap {
max-width: 700px;
margin: 70px auto;
background: white;
padding: 40px;
text-align: justify;
box-shadow: 0 0 10px 5px rgba(0, 0, 0, 0.05);
transform: scale(0.98);
transition: transform 0.5s;
}
header {
text-align: center;
height: 50vh;
background: url(https://source.unsplash.com/GKN6rpDr0EI/960x640) bottom center no-repeat;
background-size: cover;
display: flex;
align-items: center;
justify-content: center;
}
h1 {
color: white;
font-size: 7vw;
text-shadow: 3px 4px 0 rgba(0,0,0,0.2);
}
nav {
background: black;
top: 0;
width: 100%;
transition: all 0.5s;
position: relative;
z-index: 1;
}
nav ul {
margin: 0;
padding:0;
list-style: none;
display: flex;
}
nav li {
flex: 1;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
li.logo {
max-width: 0;
overflow: hidden;
background: white;
transition: all .5s;
font-weight: 600;
font-size: 30px;
}
li.logo a {
color: black;
}
nav a {
text-decoration: none;
padding: 20px;
display: inline-block;
color: white;
transition: all 0.2s;
text-transform: uppercase;
}
================================================
FILE: 25 - Event Capture, Propagation, Bubbling and Once/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Understanding JavaScript's Capture</title>
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body class="bod">
<div class="one">
<div class="two">
<div class="three">
</div>
</div>
</div>
<style>
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
div {
width: 100%;
padding: 100px;
}
.one {
background: thistle;
}
.two {
background: mistyrose;
}
.three {
background: coral;
}
</style>
<button></button>
<script>
const divs = document.querySelectorAll('div');
const button = document.querySelector('button');
function logText(e) {
console.log(this.classList.value);
// e.stopPropagation(); // stop bubbling!
// console.log(this);
}
divs.forEach(div => div.addEventListener('click', logText, {
capture: false,
once: true
}));
button.addEventListener('click', () => {
console.log('Click!!!');
}, {
once: true
});
</script>
</body>
</html>
================================================
FILE: 25 - Event Capture, Propagation, Bubbling and Once/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Understanding JavaScript's Capture</title>
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body class="bod">
<div class="one">
<div class="two">
<div class="three">
</div>
</div>
</div>
<style>
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
div {
width: 100%;
padding: 100px;
}
.one {
background: thistle;
}
.two {
background: mistyrose;
}
.three {
background: coral;
}
</style>
<button></button>
<script>
</script>
</body>
</html>
================================================
FILE: 26 - Stripe Follow Along Nav/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Follow Along Nav</title>
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<h2>Cool</h2>
<nav class="top">
<div class="dropdownBackground">
<span class="arrow"></span>
</div>
<ul class="cool">
<li>
<a href="#">About Me</a>
<div class="dropdown dropdown1">
<div class="bio">
<img src="https://logo.clearbit.com/wesbos.com">
<p>Wes Bos sure does love web development. He teaches things like JavaScript, CSS and BBQ. Wait. BBQ isn't part of web development. It should be though!</p>
</div>
</div>
</li>
<li>
<a href="#">Courses</a>
<ul class="dropdown courses">
<li>
<span class="code">RFB</span>
<a href="https://ReactForBeginners.com">React For Beginners</a>
</li>
<li>
<span class="code">ES6</span>
<a href="https://ES6.io">ES6 For Everyone</a>
</li>
<li>
<span class="code">NODE</span>
<a href="https://LearnNode.com">Learn Node</a>
</li>
<li>
<span class="code">STPU</span>
<a href="https://SublimeTextBook.com">Sublime Text Power User</a>
</li>
<li>
<span class="code">WTF</span>
<a href="http://Flexbox.io">What The Flexbox?!</a>
</li>
<li>
<span class="code">GRID</span>
<a href="https://CSSGrid.io">CSS Grid</a>
</li>
<li>
<span class="code">LRX</span>
<a href="http://LearnRedux.com">Learn Redux</a>
</li>
<li>
<span class="code">CLPU</span>
<a href="http://CommandLinePowerUser.com">Command Line Power User</a>
</li>
<li>
<span class="code">MMD</span>
<a href="http://MasteringMarkdown.com">Mastering Markdown</a>
</li>
</ul>
</li>
<li>
<a href="#">Other Links</a>
<ul class="dropdown dropdown3">
<li><a class="button" href="http://twitter.com/wesbos">Twitter</a></li>
<li><a class="button" href="http://facebook.com/wesbos.developer">Facebook</a></li>
<li><a class="button" href="http://wesbos.com">Blog</a></li>
<li><a class="button" href="http://wesbos.com/courses">Course Catalog</a></li>
</ul>
</li>
</ul>
</nav>
<style>
html {
box-sizing: border-box;
font-family: "Arial Rounded MT Bold", "Helvetica Rounded", Arial, sans-serif;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
margin: 0;
min-height: 100vh;
background:
linear-gradient(45deg, hsla(340, 100%, 55%, 1) 0%, hsla(340, 100%, 55%, 0) 70%),
linear-gradient(135deg, hsla(225, 95%, 50%, 1) 10%, hsla(225, 95%, 50%, 0) 80%),
linear-gradient(225deg, hsla(140, 90%, 50%, 1) 10%, hsla(140, 90%, 50%, 0) 80%),
linear-gradient(315deg, hsla(35, 95%, 55%, 1) 100%, hsla(35, 95%, 55%, 0) 70%);
}
h2 {
margin-top: 0;
padding-top: .8em;
}
nav {
position: relative;
perspective: 600px;
}
.cool > li > a {
color: yellow;
text-decoration: none;
font-size: 20px;
background: rgba(0,0,0,0.2);
padding: 10px 20px;
display: inline-block;
margin: 20px;
border-radius: 5px;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
}
.cool > li {
position: relative;
display: flex;
justify-content: center;
}
.dropdown {
opacity: 0;
position: absolute;
overflow: hidden;
padding: 20px;
top: -20px;
border-radius: 2px;
transition: all 0.5s;
transform: translateY(100px);
will-change: opacity;
display: none;
}
.trigger-enter .dropdown {
display: block;
}
.trigger-enter-active .dropdown {
opacity: 1;
}
.dropdownBackground {
width: 100px;
height: 100px;
position: absolute;
background: #fff;
border-radius: 4px;
box-shadow: 0 50px 100px rgba(50,50,93,.1), 0 15px 35px rgba(50,50,93,.15), 0 5px 15px rgba(0,0,0,.1);
transition: all 0.3s, opacity 0.1s, transform 0.2s;
transform-origin: 50% 0;
display: flex;
justify-content: center;
opacity: 0;
}
.dropdownBackground.open {
opacity: 1;
}
.arrow {
position: absolute;
width: 20px;
height: 20px;
display: block;
background: white;
transform: translateY(-50%) rotate(45deg);
}
.bio {
min-width: 500px;
display: flex;
justify-content: center;
align-items: center;
line-height: 1.7;
}
.bio img {
float: left;
margin-right: 20px;
}
.courses {
min-width: 300px;
}
.courses li {
padding: 10px 0;
display: block;
border-bottom: 1px solid rgba(0,0,0,0.2);
}
.dropdown a {
text-decoration: none;
color: #ffc600;
}
a.button {
background: black;
display: block;
padding: 10px;
color: white;
margin-bottom: 10px;
}
/* Matches Twitter, TWITTER, twitter, tWitter, TWiTTeR... */
.button[href*=twitter] { background: #019FE9; }
.button[href*=facebook] { background: #3B5998; }
.button[href*=courses] { background: #ffc600; }
</style>
<script>
const triggers = document.querySelectorAll('.cool > li');
const background = document.querySelector('.dropdownBackground');
const nav = document.querySelector('.top');
function handleEnter() {
this.classList.add('trigger-enter');
setTimeout(() => this.classList.contains('trigger-enter') && this.classList.add('trigger-enter-active'), 150);
background.classList.add('open');
const dropdown = this.querySelector('.dropdown');
const dropdownCoords = dropdown.getBoundingClientRect();
const navCoords = nav.getBoundingClientRect();
const coords = {
height: dropdownCoords.height,
width: dropdownCoords.width,
top: dropdownCoords.top - navCoords.top,
left: dropdownCoords.left - navCoords.left
};
background.style.setProperty('width', `${coords.width}px`);
background.style.setProperty('height', `${coords.height}px`);
background.style.setProperty('transform', `translate(${coords.left}px, ${coords.top}px)`);
}
function handleLeave() {
this.classList.remove('trigger-enter', 'trigger-enter-active');
background.classList.remove('open');
}
triggers.forEach(trigger => trigger.addEventListener('mouseenter', handleEnter));
triggers.forEach(trigger => trigger.addEventListener('mouseleave', handleLeave));
</script>
</body>
</html>
================================================
FILE: 26 - Stripe Follow Along Nav/index-START.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Follow Along Nav</title>
<link rel="icon" href="https://fav.farm/🔥" />
</head>
<body>
<h2>Cool</h2>
<nav class="top">
<div class="dropdownBackground">
<span class="arrow"></span>
</div>
<ul class="cool">
<li>
<a href="#">About Me</a>
<div class="dropdown dropdown1">
<div class="bio">
<img src="https://logo.clearbit.com/wesbos.com">
<p>Wes Bos sure does love web development. He teaches things like JavaScript, CSS and BBQ. Wait. BBQ isn't part of web development. It should be though!</p>
</div>
</div>
</li>
<li>
<a href="#">Courses</a>
<ul class="dropdown courses">
<li>
<span class="code">RFB</span>
<a href="https://ReactForBeginners.com">React For Beginners</a>
</li>
<li>
<span class="code">ES6</span>
<a href="https://ES6.io">ES6 For Everyone</a>
</li>
<li>
<span class="code">NODE</span>
<a href="https://LearnNode.com">Learn Node</a>
</li>
<li>
<span class="code">STPU</span>
<a href="https://SublimeTextBook.com">Sublime Text Power User</a>
</li>
<li>
<span class="code">WTF</span>
<a href="http://Flexbox.io">What The Flexbox?!</a>
</li>
<li>
<span class="code">GRID</span>
<a href="https://CSSGrid.io">CSS Grid</a>
</li>
<li>
<span class="code">LRX</span>
<a href="http://LearnRedux.com">Learn Redux</a>
</li>
<li>
<span class="code">CLPU</span>
<a href="http://CommandLinePowerUser.com">Command Line Power User</a>
</li>
<li>
<span class="code">MMD</span>
<a href="http://MasteringMarkdown.com">Mastering Markdown</a>
</li>
</ul>
</li>
<li>
<a href="#">Other Links</a>
<ul class="dropdown dropdown3">
<li><a class="button" href="http://twitter.com/wesbos">Twitter</a></li>
<li><a class="button" href="http://facebook.com/wesbos.developer">Facebook</a></li>
<li><a class="button" href="http://wesbos.com">Blog</a></li>
<li><a class="button" href="http://wesbos.com/courses">Course Catalog</a></li>
</ul>
</li>
</ul>
</nav>
<style>
html {
box-sizing: border-box;
font-family: "Arial Rounded MT Bold", "Helvetica Rounded", Arial, sans-serif;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
margin: 0;
min-height: 100vh;
background:
linear-gradient(45deg, hsla(340, 100%, 55%, 1) 0%, hsla(340, 100%, 55%, 0) 70%),
linear-gradient(135deg, hsla(225, 95%, 50%, 1) 10%, hsla(225, 95%, 50%, 0) 80%),
linear-gradient(225deg, hsla(140, 90%, 50%, 1) 10%, hsla(140, 90%, 50%, 0) 80%),
linear-gradient(315deg, hsla(35, 95%, 55%, 1) 100%, hsla(35, 95%, 55%, 0) 70%);
}
h2 {
margin-top: 0;
padding-top: .8em;
}
nav {
position: relative;
perspective: 600px;
}
.cool > li > a {
color: yellow;
text-decoration: none;
font-size: 20px;
background: rgba(0,0,0,0.2);
padding: 10px 20px;
display: inline-block;
margin: 20px;
border-radius: 5px;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
}
.cool > li {
position: relative;
display: flex;
justify-content: center;
}
.dropdown {
opacity: 0;
position: absolute;
overflow: hidden;
padding: 20px;
top: -20px;
border-radius: 2px;
transition: all 0.5s;
transform: translateY(100px);
will-change: opacity;
display: none;
}
.trigger-enter .dropdown {
display: block;
}
.trigger-enter-active .dropdown {
opacity: 1;
}
.dropdownBackground {
width: 100px;
height: 100px;
position: absolute;
background: #fff;
border-radius: 4px;
box-shadow: 0 50px 100px rgba(50,50,93,.1), 0 15px 35px rgba(50,50,93,.15), 0 5px 15px rgba(0,0,0,.1);
transition: all 0.3s, opacity 0.1s, transform 0.2s;
transform-origin: 50% 0;
display: flex;
justify-content: center;
opacity:0;
}
.dropdownBackground.open {
opacity: 1;
}
.arrow {
position: absolute;
width: 20px;
height: 20px;
display: block;
background: white;
transform: translateY(-50%) rotate(45deg);
}
.bio {
min-width: 500px;
display: flex;
justify-content: center;
align-items: center;
line-height: 1.7;
}
.bio img {
float: left;
margin-right: 20px;
}
.courses {
min-width: 300px;
}
.courses li {
padding: 10px 0;
display: block;
border-bottom: 1px solid rgba(0,0,0,0.2);
}
.dropdown a {
text-decoration: none;
color: #ffc600;
}
a.button {
background: black;
display: block;
padding: 10px;
color: white;
margin-bottom: 10px;
}
/* Matches Twitter, TWITTER, twitter, tWitter, TWiTTeR... */
.button[href*=twitter] { background: #019FE9; }
.button[href*=facebook] { background: #3B5998; }
.button[href*=courses] { background: #ffc600; }
</style>
<script>
</script>
</body>
</html>
================================================
FILE: 27 - Click and Drag/index-FINISHED.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Click and Drag</title>
<link rel="stylesheet" href="style.css">
<link rel="icon" href="https://fav.farm/✅" />
</head>
<body>
<div class="items">
<div class="item item1">01</div>
<div class="item item2">02</div>
<div class="item item3">03</div>
<div class="item item4">04</div>
<div class="item item5">05</div>
<div class="item item6">06</div>
<div class="item item7">07</div>
<div class="item item8">08</div>
<div class="item item9">09</div>
<div class="item item10">10</div>
<div class="item item11">11</div>
<div class="item item12">12</div>
<div class="item item13">13</div>
<div class="item item14">14</div>
<div class="item item15">15</div>
<div class="item item16">16</div>
<div class="item item17">17</div>
<div class="item item18">18</div>
<div class="item item19">19</div>
<div class="item item20">20</div>
<div class="ite
gitextract_awdz6csi/ ├── .gitignore ├── 01 - JavaScript Drum Kit/ │ ├── index-FINISHED.html │ ├── index-START.html │ └── style.css ├── 02 - JS and CSS Clock/ │ ├── index-FINISHED.html │ └── index-START.html ├── 03 - CSS Variables/ │ ├── index-FINISHED.html │ └── index-START.html ├── 04 - Array Cardio Day 1/ │ ├── index-FINISHED.html │ └── index-START.html ├── 05 - Flex Panel Gallery/ │ ├── index-FINISHED.html │ └── index-START.html ├── 06 - Type Ahead/ │ ├── index-FINISHED.html │ ├── index-START.html │ └── style.css ├── 07 - Array Cardio Day 2/ │ ├── index-FINISHED.html │ └── index-START.html ├── 08 - Fun with HTML5 Canvas/ │ ├── index-FINISHED.html │ └── index-START.html ├── 09 - Dev Tools Domination/ │ ├── index-FINISHED.html │ └── index-START.html ├── 10 - Hold Shift and Check Checkboxes/ │ ├── index-FINISHED.html │ └── index-START.html ├── 11 - Custom Video Player/ │ ├── index.html │ ├── scripts-FINISHED.js │ ├── scripts.js │ └── style.css ├── 12 - Key Sequence Detection/ │ ├── cornify.js │ ├── index-FINISHED.html │ └── index-START.html ├── 13 - Slide in on Scroll/ │ ├── index-FINISHED.html │ └── index-START.html ├── 14 - JavaScript References VS Copying/ │ ├── index-FINISHED.html │ └── index-START.html ├── 15 - LocalStorage/ │ ├── index-FINISHED.html │ ├── index-START.html │ └── style.css ├── 16 - Mouse Move Shadow/ │ ├── index-FINISHED.html │ └── index-START.html ├── 17 - Sort Without Articles/ │ ├── index-FINISHED.html │ └── index-START.html ├── 18 - Adding Up Times with Reduce/ │ ├── index-FINISHED.html │ └── index-START.html ├── 19 - Webcam Fun/ │ ├── index.html │ ├── package.json │ ├── scripts-FINISHED.js │ ├── scripts.js │ └── style.css ├── 20 - Speech Detection/ │ ├── index-FINISHED.html │ ├── index-START.html │ └── package.json ├── 21 - Geolocation/ │ ├── index-FINISHED.html │ ├── index-START.html │ └── package.json ├── 22 - Follow Along Link Highlighter/ │ ├── index-FINISHED.html │ ├── index-START.html │ └── style.css ├── 23 - Speech Synthesis/ │ ├── index-FINISHED.html │ ├── index-START.html │ └── style.css ├── 24 - Sticky Nav/ │ ├── index-FINISHED.html │ ├── index-START.html │ ├── style-FINISHED.css │ └── style-START.css ├── 25 - Event Capture, Propagation, Bubbling and Once/ │ ├── index-FINISHED.html │ └── index-START.html ├── 26 - Stripe Follow Along Nav/ │ ├── index-FINISHED.html │ └── index-START.html ├── 27 - Click and Drag/ │ ├── index-FINISHED.html │ ├── index-START.html │ └── style.css ├── 28 - Video Speed Controller/ │ ├── index-FINISHED.html │ ├── index-START.html │ └── style.css ├── 29 - Countdown Timer/ │ ├── index.html │ ├── scripts-FINISHED.js │ ├── scripts-START.js │ └── style.css ├── 30 - Whack A Mole/ │ ├── index-FINISHED.html │ ├── index-START.html │ └── style.css ├── PULL_REQUEST_TEMPLATE.md └── readme.md
SYMBOL INDEX (16 symbols across 3 files)
FILE: 11 - Custom Video Player/scripts-FINISHED.js
function togglePlay (line 11) | function togglePlay() {
function updateButton (line 16) | function updateButton() {
function skip (line 22) | function skip() {
function handleRangeUpdate (line 26) | function handleRangeUpdate() {
function handleProgress (line 30) | function handleProgress() {
function scrub (line 35) | function scrub(e) {
FILE: 19 - Webcam Fun/scripts-FINISHED.js
function getVideo (line 7) | function getVideo() {
function paintToCanvas (line 27) | function paintToCanvas() {
function takePhoto (line 49) | function takePhoto() {
function redEffect (line 63) | function redEffect(pixels) {
function rgbSplit (line 72) | function rgbSplit(pixels) {
function greenScreen (line 81) | function greenScreen(pixels) {
FILE: 29 - Countdown Timer/scripts-FINISHED.js
function timer (line 6) | function timer(seconds) {
function displayTimeLeft (line 27) | function displayTimeLeft(seconds) {
function displayEndTime (line 35) | function displayEndTime(timestamp) {
function startTimer (line 43) | function startTimer() {
Condensed preview — 83 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (229K chars).
[
{
"path": ".gitignore",
"chars": 45,
"preview": ".DS_Store\nnode_modules/\n*.log\nhaters/\n.idea/\n"
},
{
"path": "01 - JavaScript Drum Kit/index-FINISHED.html",
"chars": 2303,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>JS Drum Kit</title>\n <link rel=\"stylesheet\" h"
},
{
"path": "01 - JavaScript Drum Kit/index-START.html",
"chars": 1702,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>JS Drum Kit</title>\n <link rel=\"stylesheet\" h"
},
{
"path": "01 - JavaScript Drum Kit/style.css",
"chars": 802,
"preview": "html {\n font-size: 10px;\n background: url('./background.jpg') bottom center;\n background-size: cover;\n}\n\nbody,html {\n"
},
{
"path": "02 - JS and CSS Clock/index-FINISHED.html",
"chars": 2343,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>JS + CSS Clock</title>\n <link rel=\"icon\" href"
},
{
"path": "02 - JS and CSS Clock/index-START.html",
"chars": 1432,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>JS + CSS Clock</title>\n <link rel=\"icon\" href"
},
{
"path": "03 - CSS Variables/index-FINISHED.html",
"chars": 1754,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Scoped CSS Variables and JS</title>\n <link re"
},
{
"path": "03 - CSS Variables/index-START.html",
"chars": 1117,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Scoped CSS Variables and JS</title>\n <link re"
},
{
"path": "04 - Array Cardio Day 1/index-FINISHED.html",
"chars": 4500,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Array Cardio 💪</title>\n <link rel=\"icon\" href"
},
{
"path": "04 - Array Cardio Day 1/index-START.html",
"chars": 2907,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Array Cardio 💪</title>\n <link rel=\"icon\" href"
},
{
"path": "05 - Flex Panel Gallery/index-FINISHED.html",
"chars": 3788,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Flex Panels 💪</title>\n <link href='https://fo"
},
{
"path": "05 - Flex Panel Gallery/index-START.html",
"chars": 2712,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Flex Panels 💪</title>\n <link href='https://fo"
},
{
"path": "06 - Type Ahead/index-FINISHED.html",
"chars": 1875,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Type Ahead 👀</title>\n <link rel=\"stylesheet\" "
},
{
"path": "06 - Type Ahead/index-START.html",
"chars": 584,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Type Ahead 👀</title>\n <link rel=\"stylesheet\" "
},
{
"path": "06 - Type Ahead/style.css",
"chars": 1369,
"preview": "html {\n box-sizing: border-box;\n background: #ffc600;\n font-family: 'helvetica neue';\n font-size: 20px;\n font-weigh"
},
{
"path": "07 - Array Cardio Day 2/index-FINISHED.html",
"chars": 1936,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Array Cardio 💪💪</title>\n <link rel=\"icon\" hre"
},
{
"path": "07 - Array Cardio Day 2/index-START.html",
"chars": 1167,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Array Cardio 💪💪</title>\n <link rel=\"icon\" hre"
},
{
"path": "08 - Fun with HTML5 Canvas/index-FINISHED.html",
"chars": 1517,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>HTML5 Canvas</title>\n <link rel=\"icon\" href=\""
},
{
"path": "08 - Fun with HTML5 Canvas/index-START.html",
"chars": 299,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>HTML5 Canvas</title>\n <link rel=\"icon\" href=\""
},
{
"path": "09 - Dev Tools Domination/index-FINISHED.html",
"chars": 2037,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Console Tricks!</title>\n <link rel=\"icon\" hre"
},
{
"path": "09 - Dev Tools Domination/index-START.html",
"chars": 686,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Console Tricks!</title>\n <link rel=\"icon\" hre"
},
{
"path": "10 - Hold Shift and Check Checkboxes/index-FINISHED.html",
"chars": 2991,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Hold Shift to Check Multiple Checkboxes</title"
},
{
"path": "10 - Hold Shift and Check Checkboxes/index-START.html",
"chars": 2238,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Hold Shift to Check Multiple Checkboxes</title"
},
{
"path": "11 - Custom Video Player/index.html",
"chars": 929,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>HTML Video Player</title>\n <link rel=\"stylesh"
},
{
"path": "11 - Custom Video Player/scripts-FINISHED.js",
"chars": 1823,
"preview": "/* Get Our Elements */\nconst player = document.querySelector('.player');\nconst video = player.querySelector('.viewer');\n"
},
{
"path": "11 - Custom Video Player/scripts.js",
"chars": 0,
"preview": ""
},
{
"path": "11 - Custom Video Player/style.css",
"chars": 2876,
"preview": "html {\n box-sizing: border-box;\n}\n\n*, *:before, *:after {\n box-sizing: inherit;\n}\n\nbody {\n margin: 0;\n padding: 0;\n "
},
{
"path": "12 - Key Sequence Detection/cornify.js",
"chars": 10898,
"preview": "/*\n\n _______ ,-----. .-------. ,---. .--..-./`) ________ ____ __\n / __ \\ .' .-, '. | "
},
{
"path": "12 - Key Sequence Detection/index-FINISHED.html",
"chars": 728,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <title>Key Detection</title>\n <script type"
},
{
"path": "12 - Key Sequence Detection/index-START.html",
"chars": 277,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <title>Key Detection</title>\n <script type"
},
{
"path": "13 - Slide in on Scroll/index-FINISHED.html",
"chars": 14477,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Document</title>\n <link rel=\"icon\" href=\"http"
},
{
"path": "13 - Slide in on Scroll/index-START.html",
"chars": 13729,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Document</title>\n <link rel=\"icon\" href=\"http"
},
{
"path": "14 - JavaScript References VS Copying/index-FINISHED.html",
"chars": 2389,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>JS Reference VS Copy</title>\n <link rel=\"icon"
},
{
"path": "14 - JavaScript References VS Copying/index-START.html",
"chars": 1371,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>JS Reference VS Copy</title>\n <link rel=\"icon"
},
{
"path": "15 - LocalStorage/index-FINISHED.html",
"chars": 3661,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>LocalStorage</title>\n <link rel=\"stylesheet\" "
},
{
"path": "15 - LocalStorage/index-START.html",
"chars": 2539,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>LocalStorage</title>\n <link rel=\"stylesheet\" "
},
{
"path": "15 - LocalStorage/style.css",
"chars": 1211,
"preview": "html {\n box-sizing: border-box;\n background: url(\"oh-la-la.jpeg\") center no-repeat;\n background-size: cover;\n min-he"
},
{
"path": "16 - Mouse Move Shadow/index-FINISHED.html",
"chars": 1361,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Mouse Shadow</title>\n <link rel=\"icon\" href=\""
},
{
"path": "16 - Mouse Move Shadow/index-START.html",
"chars": 579,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Mouse Shadow</title>\n <link rel=\"icon\" href=\""
},
{
"path": "17 - Sort Without Articles/index-FINISHED.html",
"chars": 1458,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Sort Without Articles</title>\n <link rel=\"ico"
},
{
"path": "17 - Sort Without Articles/index-START.html",
"chars": 1160,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Sort Without Articles</title>\n <link rel=\"ico"
},
{
"path": "18 - Adding Up Times with Reduce/index-FINISHED.html",
"chars": 3742,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Videos</title>\n <link rel=\"icon\" href=\"https:"
},
{
"path": "18 - Adding Up Times with Reduce/index-START.html",
"chars": 3170,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Videos</title>\n <link rel=\"icon\" href=\"https:"
},
{
"path": "19 - Webcam Fun/index.html",
"chars": 1229,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Get User Media Code Along!</title>\n <link rel"
},
{
"path": "19 - Webcam Fun/package.json",
"chars": 284,
"preview": "{\n \"name\": \"gum\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"scripts.js\",\n \"scripts\": {\n \"start\": \"brows"
},
{
"path": "19 - Webcam Fun/scripts-FINISHED.js",
"chars": 3069,
"preview": "const video = document.querySelector('.player');\nconst canvas = document.querySelector('.photo');\nconst ctx = canvas.get"
},
{
"path": "19 - Webcam Fun/scripts.js",
"chars": 229,
"preview": "const video = document.querySelector('.player');\nconst canvas = document.querySelector('.photo');\nconst ctx = canvas.get"
},
{
"path": "19 - Webcam Fun/style.css",
"chars": 937,
"preview": "html {\n box-sizing: border-box;\n}\n\n*, *:before, *:after {\n box-sizing: inherit;\n}\n\nhtml {\n font-size: 10px;\n backgro"
},
{
"path": "20 - Speech Detection/index-FINISHED.html",
"chars": 1885,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Speech Detection</title>\n <link rel=\"icon\" hr"
},
{
"path": "20 - Speech Detection/index-START.html",
"chars": 1162,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Speech Detection</title>\n <link rel=\"icon\" hr"
},
{
"path": "20 - Speech Detection/package.json",
"chars": 296,
"preview": "{\n \"name\": \"gum\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"scripts.js\",\n \"scripts\": {\n \"start\": \"brows"
},
{
"path": "21 - Geolocation/index-FINISHED.html",
"chars": 6173,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Document</title>\n <meta name=\"viewport\" conte"
},
{
"path": "21 - Geolocation/index-START.html",
"chars": 5821,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Document</title>\n <meta name=\"viewport\" conte"
},
{
"path": "21 - Geolocation/package.json",
"chars": 304,
"preview": "{\n \"name\": \"gum\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"scripts.js\",\n \"scripts\": {\n \"start\": \"brows"
},
{
"path": "22 - Follow Along Link Highlighter/index-FINISHED.html",
"chars": 2315,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>👀👀👀Follow Along Nav</title>\n <link rel=\"style"
},
{
"path": "22 - Follow Along Link Highlighter/index-START.html",
"chars": 1604,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>👀👀👀Follow Along Nav</title>\n <link rel=\"style"
},
{
"path": "22 - Follow Along Link Highlighter/style.css",
"chars": 1168,
"preview": "html {\n box-sizing: border-box;\n}\n\n*, *:before, *:after {\n box-sizing: inherit;\n}\n\nbody {\n min-height: 100vh;\n margi"
},
{
"path": "23 - Speech Synthesis/index-FINISHED.html",
"chars": 2208,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Speech Synthesis</title>\n <link href='https:/"
},
{
"path": "23 - Speech Synthesis/index-START.html",
"chars": 1215,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Speech Synthesis</title>\n <link href='https:/"
},
{
"path": "23 - Speech Synthesis/style.css",
"chars": 2430,
"preview": "html {\n font-size: 10px;\n box-sizing: border-box;\n}\n\n*, *:before, *:after {\n box-sizing: inherit;\n}\n\nbody {\n margin:"
},
{
"path": "24 - Sticky Nav/index-FINISHED.html",
"chars": 14886,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Document</title>\n <link rel=\"stylesheet\" href"
},
{
"path": "24 - Sticky Nav/index-START.html",
"chars": 14414,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Sticky Nav</title>\n <link rel=\"stylesheet\" hr"
},
{
"path": "24 - Sticky Nav/style-FINISHED.css",
"chars": 1536,
"preview": "html {\n box-sizing: border-box;\n background: #eeeeee;\n font-family: 'helvetica neue';\n font-size: 20px;\n font-weigh"
},
{
"path": "24 - Sticky Nav/style-START.css",
"chars": 1355,
"preview": "html {\n box-sizing: border-box;\n background: #eeeeee;\n font-family: 'helvetica neue';\n font-size: 20px;\n font-weigh"
},
{
"path": "25 - Event Capture, Propagation, Bubbling and Once/index-FINISHED.html",
"chars": 1079,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Understanding JavaScript's Capture</title>\n <"
},
{
"path": "25 - Event Capture, Propagation, Bubbling and Once/index-START.html",
"chars": 632,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Understanding JavaScript's Capture</title>\n <"
},
{
"path": "26 - Stripe Follow Along Nav/index-FINISHED.html",
"chars": 6728,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Follow Along Nav</title>\n <link rel=\"icon\" hr"
},
{
"path": "26 - Stripe Follow Along Nav/index-START.html",
"chars": 5425,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Follow Along Nav</title>\n <link rel=\"icon\" hr"
},
{
"path": "27 - Click and Drag/index-FINISHED.html",
"chars": 1987,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Click and Drag</title>\n <link rel=\"stylesheet"
},
{
"path": "27 - Click and Drag/index-START.html",
"chars": 1214,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Click and Drag</title>\n <link rel=\"stylesheet"
},
{
"path": "27 - Click and Drag/style.css",
"chars": 1658,
"preview": "html {\n box-sizing: border-box;\n background: url('https://source.unsplash.com/NFs6dRTBgaM/2000x2000') fixed;\n backgro"
},
{
"path": "28 - Video Speed Controller/index-FINISHED.html",
"chars": 1080,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Video Speed Scrubber</title>\n <link rel=\"styl"
},
{
"path": "28 - Video Speed Controller/index-START.html",
"chars": 475,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Video Speed Scrubber</title>\n <link rel=\"styl"
},
{
"path": "28 - Video Speed Controller/style.css",
"chars": 781,
"preview": "body {\n margin: 0;\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n background"
},
{
"path": "29 - Countdown Timer/index.html",
"chars": 1040,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Countdown Timer</title>\n <link href='https://"
},
{
"path": "29 - Countdown Timer/scripts-FINISHED.js",
"chars": 1592,
"preview": "let countdown;\nconst timerDisplay = document.querySelector('.display__time-left');\nconst endTime = document.querySelecto"
},
{
"path": "29 - Countdown Timer/scripts-START.js",
"chars": 0,
"preview": ""
},
{
"path": "29 - Countdown Timer/style.css",
"chars": 1283,
"preview": "html {\n box-sizing: border-box;\n font-size: 10px;\n background: #8E24AA;\n background: linear-gradient(45deg, #42a5f5"
},
{
"path": "30 - Whack A Mole/index-FINISHED.html",
"chars": 2103,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Whack A Mole!</title>\n <link href='https://fo"
},
{
"path": "30 - Whack A Mole/index-START.html",
"chars": 1065,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <title>Whack A Mole!</title>\n <link href='https://fo"
},
{
"path": "30 - Whack A Mole/style.css",
"chars": 991,
"preview": "html {\n box-sizing: border-box;\n font-size: 10px;\n background: #ffc600;\n}\n\n*, *:before, *:after {\n box-sizing: inher"
},
{
"path": "PULL_REQUEST_TEMPLATE.md",
"chars": 630,
"preview": "<!-- \n👋👋👋👋👋👋👋👋👋👋👋👋👋👋\n👋👋👋Hello Friend!👋👋👋👋\n👋👋👋👋👋👋👋👋👋👋👋👋👋👋\n\nThanks for Submitting a pull request. Before you hit that butt"
},
{
"path": "readme.md",
"chars": 9680,
"preview": "\n\n# JavaScript30\n\nStarter Files + Completed solutions for the "
}
]
About this extraction
This page contains the full source code of the wesbos/JavaScript30 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 83 files (209.4 KB), approximately 68.3k tokens, and a symbol index with 16 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.