get-gaoding-material

获取搞定设计画布所有素材

安装此脚本
作者推荐脚本

您可能也喜欢remove-gaoding-watermark

安装此脚本
  1. // ==UserScript==
  2. // @name get-gaoding-material
  3. // @namespace get-gaoding-material
  4. // @version 1.0
  5. // @license MIT
  6. // @icon https://gd-filems.dancf.com/gaoding/gaoding/0/c012b037-b933-4364-96d0-c7ed4e1588984217369.png
  7. // @description 获取搞定设计画布所有素材
  8. // @author sertraline
  9. // @match https://www.gaoding.com/design*
  10. // @require https://cdn.staticfile.org/jquery/3.6.2/jquery.min.js
  11. // @grant GM_openInTab
  12. // @grant GM_download
  13. // ==/UserScript==
  14. const SOURCE_IMG_SELECTOR = '.design-editor img'
  15. const BTN_BOX_SELECTOR = `.editor-right-actions`
  16. const NAMESPACE = GM_info.script.namespace
  17. function uuid() {
  18. return Math.random().toString(36).substr(2)
  19. }
  20. function namespace(str) {
  21. return `${NAMESPACE}-${str}`
  22. }
  23.  
  24. let toasts = [];
  25. let $toastContainer;
  26. const TOAST_CONTAINER_SELECTOR = `#${namespace("toast")}`;
  27. function initToast() {
  28. if (!$toastContainer) {
  29. $toastContainer = $(TOAST_CONTAINER_SELECTOR);
  30. if (!$toastContainer.length) {
  31. const toast = `
  32. <div id="${namespace("toast")}" class="${namespace("toast")}">
  33. </div>
  34. `;
  35. $toastContainer = $(toast);
  36. $("body").append($toastContainer);
  37. }
  38. }
  39. }
  40.  
  41. function openToast(text, duration = 2000) {
  42. if (!text) return;
  43.  
  44. initToast();
  45. const id = namespace(uuid + "toast")
  46. const toast = {
  47. id,
  48. element: $.parseHTML(`
  49. <div id="${id}" class="${namespace("toast__item")}">
  50. ${text}
  51. </div>
  52. `),
  53. };
  54. toasts.push(toast);
  55.  
  56. $toastContainer.append(toast.element);
  57. setTimeout(() => {
  58. $(toast.element).remove();
  59. toasts = toasts.filter((t) => t.id !== toast.id);
  60. }, duration);
  61. }
  62.  
  63. let btnBoxLoaded = false
  64.  
  65. function createBtn(id, text, callback) {
  66. const element = document.querySelector(BTN_BOX_SELECTOR)
  67. if (!element) {
  68. const observer = new MutationObserver((mutationsList, observer) => {
  69. for (const mutation of mutationsList) {
  70. if (mutation.type === 'childList') {
  71. const element = document.querySelector(BTN_BOX_SELECTOR)
  72. if (element) {
  73. observer.disconnect()
  74. btnBoxLoaded = true
  75. createBtn(id, text, callback)
  76. }
  77. }
  78. }
  79. })
  80. observer.observe(document.body, {
  81. childList: true
  82. })
  83. return
  84. }
  85.  
  86. const _id = namespace(id)
  87. if (document.getElementById(_id)) return
  88.  
  89. const btn = `
  90. <div id="${_id}" class="${namespace('btns-item')}">${text}</div>
  91. `
  92. $(BTN_BOX_SELECTOR).append(btn)
  93. $(`#${_id}`).click(callback)
  94. }
  95.  
  96. function createDrawer() {
  97. const drawer = `
  98. <div id="${namespace('drawer')}" class="${namespace('drawer')}">
  99. <div id="${namespace('drawer__mask')}" class="${namespace('drawer__mask')}"></div>
  100. <div id="${namespace('drawer__wrap')}" class="${namespace('drawer__wrap')}">
  101. <div id="${namespace('drawer__info')}" class="${namespace('drawer__info')}">
  102. </div>
  103. <div id="${namespace('drawer__content')}" class="${namespace('drawer__content')}">
  104. </div>
  105. </div>
  106. </div>
  107. `
  108. $('body').append(drawer)
  109. $(`#${namespace('drawer__mask')}`).click(function () {
  110. hideDrawer()
  111. })
  112. $(`#${namespace('drawer__content')}`).click(function (e) {
  113. const target = e.target
  114. if ($(target).hasClass(namespace('drawer__pic')) || $(target).parent().hasClass(namespace('drawer__pic'))) {
  115. const src = $(target).find('img').attr('src') || $(target).attr('src')
  116. if (src.indexOf('http') !== 0) {
  117. GM_openInTab(src, { active: true })
  118. return
  119. }
  120. downloadImg(src)
  121. }
  122. })
  123. hideDrawer()
  124. }
  125. function clearDrawer() {
  126. const _contentId = namespace('drawer__content')
  127. if (!$(`#${_contentId}`).length) return
  128. $(`#${_contentId}`).empty()
  129. }
  130. function hideDrawer() {
  131. const _drawerId = namespace('drawer')
  132. if (!$(`#${_drawerId}`).length) return
  133. $(`#${_drawerId}`).fadeOut()
  134. }
  135. function showDrawer() {
  136. const _drawerId = namespace('drawer')
  137. if (!$(`#${_drawerId}`).length) return
  138. $(`#${_drawerId}`).fadeIn()
  139. }
  140. function updateDrawerInfo() {
  141. const len = $(`#${namespace('drawer__content')}`).children().length
  142. $(`#${namespace('drawer__info')}`).text(`共${len}个素材`)
  143. }
  144. function pushImgItem(src) {
  145. const img = `
  146. <div class="${namespace('drawer__pic')}">
  147. <div class="${namespace('drawer__type')}">${getFileTypeFromUrl(src) || '未知'}</div>
  148. <img src="${src}">
  149. </div>
  150. `
  151. $(`#${namespace('drawer__content')}`).append(img)
  152. }
  153.  
  154. function getNameFromUrl(url) {
  155. const SPLIT_REGEXP = /\/|\?/
  156. return new URL(url).pathname.split(SPLIT_REGEXP).pop()
  157. }
  158. function getFileTypeFromUrl(url) {
  159. const name = getNameFromUrl(url)
  160. const SPLIT_REGEXP = /\./
  161. const res = name.split(SPLIT_REGEXP)[1]
  162. return res ? res.toUpperCase() : null
  163. }
  164. function downloadImg(url) {
  165. const name = getNameFromUrl(url)
  166. GM_download({
  167. url,
  168. name,
  169. saveAs: true,
  170. onload: () => {
  171. openToast('下载成功')
  172. },
  173. onerror: () => {
  174. openToast('下载失败')
  175. }
  176. })
  177. }
  178. ; (function ($) {
  179. initStyles()
  180. createDrawer()
  181. createBtn(
  182. 'get-material',
  183. `<svg style="height: 20px;fill: #fff;marign-right: 5px" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M362.667 256H832a42.667 42.667 0 0142.667 42.667V896A42.667 42.667 0 01832 938.667H362.667A42.667 42.667 0 01320 896V298.667A42.667 42.667 0 01362.667 256zm42.666 85.333v512h384v-512h-384zm256-170.666H234.667v554.666h-85.334V128A42.667 42.667 0 01192 85.333h469.333v85.334z"></path></svg>获取素材`,
  184. function () {
  185. const sourceImgEls = document.querySelectorAll(SOURCE_IMG_SELECTOR)
  186. if (!sourceImgEls.length) {
  187. openToast('请等待页面加载完成')
  188. return
  189. }
  190. clearDrawer()
  191. sourceImgEls.forEach(el => {
  192. pushImgItem(el.src)
  193. })
  194. updateDrawerInfo()
  195. showDrawer()
  196. openToast('素材获取成功')
  197. }
  198. )
  199. })(jQuery)
  200.  
  201. function initStyles() {
  202. const styles = `
  203. <style>
  204. .${namespace('btns-item')} {
  205. margin-right: 10px;
  206. padding: 8px 16px;
  207. font-size: 14px;
  208. line-height: 24px;
  209. background: #2254f4;
  210. color: #fff;
  211. border-radius: 8px;
  212. cursor: pointer;
  213. display: flex;
  214. align-items: center;
  215. }
  216. .${namespace('drawer')}{
  217. position: fixed;
  218. bottom: 0;
  219. left: 0;
  220. z-index: 100000;
  221. }
  222. .${namespace('drawer__mask')}{
  223. position: fixed;
  224. top: 0;
  225. left: 0;
  226. z-index: 99998;
  227. background: rgba(0,0,0,0.5);
  228. width: 100vw;
  229. height: 100vh;
  230. }
  231. .${namespace('drawer__info')}{
  232. padding: 15px 20px;
  233. background: #fff;
  234. font-size: 14px;
  235. line-height: 20px;
  236. color: #333;
  237. border-bottom: 1px solid #eee;
  238. margin-bottom: 10px;
  239. }
  240. .${namespace('drawer__wrap')}{
  241. position: fixed;
  242. bottom: 0;
  243. left: 0;
  244. z-index: 99999;
  245. background: #fff;
  246. width: 300px;
  247. height: 100vh;
  248. }
  249. .${namespace('drawer__content')}{
  250. height: calc(100% - 60px);
  251. padding: 15px 20px;
  252. overflow-y: auto;
  253. }
  254. .${namespace('drawer__pic')}{
  255. width: 100%;
  256. height: 100px;
  257. background: #f1f2f4;
  258. margin-bottom: 10px;
  259. padding: 10px 5px;
  260. cursor: pointer;
  261. position: relative;
  262. border-radius: 8px;
  263. }
  264. .${namespace('drawer__type')}{
  265. position: absolute;
  266. bottom: 5px;
  267. right: 5px;
  268. background: #2254f4;
  269. color: #fff;
  270. padding: 2px 10px;
  271. font-size: 12px;
  272. line-height: 16px;
  273. }
  274. .${namespace('drawer__pic')} img{
  275. width: 100%;
  276. height: 100%;
  277. object-fit: contain;
  278. }
  279. .${namespace('toast')}{
  280. position: fixed;
  281. top: 50px;
  282. left: 50%;
  283. transform: translateX(-50%);
  284. display: flex;
  285. flex-direction: column;
  286. align-items: center;
  287. z-index: 99999999;
  288. }
  289. .${namespace('toast__item')}{
  290. padding: 10px 20px;
  291. background: rgba(0,0,0,0.5);
  292. color: #fff;
  293. border-radius: 5px;
  294. margin-bottom: 10px;
  295. }
  296. </style>
  297. `
  298. $('head').append(styles)
  299. }