Furaffinity-Submission-Image-Viewer

Library for creating custom image elements on Furaffinity

当前为 2024-04-19 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/492931/1362748/Furaffinity-Submission-Image-Viewer.js

  1. // ==UserScript==
  2. // @name Furaffinity-Submission-Image-Viewer
  3. // @namespace Violentmonkey Scripts
  4. // @grant none
  5. // @version 1.0.0
  6. // @author Midori Dragon
  7. // @description Library for creating custom image elements on Furaffinity
  8. // @icon https://www.furaffinity.net/themes/beta/img/banners/fa_logo.png?v2
  9. // @homepageURL
  10. // @supportURL
  11. // @license MIT
  12. // ==/UserScript==
  13.  
  14. // jshint esversion: 8
  15.  
  16. (() => {
  17. class CustomImageViewer {
  18. constructor(imageUrl, previewUrl) {
  19. this.imageUrl = imageUrl;
  20. this.previewUrl = previewUrl;
  21. this.parentContainer;
  22. this.faImage;
  23. this.faImagePreview;
  24.  
  25. this.onImageLoad;
  26. this.onImageLoadStart;
  27. this.onPreviewImageLoad;
  28.  
  29. this.reset();
  30. this.hasReset = true;
  31. }
  32.  
  33. reset() {
  34. if (!this.faImage) {
  35. this.faImage = document.createElement('img', { is: 'fa-image' });
  36. this.faImage.addEventListener("load", () => {
  37. this.faImagePreview.parentNode.removeChild(this.faImagePreview);
  38. this.parentContainer.appendChild(this.faImage);
  39. this.faImage.style.visibility = "visible";
  40. this.hasReset = false;
  41. if (this.onImageLoad)
  42. this.onImageLoad();
  43. });
  44. }
  45. this.faImage.src = this.imageUrl;
  46. this.faImage.dataPreviewSrc = this.previewUrl;
  47. this.faImage.style.visibility = "hidden";
  48. this.faImage.style.objectFit = "cover";
  49.  
  50. if (this.previewUrl) {
  51. if (!this.faImagePreview)
  52. this.faImagePreview = document.createElement('img', { is: 'fa-image' });
  53. this.faImagePreview.src = this.previewUrl;
  54. this.faImagePreview.style.objectFit = "cover";
  55. this.faImagePreview.style.imageRendering = "pixelated";
  56. this.faImagePreview.addEventListener("load", () => {
  57. if (this.onPreviewImageLoad)
  58. this.onPreviewImageLoad();
  59. });
  60. }
  61. }
  62.  
  63. async load(parentContainer) {
  64. if (parentContainer)
  65. this.parentContainer = parentContainer;
  66. if (this.hasReset === false)
  67. this.reset();
  68.  
  69. const invisibleContainer = document.createElement('div');
  70. invisibleContainer.style.width = "0px";
  71. invisibleContainer.style.height = "0px";
  72. invisibleContainer.style.overflow = "hidden";
  73. invisibleContainer.appendChild(this.faImage);
  74. document.body.appendChild(invisibleContainer);
  75. if (this.previewUrl) {
  76. await new Promise((resolve, reject) => {
  77. const intervalId = setInterval(() => {
  78. if (this.faImage.offsetWidth != 0) {
  79. clearInterval(intervalId);
  80. this.faImagePreview.style.width = this.faImage.offsetWidth + "px";
  81. this.faImagePreview.style.height = this.faImage.offsetHeight + "px";
  82. parentContainer.appendChild(this.faImagePreview);
  83. if (this.onImageLoadStart)
  84. this.onImageLoadStart();
  85. resolve();
  86. }
  87. }, 10);
  88. });
  89. }
  90. }
  91. }
  92.  
  93. class FAImage extends HTMLImageElement {
  94. constructor() {
  95. super();
  96. }
  97.  
  98. get dataFullviewSrc() {
  99. return this.getAttribute('data-fullview-src');
  100. }
  101. set dataFullviewSrc(value) {
  102. this.setAttribute('data-fullview-src', value);
  103. }
  104.  
  105. get dataPreviewSrc() {
  106. return this.getAttribute('data-preview-src');
  107. }
  108. set dataPreviewSrc(value) {
  109. this.setAttribute('data-preview-src', value);
  110. }
  111.  
  112. set src(value) {
  113. super.src = value;
  114. this.dataFullviewSrc = value;
  115. }
  116. }
  117. customElements.define('fa-image', FAImage, { extends: 'img' });
  118. window.CustomImageViewer = CustomImageViewer;
  119. })();