User:Toad64/Sandbox: Difference between revisionsGive feedback
Jump to navigation
Jump to search
This code creates this (visually bugged but code is functional):
No edit summary |
IT WORKS |
||
| Line 1: | Line 1: | ||
<div class="my-custom-player-wrapper"> | <div class="my-custom-player-wrapper"><syntaxhighlight lang="javascript"> | ||
// gemini code | |||
// In your Common.js | |||
$(document).ready(function() { | |||
// Find every native audio player generated by the wiki | |||
$('audio').each(function() { | |||
// Create your custom component | |||
const myPlayer = document.createElement('audio-player'); | |||
// Transfer the source | |||
myPlayer.setAttribute('track', $(this).attr('src')); | |||
// Replace the native player with your custom one | |||
$(this).replaceWith(myPlayer); | |||
}); | |||
}); | |||
// audioplayer.js (pulled from website) | |||
if (!customElements.get('audio-player')) { | |||
class AudioPlayer extends HTMLElement { | |||
connectedCallback() { | |||
const song = this.getAttribute("song") || ""; | |||
const artist = this.getAttribute("artist") || ""; | |||
const src = this.getAttribute("track") || ""; | |||
const cover = this.getAttribute("artcover") || ""; | |||
const originalArtist = | |||
this.getAttribute("originalartist") || ""; | |||
const originalSource = | |||
this.getAttribute("originalsource") || ""; | |||
const ext = src.split(".").pop().toLowerCase(); | |||
let mime = "audio/mpeg"; | |||
if (ext === "wav") { | |||
mime = "audio/wav"; | |||
} | |||
this.innerHTML = ` | |||
<style> | |||
.player { | |||
display: flex; | |||
width: 100%; | |||
max-width: 500px; | |||
min-height: 150px; | |||
background: var(--box-color); | |||
color: white; | |||
border-radius: 12px; | |||
overflow: hidden; | |||
font-family: Arial, sans-serif; | |||
} | |||
.cover { | |||
width: 40%; | |||
object-fit: cover; | |||
background-color: #333; | |||
display: block; | |||
} | |||
.info { | |||
width: 60%; | |||
padding: 12px; | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: space-between; | |||
gap: 10px; | |||
} | |||
.meta { | |||
display: grid; | |||
grid-template-columns: 1fr 1fr; | |||
gap: 12px; | |||
} | |||
.leftmeta, | |||
.rightmeta { | |||
display: flex; | |||
flex-direction: column; | |||
gap: 4px; | |||
} | |||
h3 { | |||
margin: 0; | |||
font-size: 16px; | |||
} | |||
p { | |||
margin: 0; | |||
font-size: 12px; | |||
opacity: 0.7; | |||
} | |||
.credit { | |||
font-size: 11px; | |||
opacity: 0.6; | |||
line-height: 1.4; | |||
} | |||
.controls { | |||
display: flex; | |||
align-items: center; | |||
gap: 10px; | |||
width: 100%; | |||
} | |||
.playBtn { | |||
width: 24px; | |||
height: 24px; | |||
background: var(--green-color); | |||
border: none; | |||
color: white; | |||
padding: 3px 8px; | |||
border-radius: 50px; | |||
cursor: pointer; | |||
flex-shrink: 0; | |||
} | |||
.playBtn:hover { | |||
background: var(--green-hover); | |||
} | |||
.playBtn:active { | |||
background: var(--green-active); | |||
} | |||
.seek { | |||
-webkit-appearance: none; | |||
appearance: none; | |||
border-radius: 50px; | |||
flex: 1; | |||
background-color: #7e7e7e; | |||
height: 7px; | |||
min-width: 0; | |||
} | |||
.seek::-webkit-slider-thumb { | |||
-webkit-appearance: none; /* Override default look */ | |||
appearance: none; | |||
border-radius: 50px; | |||
width: 15px; | |||
height: 15px; | |||
background: var(--green-color); | |||
cursor: pointer; | |||
} | |||
.seek::-moz-range-thumb { | |||
border-radius: 50px; | |||
width: 15px; | |||
height: 15px; | |||
background: var(--green-color); | |||
cursor: pointer; | |||
} | |||
.time { | |||
font-size: 12px; | |||
opacity: 0.8; | |||
white-space: nowrap; | |||
} | |||
@media (max-width: 800px) { | |||
.player { | |||
flex-direction: column; | |||
} | |||
.cover { | |||
width: 100%; | |||
height: 180px; | |||
} | |||
.info { | |||
width: auto; | |||
} | |||
.meta { | |||
grid-template-columns: 1fr; | |||
} | |||
.controls { | |||
flex-wrap: wrap; | |||
} | |||
.time { | |||
width: 100%; | |||
} | |||
} | |||
</style> | |||
<div class="player"> | |||
<img class="cover" src="${cover}" alt="${song} cover art"> | |||
<div class="info"> | |||
<div class="meta"> | |||
<div class="leftmeta"> | |||
<h3>${song}</h3> | |||
<p>${artist}</p> | |||
</div> | |||
<div class="rightmeta"> | |||
<div class="credit"> | |||
Original Artist: ${originalArtist} | |||
</div> | |||
<div class="credit"> | |||
Original Source: ${originalSource} | |||
</div> | |||
</div> | |||
</div> | |||
<audio class="audio"> | |||
<source src="${src}" type="${mime}"> | |||
</audio> | |||
<div class="controls"> | |||
<button class="playBtn"><i class="fa-solid fa-play"></i></button> | |||
<input | |||
class="seek" | |||
type="range" | |||
value="0" | |||
min="0" | |||
max="100"> | |||
<span class="time">0:00 / 0:00</span> | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
// component-local elements | |||
const audio = this.querySelector(".audio"); | |||
const playBtn = this.querySelector(".playBtn"); | |||
const seek = this.querySelector(".seek"); | |||
const time = this.querySelector(".time"); | |||
// play / pause | |||
playBtn.addEventListener("click", () => { | |||
if (audio.paused) { | |||
audio.play(); | |||
playBtn.innerHTML = '⏸'; | |||
} else { | |||
audio.pause(); | |||
playBtn.innerHTML = '▶'; | |||
} | |||
}); | |||
// update seek bar + time | |||
audio.addEventListener("timeupdate", () => { | |||
seek.value = | |||
(audio.currentTime / audio.duration) * 100 || 0; | |||
time.textContent = | |||
formatTime(audio.currentTime) | |||
+ " / " + | |||
formatTime(audio.duration); | |||
}); | |||
// seeking | |||
seek.addEventListener("input", () => { | |||
audio.currentTime = | |||
(seek.value / 100) * audio.duration; | |||
}); | |||
// reset button when song ends | |||
audio.addEventListener("ended", () => { | |||
playBtn.innerHTML = '▶'; | |||
}); | |||
// format time helper | |||
function formatTime(sec) { | |||
if (isNaN(sec)) return "0:00"; | |||
const m = Math.floor(sec / 60); | |||
const s = Math.floor(sec % 60) | |||
.toString() | |||
.padStart(2, "0"); | |||
return `${m}:${s}`; | |||
} | |||
} | |||
} | |||
customElements.define("audio-player", AudioPlayer); | |||
} | |||
</syntaxhighlight>This code creates this (visually bugged but code is functional): | |||
[[File:Curio music.mp3]] | [[File:Curio music.mp3]] | ||
</div> | </div> | ||
Revision as of 21:22, 30 June 2026
// gemini code
// In your Common.js
$(document).ready(function() {
// Find every native audio player generated by the wiki
$('audio').each(function() {
// Create your custom component
const myPlayer = document.createElement('audio-player');
// Transfer the source
myPlayer.setAttribute('track', $(this).attr('src'));
// Replace the native player with your custom one
$(this).replaceWith(myPlayer);
});
});
// audioplayer.js (pulled from website)
if (!customElements.get('audio-player')) {
class AudioPlayer extends HTMLElement {
connectedCallback() {
const song = this.getAttribute("song") || "";
const artist = this.getAttribute("artist") || "";
const src = this.getAttribute("track") || "";
const cover = this.getAttribute("artcover") || "";
const originalArtist =
this.getAttribute("originalartist") || "";
const originalSource =
this.getAttribute("originalsource") || "";
const ext = src.split(".").pop().toLowerCase();
let mime = "audio/mpeg";
if (ext === "wav") {
mime = "audio/wav";
}
this.innerHTML = `
<style>
.player {
display: flex;
width: 100%;
max-width: 500px;
min-height: 150px;
background: var(--box-color);
color: white;
border-radius: 12px;
overflow: hidden;
font-family: Arial, sans-serif;
}
.cover {
width: 40%;
object-fit: cover;
background-color: #333;
display: block;
}
.info {
width: 60%;
padding: 12px;
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 10px;
}
.meta {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.leftmeta,
.rightmeta {
display: flex;
flex-direction: column;
gap: 4px;
}
h3 {
margin: 0;
font-size: 16px;
}
p {
margin: 0;
font-size: 12px;
opacity: 0.7;
}
.credit {
font-size: 11px;
opacity: 0.6;
line-height: 1.4;
}
.controls {
display: flex;
align-items: center;
gap: 10px;
width: 100%;
}
.playBtn {
width: 24px;
height: 24px;
background: var(--green-color);
border: none;
color: white;
padding: 3px 8px;
border-radius: 50px;
cursor: pointer;
flex-shrink: 0;
}
.playBtn:hover {
background: var(--green-hover);
}
.playBtn:active {
background: var(--green-active);
}
.seek {
-webkit-appearance: none;
appearance: none;
border-radius: 50px;
flex: 1;
background-color: #7e7e7e;
height: 7px;
min-width: 0;
}
.seek::-webkit-slider-thumb {
-webkit-appearance: none; /* Override default look */
appearance: none;
border-radius: 50px;
width: 15px;
height: 15px;
background: var(--green-color);
cursor: pointer;
}
.seek::-moz-range-thumb {
border-radius: 50px;
width: 15px;
height: 15px;
background: var(--green-color);
cursor: pointer;
}
.time {
font-size: 12px;
opacity: 0.8;
white-space: nowrap;
}
@media (max-width: 800px) {
.player {
flex-direction: column;
}
.cover {
width: 100%;
height: 180px;
}
.info {
width: auto;
}
.meta {
grid-template-columns: 1fr;
}
.controls {
flex-wrap: wrap;
}
.time {
width: 100%;
}
}
</style>
<div class="player">
<img class="cover" src="${cover}" alt="${song} cover art">
<div class="info">
<div class="meta">
<div class="leftmeta">
<h3>${song}</h3>
<p>${artist}</p>
</div>
<div class="rightmeta">
<div class="credit">
Original Artist: ${originalArtist}
</div>
<div class="credit">
Original Source: ${originalSource}
</div>
</div>
</div>
<audio class="audio">
<source src="${src}" type="${mime}">
</audio>
<div class="controls">
<button class="playBtn"><i class="fa-solid fa-play"></i></button>
<input
class="seek"
type="range"
value="0"
min="0"
max="100">
<span class="time">0:00 / 0:00</span>
</div>
</div>
</div>
`;
// component-local elements
const audio = this.querySelector(".audio");
const playBtn = this.querySelector(".playBtn");
const seek = this.querySelector(".seek");
const time = this.querySelector(".time");
// play / pause
playBtn.addEventListener("click", () => {
if (audio.paused) {
audio.play();
playBtn.innerHTML = '⏸';
} else {
audio.pause();
playBtn.innerHTML = '▶';
}
});
// update seek bar + time
audio.addEventListener("timeupdate", () => {
seek.value =
(audio.currentTime / audio.duration) * 100 || 0;
time.textContent =
formatTime(audio.currentTime)
+ " / " +
formatTime(audio.duration);
});
// seeking
seek.addEventListener("input", () => {
audio.currentTime =
(seek.value / 100) * audio.duration;
});
// reset button when song ends
audio.addEventListener("ended", () => {
playBtn.innerHTML = '▶';
});
// format time helper
function formatTime(sec) {
if (isNaN(sec)) return "0:00";
const m = Math.floor(sec / 60);
const s = Math.floor(sec % 60)
.toString()
.padStart(2, "0");
return `${m}:${s}`;
}
}
}
customElements.define("audio-player", AudioPlayer);
}