added audio player section and player script

main
Alina Marquardt 2025-05-15 22:27:05 +02:00
parent 19850dfc1a
commit e9f0cd8dea
14 changed files with 240 additions and 11 deletions

View File

@ -1,9 +1,117 @@
// gif player
document.querySelectorAll('.paused-animation').forEach(el => {
el.addEventListener('click', () => {
el.classList.toggle('active');
});
});
// track players
const players = document.querySelectorAll('.track-player');
players.forEach(player => {
const trackName = player.getAttribute('data-track');
const button = document.createElement('div');
button.className = 'play-button play'; // start as play
player.appendChild(button);
const wrapper = document.createElement('div');
wrapper.className = 'track';
wrapper.innerHTML = `
<div class="blurgreen track-container">
<div class="track-played"></div>
<div class="track-unplayed"></div>
</div>
`;
player.appendChild(wrapper);
const playercontainer = player.querySelector('.track-container');
const played = player.querySelector('.track-played');
const unplayed = player.querySelector('.track-unplayed');
played.style.backgroundImage = `url('tracks/${trackName}-played.png')`;
unplayed.style.backgroundImage = `url('tracks/${trackName}.png')`;
const audio = document.createElement('audio');
audio.style.display = 'none';
player.appendChild(audio);
button.addEventListener('click', () => {
// Pause other players immediately
players.forEach(p => {
const otherAudio = p.querySelector('audio');
const otherBtn = p.querySelector('.play-button');
if (otherAudio !== audio) {
if (!otherAudio.paused) otherAudio.pause();
if (otherBtn) {
otherBtn.classList.add('play');
otherBtn.classList.remove('pause');
}
}
});
// Then lazy-load and play/pause current audio as before...
if (!audio.src) {
audio.src = 'tracks/' + trackName + '.mp3';
audio.currentTime = 0;
audio.load();
audio.addEventListener('canplay', () => {
audio.play().then(() => {
button.classList.remove('play');
button.classList.add('pause');
}).catch(() => {
button.classList.add('play');
button.classList.remove('pause');
});
}, { once: true });
return;
}
if (audio.paused) {
audio.play().then(() => {
button.classList.remove('play');
button.classList.add('pause');
}).catch(() => {
button.classList.add('play');
button.classList.remove('pause');
});
} else {
audio.pause();
button.classList.add('play');
button.classList.remove('pause');
}
});
audio.addEventListener('ended', () => {
button.classList.add('play');
button.classList.remove('pause');
});
playercontainer.addEventListener('click', e => {
const rect = playercontainer.getBoundingClientRect(); // Use container rect!
const clickX = e.clientX - rect.left;
const width = rect.width;
const portion = Math.min(Math.max(clickX / width, 0), 1);
audio.currentTime = portion * audio.duration;
});
audio.addEventListener('timeupdate', () => {
const portion = audio.duration ? audio.currentTime / audio.duration : 0;
update_play_position(played, unplayed, portion);
});
});
function update_play_position(played_element, unplayed_element, portion) {
const playedPercent = portion * 100;
const unplayedPercent = 100 - playedPercent;
played_element.style.width = playedPercent + "%";
unplayed_element.style.width = unplayedPercent + "%";
}
// icosahedron
// Wait for everything to load

View File

@ -7,7 +7,7 @@
<rect x="464.497" y="245.176" width="95.007" height="95.01"/>
</clipPath>
<g clip-path="url(#_clip1)">
<g transform="matrix(1,0,0,1,462.499,242.853)">
<g transform="matrix(1,0,0,1,462.002,242.677)">
<path d="M49.9,2.5C23.6,2.8 2.1,24.4 2.5,50.4C2.9,76.5 24.7,98 50.3,97.5C76.7,96.9 97.7,75.7 97.5,49.8C97.3,23.7 75.7,2.3 49.9,2.5" style="fill:rgb(99,168,184);fill-rule:nonzero;"/>
</g>
<g transform="matrix(1,0,0,1,462.499,242.853)">

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 96 96" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1,0,0,1,-126,-134)">
<g id="track-pause" transform="matrix(1,0,0,1,-338.497,-111.176)">
<rect x="464.497" y="245.176" width="95.007" height="95.01" style="fill:none;"/>
<clipPath id="_clip1">
<rect x="464.497" y="245.176" width="95.007" height="95.01"/>
</clipPath>
<g clip-path="url(#_clip1)">
<g transform="matrix(1,0,0,1,462.002,242.677)">
<path d="M49.9,2.5C23.6,2.8 2.1,24.4 2.5,50.4C2.9,76.5 24.7,98 50.3,97.5C76.7,96.9 97.7,75.7 97.5,49.8C97.3,23.7 75.7,2.3 49.9,2.5" style="fill:white;fill-rule:nonzero;"/>
</g>
<g transform="matrix(1,0,0,1,338.582,110.729)">
<path d="M170.225,165.93C170.225,164.274 168.881,162.93 167.225,162.93L159.923,162.93C158.268,162.93 156.923,164.274 156.923,165.93L156.923,198.318C156.923,199.974 158.268,201.318 159.923,201.318L167.225,201.318C168.881,201.318 170.225,199.974 170.225,198.318L170.225,165.93ZM190.906,165.93C190.906,164.274 189.562,162.93 187.906,162.93L180.605,162.93C178.949,162.93 177.605,164.274 177.605,165.93L177.605,198.318C177.605,199.974 178.949,201.318 180.605,201.318L187.906,201.318C189.562,201.318 190.906,199.974 190.906,198.318L190.906,165.93Z" style="fill:rgb(99,168,184);"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 96 96" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1,0,0,1,0,-134)">
<g id="track-play" transform="matrix(1,0,0,1,-464.497,-111.176)">
<rect x="464.497" y="245.176" width="95.007" height="95.01" style="fill:none;"/>
<clipPath id="_clip1">
<rect x="464.497" y="245.176" width="95.007" height="95.01"/>
</clipPath>
<g clip-path="url(#_clip1)">
<g transform="matrix(1,0,0,1,462.002,242.677)">
<path d="M49.9,2.5C23.6,2.8 2.1,24.4 2.5,50.4C2.9,76.5 24.7,98 50.3,97.5C76.7,96.9 97.7,75.7 97.5,49.8C97.3,23.7 75.7,2.3 49.9,2.5" style="fill:white;fill-rule:nonzero;"/>
</g>
<g transform="matrix(1,0,0,1,462.499,242.853)">
<path d="M38,69C37,69.5 36.2,69 36.2,67.9L36.2,32.1C36.2,31 37,30.5 38,31L72,49C73,49.5 73,50.4 72,50.9L38,69Z" style="fill:rgb(99,168,184);fill-rule:nonzero;"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -123,6 +123,31 @@
<div class="listenbuy"><em>listen</em> or <em>buy</em> on bandcamp</div>
</a>
</article>
<header class="blurgreen headlineshadow spaceup">
<h1><em>highlighted</em> tracks
<img
class="icon"
src="img/head-music.webp"
srcset="img/head-music.webp 2x, img/head-music_1x.webp 1x"
width="69"
height="77"
alt
>
</h1>
</header>
<div class="transparent headlineshadow">
<article class="track">
<h2><span class="halfbubble whitebg elementshadow"></span>lastfuture <em> rattlefox</em></h2>
<div class="track-player" data-track="lastfuture-rattlefox"></div>
</article>
<article class="track">
<h2><span class="halfbubble whitebg elementshadow"></span>lastfuture <em> majesty</em></h2>
<div class="track-player" data-track="lastfuture-majesty"></div>
</article>
</div>
</section>
<section class="contentitem box maincontent" id="experiments">

