MyAnimeList(MAL) - Thumbnail Switch

When on an anime/manga/character page, you will automatically cycle through other available pictures.

  1. // ==UserScript==
  2. // @name MyAnimeList(MAL) - Thumbnail Switch
  3. // @namespace https://greasyfork.org/users/16080
  4. // @version 1.0.4
  5. // @description When on an anime/manga/character page, you will automatically cycle through other available pictures.
  6. // @author Cpt_mathix
  7. // @match https://myanimelist.net/anime/*
  8. // @match https://myanimelist.net/manga/*
  9. // @match https://myanimelist.net/character/*
  10. // @match https://myanimelist.net/anime.php?*
  11. // @match https://myanimelist.net/manga.php?*
  12. // @match https://myanimelist.net/character.php?*
  13. // @exclude /^https?:\/\/myanimelist\.net\/(anime|manga|character)\/[^0-9]+/
  14. // @grant none
  15. // ==/UserScript==
  16.  
  17. (function() {
  18. 'use strict';
  19.  
  20. // find image in html + get anime/manga/character id
  21. let anchor = document.getElementById("addtolist") || document.getElementById("profileRows");
  22. let canvas = anchor.parentElement.firstElementChild.firstElementChild;
  23. let image = canvas.firstElementChild;
  24. let id = canvas.href.match(/\/\d+\//g)[0].replace(/\//g, "");
  25.  
  26. // get type (anime/manga/character)
  27. let type;
  28. if (/https:\/\/myanimelist.net\/anime\/.*/.test(canvas.href)) {
  29. type = "anime";
  30. } else if (/https:\/\/myanimelist.net\/manga\/.*/.test(canvas.href)) {
  31. type = "manga";
  32. } else if (/https:\/\/myanimelist.net\/character\/.*/.test(canvas.href)) {
  33. type = "characters";
  34. }
  35.  
  36. // remove default click behavior
  37. canvas.href = "javascript:;";
  38.  
  39. // change some styling for image cycling
  40. canvas.style.position = "relative";
  41. canvas.style.height = "350px";
  42. canvas.style.display = "block";
  43. image.style.transition = "opacity 1s ease-in-out";
  44.  
  45. let curr = 0;
  46. let images = null;
  47.  
  48. // fetch all images for given type and id
  49. fetch('https://api.jikan.moe/v4/' + type + '/' + id + '/pictures').then(function(response) {
  50. return response.json();
  51. }).then(function(json) {
  52. images = json.data;
  53.  
  54. // shuffle images in random order
  55. for (let i = images.length - 1; i > 0; i--) {
  56. const j = Math.floor(Math.random() * (i + 1));
  57. [images[i], images[j]] = [images[j], images[i]];
  58. }
  59.  
  60. // make sure that the first random image is not the default image
  61. if (images[0].small === image.src) {
  62. images.push(images.shift());
  63. }
  64.  
  65. cycle();
  66.  
  67. // cycle through images each 3000ms (3s)
  68. setInterval(cycle, 3000);
  69. });
  70.  
  71. // cycle when clicking
  72. canvas.addEventListener("click", function(event) {
  73. event.preventDefault();
  74.  
  75. if (images) {
  76. cycle();
  77. }
  78. });
  79.  
  80. function cycle() {
  81. if (++curr === images.length) {
  82. curr = 0;
  83. }
  84.  
  85. let new_image = document.createElement("img");
  86. new_image.classList.add("ac");
  87. new_image.setAttribute("style", "width: 100%; max-height: 350px; position: absolute; opacity: 1; transition: opacity 1s ease-in-out;");
  88. new_image.onload = function() {
  89. canvas.insertBefore(new_image, canvas.firstChild);
  90. canvas.children[0].style.opacity = 100;
  91. canvas.children[1].style.opacity = 0;
  92.  
  93. setTimeout(function() {
  94. canvas.children[0].style.position = "";
  95. canvas.children[1].remove()
  96. }, 1000);
  97. }
  98.  
  99. let next_image_src = images[curr].jpg.image_url;
  100. new_image.src = next_image_src;
  101. }
  102. })();