您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
An automatic and free score downloader for musescore
- // ==UserScript==
- // @name Musescore Free PDF Downloader
- // @namespace http://tampermonkey.net/
- // @version 1.0
- // @author malatia
- // @match https://musescore.com/*/*
- // @icon https://www.google.com/s2/favicons?sz=64&domain=musescore.com
- // @grant GM_addStyle
- // @require https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js
- // @require https://cdnjs.cloudflare.com/ajax/libs/pdf-lib/1.16.0/pdf-lib.min.js
- // @description An automatic and free score downloader for musescore
- // @license MIT
- // ==/UserScript==
- // Idea from MuseScore Download By flancast90
- let DEBUG = true
- GM_addStyle(`.glowbutton {
- --glow-color: rgb(176, 252, 255);
- --glow-spread-color: rgba(123, 251, 255, 0.781);
- --enhanced-glow-color: rgb(206, 255, 255);
- --btn-color: rgb(61, 127, 136);
- border: 0.25em solid var(--glow-color);
- padding: 1em 1em;
- color: var(--glow-color);
- font-size: 15px;
- font-weight: bold;
- background-color: var(--btn-color);
- border-radius: 1em;
- outline: none;
- box-shadow: 0 0 1em 0.25em var(--glow-color),
- 0 0 4em 1em var(--glow-spread-color),
- inset 0 0 0.75em 0.25em var(--glow-color);
- text-shadow: 0 0 0.5em var(--glow-color);
- position: relative;
- transition: all 0.3s;
- }
- .glowbutton::after {
- pointer-events: none;
- content: "";
- position: absolute;
- top: 120%;
- left: 0;
- height: 100%;
- width: 100%;
- background-color: var(--glow-spread-color);
- filter: blur(2em);
- opacity: 0.7;
- transform: perspective(1.5em) rotateX(35deg) scale(1, 0.6);
- }
- .glowbutton:hover {
- color: var(--btn-color);
- background-color: var(--glow-color);
- box-shadow: 0 0 1em 0.25em var(--glow-color),
- 0 0 4em 2em var(--glow-spread-color),
- inset 0 0 0.75em 0.25em var(--glow-color);
- }
- .glowbutton:active {
- box-shadow: 0 0 0.6em 0.25em var(--glow-color),
- 0 0 2.5em 2em var(--glow-spread-color),
- inset 0 0 0.5em 0.25em var(--glow-color);
- }
- `)
- async function img_to_canvas_to_bytes(img) {
- return new Promise((resolve, reject) => {
- // Création d'un canvas pour dessiner l'image
- const canvas = document.createElement('canvas');
- const ctx = canvas.getContext('2d');
- // Chargement de l'image dans le canvas
- img.crossOrigin = 'Anonymous'; // Permet d'accéder à l'image cross-origin
- img.onload = () => {
- canvas.width = img.width;
- canvas.height = img.height;
- ctx.drawImage(img, 0, 0);
- // Conversion du contenu du canvas en données PNG
- const pngBytes = canvas.toDataURL('image/png').split(',')[1];
- resolve(pngBytes);
- };
- img.onerror = () => {
- reject(new Error('Échec du chargement de l\'image.'));
- };
- img.src = img.src; // Déclenche le chargement de l'image
- });
- }
- async function fetchAndAssemblePDF(urls) {
- // Création d'un nouveau document PDF
- const pdfDoc = await PDFLib.PDFDocument.create();
- // Tableau pour stocker les documents PNG générés
- const pngDocs = [];
- // Parcours de chaque URL de fichier img
- console.log("Avant boucle urls")
- for (const url of urls) {
- console.log("url = " + url)
- // Récupération du fichier img à partir de l'URL
- const response = await fetch(url);
- console.log(response)
- const imgText = await response.text();
- if (url.includes(".svg")) {
- const img = new Image();
- const imgLoaded = new Promise((resolve, reject) => {
- img.onload = resolve;
- img.onerror = reject;
- });
- // Création d'un blob à partir du texte SVG
- const svgBlob = new Blob([imgText], { type: 'image/svg+xml' });
- // Création d'une image à partir du blob SVG
- img.src = URL.createObjectURL(svgBlob);
- // Attente du chargement complet de l'image
- try {
- // Attendre le chargement complet de l'image
- await imgLoaded;
- console.log("Image SVG chargée avec succès");
- } catch (error) {
- console.error("Erreur lors du chargement de l'image SVG:", error);
- continue; // Passe à l'itération suivante dans la boucle
- }
- // Création d'un canvas pour dessiner l'image SVG
- const canvas = document.createElement('canvas');
- canvas.width = img.width;
- canvas.height = img.height;
- const ctx = canvas.getContext('2d');
- ctx.drawImage(img, 0, 0);
- // Conversion du canvas en format PNG
- const pngBytes = canvas.toDataURL('image/png').split(',')[1];
- // Incorporation du PNG dans le document PDF
- const pngDoc = await pdfDoc.embedPng(pngBytes);
- pngDocs.push(pngDoc); // Ajout du document PNG au tableau
- }
- else if (url.includes(".png")) {
- console.log("Dans la partie PNG");
- const img = new Image();
- const imgLoaded = new Promise((resolve, reject) => {
- img.onload = resolve;
- img.onerror = reject;
- });
- // Chargement de l'image à partir de l'URL
- img.src = url;
- // Promesse basée sur le chargement complet de l'image
- try {
- // Attendre le chargement complet de l'image
- await imgLoaded;
- console.log("Image PNG chargée avec succès");
- } catch (error) {
- console.error("Erreur lors du chargement de l'image PNG:", error);
- continue; // Passe à l'itération suivante dans la boucle
- }
- const pngBytes = await img_to_canvas_to_bytes(img)
- // Incorporation de l'image PNG dans le document PDF
- const pngDoc = await pdfDoc.embedPng(pngBytes);
- pngDocs.push(pngDoc);
- }
- }
- // Parcours des documents PNG pour les ajouter au document PDF
- for (const pngDoc of pngDocs) {
- const page = pdfDoc.addPage([pngDoc.width, pngDoc.height]);
- page.drawImage(pngDoc, {
- x: 0,
- y: 0,
- width: pngDoc.width,
- height: pngDoc.height,
- });
- }
- // Enregistrement du document PDF
- const pdfBytes = await pdfDoc.save();
- // Téléchargement du PDF
- const blob = new Blob([pdfBytes], { type: 'application/pdf' });
- const link = document.createElement('a');
- link.href = window.URL.createObjectURL(blob);
- let title = document.title.replace(" ", "_") + ".pdf"
- link.download = title;
- link.click();
- }
- let scrolled = 0;
- let urls = [];
- let height;
- let scrollHeight;
- let scrollContainer
- $(document).ready(async function () {
- setTimeout(() => {
- // ICI ON PARLE DU CONTENANT AVEC SCROLL
- scrollContainer = parseInt(document.getElementById('jmuse-scroller-component').scrollHeight);
- // ICI ON PARLE DES IMAGES
- height = parseInt(document.getElementsByClassName('KfFlO')[0].height);
- scrollHeight = (scrollContainer - (scrollContainer % height));
- // On cherche le bouton downlad de base pour le remplacer par le nôtre
- const btns = [...document.getElementsByTagName("button")]
- btns.filter(el => {
- const val = el.attributes.getNamedItem("name")?.value
- return val == "download"
- }).forEach(el => {
- const type = el.attributes.getNamedItem("name").value
- const fakeEl = el.cloneNode(true)
- // fakeEl.style.border = "2px #0dbc79 solid"
- fakeEl.value = "Download Free PDF"
- fakeEl.classList.add("glowbutton")
- // fakeEl.style.webkitBoxShadow = "0px 0px 127px 65px rgba(45,255,196,0.8);"
- // fakeEl.style.mozBoxShadow = "0px 0px 127px 65px rgba(45,255,196,0.8);;"
- // fakeEl.style.BoxShadow = "0px 0px 127px 65px rgba(45,255,196,0.8);"
- fakeEl.class =
- fakeEl.onclick = download_pdf
- el.parentNode.replaceChild(fakeEl, el)
- })
- }, 2000)
- // function get_lazy_imgs() {
- // // Fonction récursive pour récupérer les images
- // while (scrolled < scrollHeight) {
- // // Attendre un peu avant de récupérer les images
- // setTimeout(() => {
- // // Faire défiler la fenêtre
- // console.log("Scrolled : " + scrolled)
- // console.log("scrollHeight : " + scrollHeight)
- // scrollContainer.scrollTop = scrolled;
- // scrolled += height;
- // if (DEBUG) console.log("Get_lazy")
- // // Récupérer les images
- // let images = document.getElementsByClassName('KfFlO');
- // if (images.length > 0) {
- // urls.push(images[images.length - 1].src);
- // }
- // }, 1000);
- // }
- // }
- function get_lazy_imgs() {
- console.log("Début get_lazy_images");
- return new Promise((resolve, reject) => {
- // Fonction récursive pour récupérer les images
- function fetchImages() {
- scrollContainer = document.getElementById('jmuse-scroller-component');
- scrollHeight = scrollContainer.scrollHeight;
- if (scrolled < scrollHeight) {
- // Faire défiler la fenêtre
- scrollContainer.scrollTop = scrolled;
- scrolled += height;
- // Attendre un peu avant de récupérer les images
- setTimeout(() => {
- // Récupérer les images
- const images = document.getElementsByClassName('KfFlO');
- if (images.length > 0) {
- // Ajouter les URLs des images au tableau
- urls.push(images[images.length - 1].src);
- }
- // Rappel récursif jusqu'à ce que le scroll atteigne la fin
- fetchImages();
- }, 1000);
- } else {
- // Résoudre la promesse avec les URLs des images
- resolve(urls);
- console.log("Fin get_lazy_images");
- }
- }
- // Début de la récupération des images
- fetchImages();
- });
- }
- async function download_pdf() {
- console.log("Avant get_lazy_images");
- await get_lazy_imgs(); // Attendre la récupération de toutes les URLs d'images
- console.log("Après get_lazy_images");
- console.log("Avant fetchAndAssemble");
- await fetchAndAssemblePDF(urls); // Utiliser les URLs pour générer le PDF
- console.log("Après fetchAndAssemble");
- scrolled = 0; // Réinitialiser le défilement
- }
- });