kkul

ipod-player.js

Dec 10th, 2025 (edited)
20
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.99 KB | Music | 0 0
  1. // ipod-player.js by kkul.neocites.org
  2.  
  3. // ---- CONFIG: list of songs (title, artist, cover URL, optional tooltip) ----
  4. const songs = [
  5. {
  6. title: "your song name goes here",
  7. artist: "your artist goes here",
  8. cover: "/path/to-your-picture.jpeg",
  9. tooltip: "song name ♡ artist name"
  10. },
  11. {
  12. title: "your song name goes here",
  13. artist: "your artist goes here",
  14. cover: "/path/to-your-picture.jpeg",
  15. tooltip: "song name ♡ artist name"
  16. },
  17. {
  18. title: "your song name goes here",
  19. artist: "your artist goes here",
  20. cover: "/path/to-your-picture.jpeg",
  21. tooltip: "song name ♡ artist name"
  22. },
  23. {
  24. title: "your song name goes here",
  25. artist: "your artist goes here",
  26. cover: "/path/to-your-picture.jpeg",
  27. tooltip: "song name ♡ artist name"
  28. }
  29. ];
  30.  
  31. // ---- Helper: pick a random index not equal to previous ----
  32. let previousIndex = -1;
  33. function getRandomSongIndex() {
  34. if (songs.length === 0) return -1;
  35. if (songs.length === 1) return 0;
  36.  
  37. let index = Math.floor(Math.random() * songs.length);
  38. while (index === previousIndex) {
  39. index = Math.floor(Math.random() * songs.length);
  40. }
  41. previousIndex = index;
  42. return index;
  43. }
  44.  
  45. // ---- TOOLTIP + MARQUEE setup function ----
  46. function setMarqueeText(container, text, tooltipText) {
  47. if (!container) return;
  48.  
  49. const safeText = String(text ?? "");
  50.  
  51. // --- Marquee track with two copies for looping ---
  52. container.innerHTML = `
  53. <div class="marquee-track">
  54. <span>${safeText}</span>
  55. <span>${safeText}</span>
  56. </div>
  57. `;
  58.  
  59. // --- TOOLTIP: ONLY set title on the song-name container ---
  60. if (container.classList.contains("song-name")) {
  61. // set title to either custom tooltip or the song text
  62. container.setAttribute("title", tooltipText || safeText);
  63.  
  64. // --- IMPORTANT: initialize SMT tooltip on this container (only once) ---
  65. // The site's plugin normally runs on selected elements at page load (e.g. $("a[title]")...),
  66. // so dynamically-added title attributes on other elements need the plugin attached.
  67. try {
  68. // if jQuery + style_my_tooltips exist, call it on this element
  69. if (window.jQuery && typeof jQuery.fn.style_my_tooltips === "function") {
  70. // avoid double-initializing by checking a class flag we set
  71. if (!container.classList.contains("smt-initialized")) {
  72. // use the same options your site uses for other elements
  73. jQuery(container).style_my_tooltips({
  74. tip_follows_cursor: true,
  75. tip_delay_time: 90,
  76. tip_fade_speed: 600,
  77. attribute: "title"
  78. });
  79. container.classList.add("smt-initialized");
  80. } else {
  81. // already initialized previously — plugin reads title on mouseover, so nothing else needed
  82. }
  83. }
  84. } catch (e) {
  85. // if anything fails, silently continue (native title will still exist as fallback)
  86. // console.warn("smt init failed", e);
  87. }
  88. } else {
  89. // ensure artist (or others) do NOT have title set
  90. container.removeAttribute("title");
  91. }
  92.  
  93. // restart CSS animation after DOM update
  94. const track = container.querySelector(".marquee-track");
  95. if (track) {
  96. track.style.animation = "none";
  97. void track.offsetWidth;
  98. track.style.animation = "";
  99. }
  100.  
  101. // Pause animation on hover (attach to container — static element)
  102. if (!container._hoverFixed) {
  103. container._hoverFixed = true;
  104.  
  105. container.addEventListener("mouseenter", () => {
  106. if (track) track.style.animationPlayState = "paused";
  107. });
  108. container.addEventListener("mouseleave", () => {
  109. if (track) track.style.animationPlayState = "running";
  110. });
  111.  
  112. // also support touch devices
  113. container.addEventListener("touchstart", () => {
  114. if (track) track.style.animationPlayState = "paused";
  115. }, { passive: true });
  116. container.addEventListener("touchend", () => {
  117. if (track) track.style.animationPlayState = "running";
  118. }, { passive: true });
  119. }
  120. }
  121.  
  122. // ---- Update the DOM to show the chosen song ----
  123. function updateSong() {
  124. const index = getRandomSongIndex();
  125. if (index === -1) return;
  126.  
  127. const song = songs[index];
  128.  
  129. // album art element (background-image)
  130. const art = document.querySelector(".album-art");
  131. if (art) {
  132. art.style.backgroundImage = `url("${song.cover}")`;
  133. }
  134.  
  135. // song title container
  136. const titleContainer = document.querySelector(".song-name");
  137. if (titleContainer) {
  138. setMarqueeText(titleContainer, song.title, song.tooltip);
  139. }
  140.  
  141. // artist container (no tooltip)
  142. const artistContainer = document.querySelector(".artist");
  143. if (artistContainer) {
  144. setMarqueeText(artistContainer, song.artist, null);
  145. }
  146. }
  147.  
  148. // ---- Initialize on DOM ready ----
  149. document.addEventListener("DOMContentLoaded", () => {
  150. updateSong();
  151.  
  152. // Change every 1 hour (3600000 ms)
  153. // setInterval(updateSong, 5000); // <-- use for testing only
  154. setInterval(updateSong, 3600000);
  155. });
Advertisement
Add Comment
Please, Sign In to add comment