View File

@ -458,10 +458,17 @@ body {
background-attachment: fixed;
}
.elementshadow {
box-shadow: 0 2px 1px rgba(0, 0, 0, 1);
}
.headlineshadow {
text-shadow: 0 2px 1px rgba(0, 0, 0, 1);
}
.spaceup {
margin-top: 4rem;
}
a {
text-decoration: underline;
transition: all 0.2s ease-in-out;
@ -489,10 +496,6 @@ a {
margin: 1.5rem;
}
.whitebg {
color: var(--text-color);
}
.nowrap {
white-space: nowrap;
}
@ -670,13 +673,12 @@ a {
text-shadow: 0 2px 1px rgba(0, 100, 125, 1);
}
.contentitem.invertedbox header h1 {
.contentitem header.whitebg h1 {
color: #4e8595;
text-shadow: none;
}
.contentitem header h1 em,
section.invertedbox h2 em {
.contentitem header h1 em {
font-style: normal;
font-weight: 400;
}
@ -700,12 +702,16 @@ section.invertedbox h2 em {
font-weight: 500;
}
.contentitem div.opaque h2 span.halfbubble {
h2 span.halfbubble {
height: 22px;
width: 11px;
border-bottom-right-radius: 11px;
border-top-right-radius: 11px;
display: inline-block;
margin: 0 0.7rem -0.25rem 0;
}
div.opaque h2 span.halfbubble {
margin: 0 0.7rem -0.25rem -1.25rem;
}
@ -733,7 +739,7 @@ section.invertedbox h2 em {
background-image: url('img/play-btn.svg');
background-position: center center;
background-repeat: no-repeat;
background-size: 4rem;
background-size: 80px 80px;
box-shadow: 0px 0px 6px rgba(0,0,0,0.3);
}
.paused-animation img {
@ -774,6 +780,7 @@ article.album a {
width: 100%;
height: 120px;
color: var(--text-color);
text-decoration: none;
}
article.album h2 {
@ -838,14 +845,63 @@ article.album a:hover {
height: 160px;
}
.track h2 {
font-size: 1.2em;
}
.track .halfbubble {
margin-bottom: -0.125em;
}
.track-player {
margin: 0.5rem 0 1.5rem;
}
.track-player .track-container {
width: 400px;
height: 80px;
border-radius: 0.3rem;
}
.track-player .track-played, .track-player .track-unplayed {
height: 100%;
float: left;
background-repeat: no-repeat;
background-size: 400px 80px;
}
.track-player .play-button {
display: block;
height: 80px;
width: 80px;
float: right;
background-position: center center;
background-repeat: no-repeat;
background-size: contain;
cursor: pointer;
}
.track-player .play-button.play {
background-image: url('img/track-play.svg');
}
.track-player .play-button.pause {
background-image: url('img/track-pause.svg');
}
.track-player .track-played {
width: 0%;
background-position: top left;
background-image: none;
}
.track-player .track-unplayed {
background-position: top right;
width: 100%;
background-image: none;
}
/* backgrounds */
.whitebg {
background-color: white;
color: var(--text-color);
}
.blurgreen {
background-color: #437888;
background-color: #1e3f2d;
background-image: url('img/bg_blur.webp');
background-repeat: no-repeat;
background-attachment: fixed;

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Binary file not shown.