您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Flatpick is a userscript to enable download SVG and copy SVG on flaticon.com for free user it's open the premium button. Not affiliated with flaticon. Use at your own risk.
// ==UserScript== // @name flatpick // @namespace https://gf.qytechs.cn/en/users/1508660-frrzyriq // @version 1.1 // @description Flatpick is a userscript to enable download SVG and copy SVG on flaticon.com for free user it's open the premium button. Not affiliated with flaticon. Use at your own risk. // @author frrzyriq // @match https://flaticon.com // @match https://www.flaticon.com/* // @icon https://media.flaticon.com/dist/min/img/favicon.ico // @grant none // @run-at document-end // @noframes // @copyright 2025, frrzyriq (https://gf.qytechs.cn/en/users/1508660-frrzyriq) // @license MIT // ==/UserScript== (function () { 'use strict'; const FLATICON_PAYLOAD = 'MGUxODE1MDQwMzUzNGM0NDU3MTQwNTRmMDUwNzQxMTIwNTAyMWIwNzRkMGMwMTRkNGQxYzQ0MGYwNjFkMDg1NjFiMGExZTA4NDMxMjAyMTc0NjU5MDI0NDVjMDYxODEzMGUxZDE1MTgwMDFhMGQwMjFkMGE=' const claves = "66 6C 61 74 70 69 63 6B 20 63 72 61 63 6B 20 66 6C 61 74 69 63 6F 6E 20 62 79 20 66 72 72 7A 79 72 69 71".split(" ").map(h => parseInt(h, 16).toString(16).padStart(2, '0')); const inspect = () => { return atob(FLATICON_PAYLOAD).match(/.{1,2}/g).map((h, i) => String.fromCharCode(parseInt(h, 16) ^ parseInt(claves[i % claves.length], 16))).join(""); } const watchAttrChange = (selector, callbackFun) => { const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; const observer = new MutationObserver((mutations) => { callbackFun(mutations); }); setInterval(() => { const watchSelector = document.querySelector(selector); if (watchSelector && !watchSelector.classList.contains('hidden')) { observer.observe(watchSelector, { attributes: true }); } setTimeout(() => { callbackFun([]); }, 500); }, 100); }; const watchElementChange = (selector, callbackFun) => { const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; const observer = new MutationObserver((mutations) => { callbackFun(mutations); }); observer.observe(document.querySelector(selector), { childList: true, subtree: true }); }; const watchMouseEnter = (selector, callbackFun) => { const elements = document.querySelectorAll(selector); elements.forEach((el) => { el.addEventListener('mouseenter', (event) => { callbackFun(event); }); }); }; const revokeIcon = async (iconId) => { const req = await fetch( inspect().replace(':id', iconId) ); const data = await req.json(); const raw = await fetch(data.url); return raw; } const downloadSVG = async (iconId) => { const data = await revokeIcon(iconId); const blob = await data.blob(); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.style.display = 'none'; a.href = url; a.download = `${iconId}.svg`; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); } const copySVG = async (iconId) => { const data = await revokeIcon(iconId); const svgText = await data.text(); navigator.clipboard.writeText(svgText).then(() => { alert('SVG copied to clipboard'); }); } const removePremIcon = (element, color = 2) => { const premIcon = element.querySelector('.icon.icon--crown-filled'); element.classList.remove('btn-warning'); switch (color) { case 1: element.classList.add('bj-button--green'); break; case 2: element.classList.add('bj-button--secondary'); break; case 3: element.classList.add('bj-button--primary'); break; default: element.classList.add('btn-warning'); } premIcon?.remove(); } const removeSVGpremDownloadOverlayHover = (element) => { element.classList.add('fsd-attached'); const iconId = parseInt(element.getAttribute('data-id'), 10); const ctxm = element.querySelector('.icon--item__context-menu'); const downloadOpt = ctxm.lastElementChild; const svgDownloadBtn = downloadOpt.querySelector('.GA_CM_download-svg>button'); svgDownloadBtn.onclick = () => downloadSVG(iconId); removePremIcon(svgDownloadBtn, 3); } const removeSVGandCopyPremDownloadOverlay = () => { const downloadSection = document.querySelector('section#detail'); const iconId = parseInt(downloadSection.getAttribute('data-elementid'), 10); const downloadBtn = downloadSection.querySelector('.btn-svg.btn,.btn-svg'); if (downloadBtn) { removePremIcon(downloadBtn, 3); downloadBtn.onclick = () => downloadSVG(iconId); } const copySvgBtn = downloadSection.querySelector('.btn-copy>.copysvg--button'); if (copySvgBtn) { removePremIcon(copySvgBtn, 2); copySvgBtn.onclick = () => copySVG(iconId); } } const initFlatpick = () => { watchMouseEnter('li.icon--item:not(.fsd-attached)', (event) => { removeSVGpremDownloadOverlayHover(event.currentTarget); }); watchAttrChange('#detail-overlay', (mutations) => { mutations.filter(({ attributeName }) => attributeName === 'class').forEach(({ target }) => { if (target.classList.contains('ready')) { watchElementChange('#detail-content', (mutations) => { removeSVGandCopyPremDownloadOverlay() }); } }); if (mutations.length === 0 && document.querySelector('section#detail') !== null) { removeSVGandCopyPremDownloadOverlay(); } }); } const alertLoginRequired = () => { const buttonLogin = document.querySelector('a.btn-login'); if (!buttonLogin) return; const alertDiv = document.createElement('div'); Object.assign(alertDiv.style, { width: 'fit-content', position: 'fixed', display: 'flex', alignItems: 'center', gap: '6px', top: '80px', right: '10px', backgroundColor: '#f44336', color: 'white', padding: '12px 15px', zIndex: '9999', borderRadius: '6px', }); alertDiv.innerHTML = `<p style="margin:0;"><b>Flatpick:</b> <i>Please log in to use this script.</i></p>`; const cloneLogin = buttonLogin.cloneNode(true); alertDiv.appendChild(cloneLogin); const closeBtn = document.createElement('button'); closeBtn.className = 'btn-close-flatpick'; closeBtn.innerHTML = ` <svg xmlns="http://www.w3.org/2000/svg" width="24" viewBox="0 0 640 640" fill="#fff"><!--!Font Awesome Free v7.0.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M183.1 137.4C170.6 124.9 150.3 124.9 137.8 137.4C125.3 149.9 125.3 170.2 137.8 182.7L275.2 320L137.9 457.4C125.4 469.9 125.4 490.2 137.9 502.7C150.4 515.2 170.7 515.2 183.2 502.7L320.5 365.3L457.9 502.6C470.4 515.1 490.7 515.1 503.2 502.6C515.7 490.1 515.7 469.8 503.2 457.3L365.8 320L503.1 182.6C515.6 170.1 515.6 149.8 503.1 137.3C490.6 124.8 470.3 124.8 457.8 137.3L320.5 274.7L183.1 137.4z"/></svg>`; closeBtn.onclick = () => alertDiv.remove(); alertDiv.appendChild(closeBtn); if (!document.getElementById('flatpick-alert-style')) { const style = document.createElement('style'); style.id = 'flatpick-alert-style'; style.textContent = ` .btn-close-flatpick { all: unset; border-radius:24px; display: flex; align-items: center; justify-content: center; cursor: pointer; } `; document.head.appendChild(style); } document.body.appendChild(alertDiv); }; if (window.USER_REGISTERED) { window.addEventListener('popstate', function (event) { initFlatpick(); }); document.addEventListener("visibilitychange", () => { initFlatpick(); }); initFlatpick(); } else { alertLoginRequired(); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址