Vox Americana

Each summer, the surefire signs of climate change come into sharper focus in the United States. Wildfires and heat waves plague the West. Increasingly intense hurricanes pummel the Southeast. Sudden thunderstorms soak towns from the Midwest to the mountains. Lyme disease-carrying ticks sicken hikers along the East Coast. And melting ice leads to more shipping pollution in Alaska. This barrage of headlines reminds us that these “extreme” events have already become our new normal as a result of the greenhouse gases accumulating in the atmosphere.

Taken one at a time, it’s possible to consume these occasional pieces of disaster coverage and still cling to the idea that climate change is happening somewhere else, to someone else. But listening to the growing chorus of people impacted by the changing climate rising up from all corners of the country forces us to recognize ourselves in our neighbors’ hopes and fears.

We have collected six audio stories from people all over the country who are already coping with the devastating consequences from climate change — in their own words.

.article__content{ width: 100%; } .g-module{ padding-top: 80px; max-width: none !important; } .g-module h2 { max-width: none; } .g-module h2 + .wp-block-ups-image.alignfull{ margin-top:20px; } .g-module p{ margin-left: auto; margin-right: auto; max-width: 600px; } .wp-block-columns{ border-top: 1px solid #F5515B; border-bottom: 1px solid #F5515B; padding: 20px 0; margin: 30px auto; align-items: center; max-width: 600px; } .wp-block-columns .wp-block-column{ margin:0; padding:0; } .wp-block-columns .wp-block-column:nth-child(2){ padding: 0 20px 0 40px; } .wp-block-columns .wp-block-column .wp-block-ups-image{ margin:0 !important; } .wp-block-columns h4{ font-size: 16px; } .wp-block-columns h3{ font-size: 24px; margin: 0 0 2px !important; padding: 0; } .article-body .wp-block-gallery{ margin-bottom: 0; } .g-diptych-caption{ font-family: “Basis Grotesque”,sans-serif; font-size: 12px; font-weight: 400; line-height: 1.4; width: calc(100% – 6vw); margin: 8px auto 0; text-align:left; margin-bottom: 36px; text-align:center; } .article-body .wp-block-ups-image.alignleft > div{ max-width: 40%; margin-top: 25px; margin-bottom: 20px; } .g-audio{ display: flex; align-items: center; margin-top: 20px; cursor: pointer; } .g-audio-button { border: 0; background: transparent; box-sizing: border-box; width: 0; height: 37px; border-color: transparent transparent transparent #F5515B; transition: 100ms all ease; cursor: pointer; border-style: solid; border-width: 18.5px 0 18.5px 30px; } .g-audio-button.g-playing { border-style: double; border-width: 0px 0 0px 30px; } .g-audio-button:hover { border-color: transparent transparent transparent #F5515B; } .g-audio h6{ margin-left: 15px; font-size: 14px; color: #F5515B; } .g-nav{ border-top: 1px solid #F5515B; padding:0; max-width: none !important; } .g-nav-item{ width: 100%; padding: 10px 20px 10px 0; border-bottom: 1px solid #F5515B; } .g-nav-item a{ display: flex; align-items: center; } .g-nav-item-image{ width: 60px; position: relative; flex-shrink: 0; } .g-nav-item-image .g-audio-button{ position: absolute; top:50%; left: 50%; transform: translate3d(-50%, -50%, 0); opacity: 0; transition: opacity 0.5s; } .g-nav-item-image img{ transition: opacity 0.5s; } .g-nav-item a .js-modal-gallery__trigger.relative .js-modal-gallery__open{ display: none; } .g-nav-item h6{ font-size: 14px; transition: color 0.5s; } .g-nav-item a:hover h6{ color: #F5515B; } .g-nav-item a:hover .g-nav-item-image img{ opacity: 0.3; } .g-nav-item a:hover .g-nav-item-image .g-audio-button{ opacity: 1; } .g-nav-item .g-nav-item-text{ padding-left: 10px; } .g-nav-item .g-nav-item-text h6:first-child{ font-size: 18px; } .g-nav .g-audio{ width: 100%; justify-content: center; margin-top: 0; margin-bottom: 20px; border-bottom: 1px solid #F5515B; padding-bottom: 10px; } .g-spotify{ width: 130px; display: flex; font-size: 12px; font-family: “PolySans”,sans-serif; align-items: center; justify-content: space-between; margin-top: 4px; margin-left: auto; } .g-spotify img{ width: 70px; } .g-spotify .js-modal-gallery__trigger.relative .js-modal-gallery__open{ display: none; } .g-sticky-nav{ max-width: none !important; width: 100vw; position: sticky; -webkit-position:sticky; top: 0; z-index: 100000; height: 50px; padding: 0px 3vw; box-sizing: border-box; overflow: hidden; background-color: rgb(240, 240, 240); transition: background-color 0.5s; -webkit-transition: background-color 0.5s; margin-top: 60px; margin-left: -5vw !important; } .g-sticky-nav.g-active{ background-color:#fff; } .g-sticky-nav > a{ width: 100%; display:block; height: 50px; transition: transform 0.5s; -webkit-transition: transform 0.5s; } .g-sticky-nav h3{ font-size: 18px; color: #F5515B; margin-left: 20px; } .g-sticky-nav .g-audio{ margin-top:0; height: 50px; } .g-sticky-nav.g-active .g-sticky-nav-inner{ transform: translate3d(0, -50px, 0); -webkit-transform: translate3d(0, -50px, 0); } .g-sticky-nav.g-active > a{ transform: translate3d(0, -50px, 0); -webkit-transform: translate3d(0, -50px, 0); } .g-sticky-nav-inner{ display: flex; transition: transform 0.5s; height: 50px; align-items: center; } .g-audio-detail{ margin-left: 20px; } .g-audio-track{ font-size: 12px; margin:0; } .g-audio-info{ display: flex; align-items: center; } .g-audio-time{ font-size: 12px; font-family: “Basis Grotesque”,sans-serif; font-size: 11px; font-weight: 400; line-height: 1.4; margin-left: 10px; } .g-audio-bar{ width: 175px; height: 4px; background: #ccc; position: relative; } .g-audio-progress{ position: absolute; height: 4px; background: #F5515B; top:0; left:0; } .g-credits{ margin-top: 60px; } .g-credits p{ font-family: “Basis Grotesque”,sans-serif; font-size: 12px; font-weight: 400; line-height: 1.4; } @media (min-width: 768px){ .g-module { padding-top: 120px; } .g-audio-track{ font-size: 14px; } .g-sticky-nav h3{ font-size: 28px; } .topper.topper-full-width{ position: relative; } .topper-full-width .topper-headings{ position: absolute; width: 100%; top: 40%; color:#fff; text-shadow: 2px 2px 2px rgba(0,0,0,0.3); } .topper-headings__subtitle{ background: rgba(0,0,0,0.5); display: inline-block; padding: 5px 10px; } h1{ font-size: 90px; } .g-audio-bar{ width: 300px; } .wp-block-columns h4{ font-size: 18px; } .wp-block-columns h3{ font-size: 28px; } .g-audio h6{ font-size: 18px; } .g-sticky-nav{ margin-left: -3vw !important; } } @media (min-width: 1070px){ .article__content{ width: auto; } h1{ font-size: 120px; } } @media(max-width: 767px){ .article-body .blocks-gallery-grid .blocks-gallery-item{ width: 100% !important; margin-right: 0; } } @media (min-width: 1440px){ .g-sticky-nav{ margin-left: calc(-300px – 6vw) !important; } .g-nav, .g-module h2{ margin-left: calc(-300px – 3vw) !important; } }

Listen to their stories

<!–

–>

Title
0:00/0:00

In Louisiana, back-to-back hurricanes leave no room to recover

gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== - Vox Americana
Flood waters surround a house in Lake Charles, Louisiana, a day after Hurricane Delta passed through the area on October 10, 2020. Hurricane Delta made landfall as a Category 2 storm in Louisiana initially leaving some 300,000 customers without power. Photo by Chandan Khanna / AFP via Getty Images
gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== - Vox Americana
Courtesy of Shonell Bacon

Shonell Bacon

Lake Charles, Louisiana

Listen to her story

My name is Shonell Bacon. I’m originally from Baltimore, but I moved to Lake Charles, Louisiana, in 2001 to do my MFA program at McNeese State University here. 

Every year from June 1st to November 30, we get fearful because half the year is worrying about when a hurricane is going to come. I keep a tab up for the National Hurricane Center all six months and I have a million apps on hurricanes and storms on my phones and tablets. 

Currently, I live with my sister and my mom, and we were here for Laura and Delta. We were double hit because we had good ol’ Laura and then about 40 days later we had Delta. Those two events have been the most traumatizing moments of my life ever. 

Left: Hurricane Laura’s high winds caused devastating damage, seen here in North Lake Charles, to many parts of Louisiana. A little over a month later, the area was hit by a second major storm, Delta. Photo by Shonell Bacon. Right: Many roofs, including these in North Lake Charles, Louisiana, collapsed as a result of Hurricane Laura’s high winds. Photo by Shonell Bacon.

I will admit that during Laura, I was fairly sure we were going to die because it sounded like a thousand trains just going as fast as they can above you, beside you, behind you, below you. And it lasted for what felt like forever. We thought for sure the roof was going to rip off. But it didn’t. We were so surprised when we woke up the next morning, there was a roof. 

As soon as day broke, my mom, my sister, and my brother went outside and they started calling for me. They’re like, “Come see.” And that’s when I broke, because I went outside and the house across the street from us had half a roof, and then the house next door to us, all the windows were busted out. I’m going to get emotional just because when I talk about this, there was such devastation, and I felt so horrible that we got saved when so many people didn’t. 

This whole city was decimated. There are parts that will probably never come back, and if they do, I won’t be here because we’re already planning to be gone before the next hurricane season. I’m not Louisiana strong. I don’t know what they have in them to keep rebuilding, but I don’t have that.

In coal country, severe flooding tests the limits of regional resilience  

gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== - Vox Americana
People stand in the middle of a mud-covered street left over from the flooding of the Elk River on June 25, 2016 in Clendenin, West Virginia. Photo by Ty Wright / Getty Images
gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== - Vox Americana
Photo courtesy of Andy Waddell

Andy Waddell

Clay County, West Virginia

Listen to his story

My name is Andy Waddell, I’m a 40-year resident of Clay County, West Virginia, Appalachian Mountains. 

Clay County is 342 square miles. We are a place of tall mountains and very narrow valleys. We enjoy four seasons. What we don’t enjoy is, we regularly have flooding. 

We had a flood five years ago; we called it a “once in a lifetime, hundred-year flood.” That’s how we explained it away. I can remember that weathercasters were saying this could just be a real damnation. And in a matter of two hours of really heavy rainfall, everything went to pot — roads were covered, creeks were out of their banks, propane tanks were floating, cars were submerged. 

gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== - Vox Americana
Kayakers float along the Elk River in Clay County, West Virginia. Residents hope the area’s natural beauty will attract more tourists, adding jobs to the formerly coal-driven economy. Photo courtesy of Andy Waddell

We’ve had other storms here and, sure, we might lose electricity for a day or two. That’s common. But this wiped out the utilities. For many people, it was three weeks without electricity. I mean, the county shut down. People were standing there with all they owned in their arms. Everything else was washed away. 

We are a resilient people. We’ve been through floods. We’ve been through disasters. And the truth is, we like it here. It’s beautiful. But for many people in this county, we don’t talk about climate change, period. The scariest part for me is, have we waited too long to make the necessary changes? If next summer, here comes another “hundred-year flood,” I don’t know if we can start over.

In Alaska, melting ice brings a boatload of new issues

gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== - Vox Americana
An Indigenous Alaskan man washes freshly caught salmon from the Northern Bering Sea. Photo by Andrew Burton/Getty Images
gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== - Vox Americana
Courtesy of Austin Ahmasuk

Austin Ahmasuk

Nome, Alaska

Listen to his story

My name is Austin Ahmasuk. I was born and raised in Nome, Alaska, and I’ve been working as a tribal, environmental, and subsistence advocate here in my hometown since 1997. 

Ways of life are changing here in the North very dramatically. A specific example was this last year during the first full moon in November. It’s a time when you can get out on land, access areas where ice isn’t terribly thick. And, for folks in the lower 48 that might not be able to understand cold, that’s always been a time in my life when river ice is generally two feet or more thick.

Left: A pile of debris gathered by Indigenous residents of Nome, Alaska during the Summer of 2020. Residents say the trash is associated with an increase in cargo shipping associated with melting ice. Photo by Austin Ahmasuk. Right: MA Russian tanker heads toward Nome, Alaska accompanied by a U.S. Coast Guard vessel Photo by Sara Francis/U.S. Coast Guard via Getty Images

Well, this past year on the first full moon in November, river ice was barely six inches. Rivers which are normally frozen substantially, were mostly open. And so hunters like myself are contemplating the possibility that the animals that we consume for food — fish, wildlife, marine mammals — some of those animals may go extinct locally or shift their distribution north. And we may have to focus on other things that we’re not entirely used to. 

These things are happening in the context of climate change. Absolutely. As another example, as waters have gotten warmer, shipping has increased. This past summer, communities in my region dealt with, for the very first time, trash from shipping-related activity washing ashore — plastics and petrochemicals and fishing gear. That month-long foreign debris event was very disturbing. We had to weed through trash to obtain things we need from the ocean. Those beaches are normally pristine. 

And so we realized with this event, we’re totally on our own. We’re going to have to clean up our beaches ourselves and address this ourselves.

In Iowa, farmers adjust to more intense conditions

gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== - Vox Americana
Rows of flood-damaged and dying corn rot on a farm outside of Mt. Vernon, Iowa. Photo by David Greedy / Getty Images
gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== - Vox Americana
Courtesy of Meredith Nunnikhoven

Meredith Nunnikhoven

Oskaloosa, Iowa

Listen to her story

My name is Meredith Nunnikhoven and I live in Oskaloosa, Iowa. I’m a fifth-generation farmer. We farm fresh, cut flowers and I just installed six acres of a chestnut plantation — so that’s the new diverse crop that I brought to the farm. 

Iowa, we have floods, we have blizzards, we have tornadoes, we have the gamut of all this crazy weather, right? But what I’ve noticed is the intensity of it. It just seems like there’s more of everything. So if we have monsoon rains for three weeks, which is what we had two years ago, that affects everything that we do. 

Normally we’re ready to plant at the end of April or early May, and we start working the ground. That goes for flowers, vegetables, and our crops. But the past several years, we’ve been very hesitant to put those crops in until we see these rains come through. 

Left: Meredith Nunnikhoven prepares a 6-acre plot of land at Barnswallow Farms for Chestnut trees. Her family has worked hard to remove the brome grasses from the area and re-seeded it with a cover crop of white dutch clover and short fescue grass. She has made many other climate-friendly changes to the farm over the past several years, including creating butterfly habitat, and improving soil drainage. Photo courtesy of Meredith Nunnikhoven Right: MA crop of fresh-cut flowers stand await sale at Barnswallow Farms in Oskaloosa, Iowa. Photo courtesy of Meredith Nunnikhoven

One year we had put in, I’d say, close to a thousand marigolds and several hundred tomato plants and peppers. Granted, those plants are pretty hardy, but I could visually see them outside getting intensely rained on for almost two and a half, three weeks. And we surely thought that they would die. And that makes us nervous now to put our crop in. 

When I talked to my whole family, they all agreed: Climate change is real. We know it’s an issue and we’re trying to do everything we can here as farmers to combat that. We’re in it for the long haul. But for us to cover crop and start seeing improvement in our soils, that’s 10, sometimes 20, sometimes 30, if not longer, years until we would see those improvements from the adjustments that we’re making right now. 

In California, the appeal of living near nature goes up in flames

gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== - Vox Americana
A lingering morning fog hovers over charred homes and vegetation in Butte Creek Canyon, California. The town was burned in the 2018 Camp Fire, which also decimated the nearby town of Paradise, California. Photo by Justin Sullivan / Getty Images
gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== - Vox Americana
Courtesy of Andrew Burke

Andrew Burke

Butte Creek Canyon, California

Listen to his story

Hello, my name is Andrew Burke and I’m a resident of Butte Creek Canyon, which was within the burn area of the California Camp Fire. 

The Camp Fire was fast-moving. We heard, “Oh, it’s on the other side of Paradise. No big deal. Oh, it’s to Paradise. Uh oh, it’s halfway through Paradise. Oh, it’s completely through Paradise.” And we’re like, oh, wait a second. It’s only been half an hour. And as the crow flies, we’re not that far from Paradise. So, yeah, that’s when we really started hurrying hurrying hurrying to evacuate. 

We packed up the back of the car. We helped my wife’s folks pack some picture boxes and stuff. I guess I didn’t mention that my wife was seven months pregnant at the time. So throughout this, we’re trying to keep stress levels down. And yeah, we scooted out. 

We hit some traffic. You know, a lot of people got kind of stuck in traffic, but we made it through the fire burning down to where we were parked. We were kind of middle-of–the-road in how we were affected. I mean, we lost our home. We lost everything. Our whole community is gone. And that’s being middle-of-the-road in something like this. 

gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== - Vox Americana
An aerial view of a neighborhood burned by the 2018 Camp Fire. Climate change has contributed to the severity of California’s wildfires in recent years as a result of drier soil and hotter weather. Photo by Justin Sullivan/Getty Images

When we came back to Butte Creek Canyon, it obviously didn’t look like anything we had ever seen. Everything was ash. Everything was charred. wWole trees were missing with just a hole in the ground where the roots were. I was just in awe. You knew there was a community here. You knew there were homes here and there was just nothing. It just didn’t look like a scene from Earth.

Even though it was really damaged. We decided to move back into the area, kind of within the burn scar — which is good and bad, because every day we have to look at the surroundings, take the kid on a stroller ride by our old home. But for the future, I hope that people are still able to live in these wild areas because they are nice places to live. On paper, this is a good place to raise a family. 

We’re just going to have to learn to live with these fires and adapt. Just realize, OK. This is something that happens now.

In Upstate New York, warmer weather comes with a sickening bite

gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== - Vox Americana
Emma Baker waters plants as part of her landscape design job in New York’s Hudson Valley. She says that dealing with ticks is a growing part of her experience working outside. Photo by CDC/ James Gathany; William L. Nicholson, Ph.D.
gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== - Vox Americana
Photo courtesy of Emma Baker

Emma Baker

Hudson Valley, New York

Listen to her story

My name is Emma Baker, and I am in Accord, New York, which is part of the Hudson Valley. I am a construction worker and landscape designer. 

I’ve noticed changes in the environment since I grew up, even just walking around in the forest. I’ve noticed that the forests just don’t look as green and healthy as they used to when I was a kid. And, of course, there are way more ticks. 

I do tick checks as soon as I get home and I try to pay attention. Other than that, I can’t change what I do for my work. That’s what I love to do. And it’s kind of inevitable that I’ll get bitten. Like just the other day when I was working, I found over 15 on me. I was like wading in tall grass and I found three on me at a time consistently for hours. 

gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== - Vox Americana
Emma Baker waters plants as part of her landscape design job in New York’s Hudson Valley. She says that dealing with ticks is a growing part of her experience working outside. Photo courtesy of Emma Baker

Generally I find them like on my legs first crawling up the ankles. If you have leg hair, it usually helps a little bit — you can feel them moving around better and you try to get them right when they’re crawling on you before they latch on. 

I was bitten by a tick at some point in my 10th grade year in high school, and I got really, really sick. I didn’t know what it was from, because I never got a rash or anything. Usually if you get sick from a tick, especially if you’re going to contract Lyme disease, you get a bull’s eye rash, which is a red rash and like a circle around the area that you were bitten. 

My main symptoms were, I had very, very severe headaches pretty much constantly; I was really sensitive to light; and I was really, really tired, like my energy level completely tanked. So that was pretty serious. I had a PICC line in my arm, which is like a little opening that they give you antibiotics through. You attach a syringe to it twice a day for a month. And the treatment did work. I was really lucky. I don’t think that I have long-term effects, although it’s kind of hard to know.

This story was reported by Emily Pontecorvo, Nathanael Johnson, Eve Andrews, and Zoya Teirstein. Teresa Chin led the art direction and produced the audio. Jacky Myint handled design and development. Edits by Katherine Bagley, Nikhil Swaminathan, and Matthew Craft.

const track = document.querySelector(‘.g-audio-track’);
const duration = document.querySelector(‘.g-audio-duration’);
const timer = document.querySelector(‘.g-audio-timer’);
const progress = document.querySelector(‘.g-audio-progress’);
const audioButtons = document.querySelectorAll(‘.g-audio-control’);
const nav = document.querySelector(‘.g-sticky-nav’);
const navA = document.querySelectorAll(‘.g-nav a’); let blocks = [];
let wWidth, wHeight, isSmaller;
let audioTurnedOn = false;
let currentSong = undefined; /** * Player class containing the state of our playlist and where we are in it. * Includes all methods for playing, skipping, updating the display, etc. * @param {Array} playlist Array of objects with playlist song details ({title, file, howl}). */
var Player = function(playlist) { this.playlist = playlist; this.index = 0; // Display the title of the first track. //track.innerHTML = ‘1. ‘ + playlist[0].title; // // // Setup the playlist display. // playlist.forEach(function(song) { // var div = document.createElement(‘div’); // div.className = ‘list-song’; // div.innerHTML = song.title; // div.onclick = function() { // player.skipTo(playlist.indexOf(song)); // }; // list.appendChild(div); // });
};
Player.prototype = { load: function(index){ }, /** * Play a song in the playlist. * @param {Number} index Index of the song in the playlist (leave empty to play the first or current). */ play: function(index) { var self = this; var sound; index = typeof index === ‘number’ ? index : self.index; var data = self.playlist[index]; // If we already loaded this track, use the current one. // Otherwise, setup and load a new Howl. if (data.howl) { sound = data.howl; } else { sound = data.howl = new Howl({ src: [data.file], html5: true, // Force to HTML5 so that the audio can stream in (best for large files). onplay: function() { // Display the duration. duration.innerHTML = self.formatTime(Math.round(sound.duration())); // Start updating the progress of the track. requestAnimationFrame(self.step.bind(self)); // changeAudioButtonsState(true); }, onload: function() { // loading.style.display = ‘none’; }, onend: function() { changeAudioButtonsState(false); audioTurnedOn = false; //self.skip(‘next’); }, onpause: function() { //changeAudioButtonsState(false); //audioTurnedOn = false; //bar.style.display = ‘block’; }, onstop: function() { //changeAudioButtonsState(false); //audioTurnedOn = false; // Stop the wave animation. // wave.container.style.display = ‘none’; // bar.style.display = ‘block’; }, onseek: function() { // Start updating the progress of the track. requestAnimationFrame(self.step.bind(self)); } }); } // Begin playing the sound. sound.play(); // Update the track display. //track.innerHTML = (index + 1) + ‘. ‘ + data.title; // Show the pause button. // if (sound.state() === ‘loaded’) { // playBtn.style.display = ‘none’; // pauseBtn.style.display = ‘block’; // } else { // loading.style.display = ‘block’; // playBtn.style.display = ‘none’; // } // Keep track of the index we are currently playing. self.index = index; }, /** * Pause the currently playing track. */ pause: function() { var self = this; // Get the Howl we want to manipulate. var sound = self.playlist[self.index].howl; // Puase the sound. sound.pause(); }, /** * Skip to a specific track based on its playlist index. * @param {Number} index Index in the playlist. */ skipTo: function(index) { var self = this; // Stop the current track. if (self.playlist[self.index].howl) { self.playlist[self.index].howl.pause(); } // Reset progress. progress.style.width = ‘0%’; // Play the new track. self.play(index); }, /** * Seek to a new position in the currently playing track. * @param {Number} per Percentage through the song to skip. */ seek: function(per) { var self = this; // Get the Howl we want to manipulate. var sound = self.playlist[self.index].howl; // Convert the percent into a seek position. if (sound.playing()) { sound.seek(sound.duration() * per); } }, /** * The step called within requestAnimationFrame to update the playback position. */ step: function() { var self = this; // Get the Howl we want to manipulate. var sound = self.playlist[self.index].howl; // Determine our current seek position. var seek = sound.seek() || 0; timer.innerHTML = self.formatTime(Math.round(seek)); progress.style.width = (((seek / sound.duration()) * 100) || 0) + ‘%’; // If the sound is still playing, continue stepping. if (sound.playing()) { requestAnimationFrame(self.step.bind(self)); } }, /** * Format the time from seconds to M:SS. * @param {Number} secs Seconds to format. * @return {String} Formatted time. */ formatTime: function(secs) { var minutes = Math.floor(secs / 60) || 0; var seconds = (secs – minutes * 60) || 0; return minutes + ‘:’ + (seconds { […audioButtons].forEach((el, index) => { el.addEventListener(‘click’, ()=> { if(audioTurnedOn){ audioTurnedOn = false; player.pause(); changeAudioButtonsState(false); }else{ audioTurnedOn = true; if(currentSong!== undefined) player.skipTo(currentSong); changeAudioButtonsState(true); } }); });
}
const changeAudioButtonsState = (playing) => { […audioButtons].forEach((el, index) => { if(playing){ el.classList.add(‘g-playing’); }else{ el.classList.remove(‘g-playing’); } }); }
const setNavLinks = () => { […navA].forEach((el, index) => { el.addEventListener(‘click’, ()=> { if(!audioTurnedOn){ audioTurnedOn = true; changeAudioButtonsState(true); } }); }); nav.querySelector(‘a’).addEventListener(‘click’, () => { if(!audioTurnedOn){ audioTurnedOn = true; changeAudioButtonsState(true); } });
} //////////////////////////////////UTILS///////////////////////////////////
const getHeight = (el) => { return el.getBoundingClientRect().height;
}
const getPositionTop = (el) => { const rect = el.getBoundingClientRect(), scrollTop = window.pageYOffset || document.documentElement.scrollTop; return rect.top + scrollTop;
}
const constrain = (n, low, high) => { return Math.max(Math.min(n, high), low);
} //////////////////////////////////BLOCKS///////////////////////////////////
const initBlocks = () => { […document.querySelectorAll(‘.g-module’)].forEach((el, index) => { var obj = {}; obj.index = index; obj.el = el; obj.title = playlist[index].title = el.querySelector(‘.wp-block-column h3’).textContent + ‘, ‘ + el.querySelector(‘.wp-block-column h4’).textContent; obj.duration = playlist[index].duration; blocks.push(obj); }); onResize(); addResizeListener(); addScrollListener(); }
//////////////////////////////////RESIZE/SCROLL///////////////////////////////////
const onResize = () => { wWidth = Math.max(document.documentElement.clientWidth, window.innerWidth); wHeight = Math.max(document.documentElement.clientHeight, window.innerHeight); isSmaller = wWidth { block.top = getPositionTop(block.el); block.height = getHeight(block.el); block.bottom = block.top + block.height; }); onScroll();
}
const onScroll = () => { const scroll = window.scrollY || window.pageYOffset || document.body.scrollTop + (document.documentElement && document.documentElement.scrollTop || 0); blocks.forEach((block, index) => { const offsetY = wHeight/4; if(block.bottom – offsetY >= scroll && block.top <= scroll + offsetY){ if(!block.el.classList.contains('g-active')){ block.el.classList.add('g-active'); currentSong = index; track.innerHTML = (index + 1) + '. ' + block.title; duration.innerHTML = block.duration; if(audioTurnedOn){ player.skipTo(currentSong); }else{ timer.innerHTML = '0:00'; progress.style.width = '0%'; } if(!nav.classList.contains('g-active')){ nav.classList.add('g-active'); } } }else{ if(block.el.classList.contains('g-active')){ block.el.classList.remove('g-active'); } if(index == 0){ if(scroll { let ticking = false; window.addEventListener(‘scroll’, scrollListener); function scrollListener(evt) { if (!ticking) { window.requestAnimationFrame((evt) => { ticking = false; onScroll(); }); } ticking = true; }
} const addResizeListener = () => { let resizeTimer; window.addEventListener(‘resize’, () => { clearTimeout(resizeTimer); resizeTimer = setTimeout(() => { onResize(); }, 1000); });
} //////////////////////////////////OBSERVER///////////////////////////////////
const setupObserver = (elements, callback) => { const options = { rootMargin: ‘-50% 0% -50% 0%’, threshold: [0] }; const observer = new IntersectionObserver(callback, options); Array.prototype.forEach.call(elements, (el) => { observer.observe(el); });
} const createScrollEls = () => { const elements = document.querySelectorAll(‘.g-module’); if (elements.length === 0) return false; setupObserver(elements, scrollerObserverCallbackFunction);
} const scrollerObserverCallbackFunction = (entries, observer) => { entries.forEach(entry => { if (entry.isIntersecting) { const { target } = entry; onResize(); } });
} //////////////////////////////////INIT///////////////////////////////////
const init = () => { initBlocks(); createScrollEls(); setAudioButtons(); setNavLinks();
}
init();

This story was originally published by Grist with the headline Vox Americana on Jul 1, 2021.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.