Canva Transparante Achtergrond Downloader

Download je Canva designs met transparante achtergrond zonder Pro versie

Size

8.6 KB

Version

1.1.4

Created

Oct 19, 2025

Updated

4 days ago

1// ==UserScript==
2// @name		Canva Transparante Achtergrond Downloader
3// @description		Download je Canva designs met transparante achtergrond zonder Pro versie
4// @version		1.1.4
5// @match		https://*.canva.com/*
6// @icon		https://static.canva.com/static/images/favicons/favicon_web_print.ico
7// @require		https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js
8// ==/UserScript==
9(function() {
10    'use strict';
11
12    console.log('Canva Transparante Achtergrond Downloader gestart');
13
14    // Debounce functie om te voorkomen dat de knop meerdere keren wordt toegevoegd
15    function debounce(func, wait) {
16        let timeout;
17        return function executedFunction(...args) {
18            const later = () => {
19                clearTimeout(timeout);
20                func(...args);
21            };
22            clearTimeout(timeout);
23            timeout = setTimeout(later, wait);
24        };
25    }
26
27    // Functie om de download knop toe te voegen
28    function addDownloadButton() {
29        // Check of de knop al bestaat
30        if (document.getElementById('transparent-download-btn')) {
31            console.log('Download knop bestaat al');
32            return;
33        }
34
35        // Zoek de toolbar container waar de "Delen" knop staat
36        const shareButtonContainer = document.querySelector('div._2WzgFw._8drCYA');
37        
38        if (!shareButtonContainer) {
39            console.log('Toolbar container nog niet gevonden, probeer later opnieuw');
40            return;
41        }
42
43        console.log('Toolbar container gevonden, voeg download knop toe');
44
45        // Maak een nieuwe container voor onze knop
46        const buttonWrapper = document.createElement('div');
47        buttonWrapper.className = '_7nAWcw';
48        buttonWrapper.id = 'transparent-download-btn';
49
50        // Maak de download knop met dezelfde styling als andere knoppen
51        const downloadButton = document.createElement('button');
52        downloadButton.className = '_5KtATA LQzFZw VgvqkQ _8ERLTg MCgm0w Z3nT2A LQzFZw VgvqkQ _4_iekA j34Zww aqbYPg _3FvZZg uyUyGw VOvjeA';
53        downloadButton.type = 'button';
54        downloadButton.setAttribute('role', 'menuitem');
55        downloadButton.style.cssText = 'background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; font-weight: 600; padding: 8px 16px; border-radius: 8px; margin-left: 8px;';
56        
57        const buttonContent = document.createElement('span');
58        buttonContent.className = 'vxQy1w';
59        buttonContent.innerHTML = '⬇️ PNG Transparant';
60        
61        downloadButton.appendChild(buttonContent);
62        buttonWrapper.appendChild(downloadButton);
63
64        // Voeg de knop toe aan de toolbar
65        shareButtonContainer.appendChild(buttonWrapper);
66
67        console.log('Download knop toegevoegd aan toolbar');
68
69        // Voeg click event toe
70        downloadButton.addEventListener('click', async function() {
71            console.log('Download knop geklikt');
72            downloadButton.disabled = true;
73            buttonContent.innerHTML = '⏳ Bezig...';
74            
75            try {
76                await downloadTransparentPNG();
77                buttonContent.innerHTML = '✅ Gelukt!';
78                setTimeout(() => {
79                    buttonContent.innerHTML = '⬇️ PNG Transparant';
80                    downloadButton.disabled = false;
81                }, 2000);
82            } catch (error) {
83                console.error('Download fout:', error);
84                buttonContent.innerHTML = '❌ Fout';
85                alert('Er ging iets mis: ' + error.message);
86                setTimeout(() => {
87                    buttonContent.innerHTML = '⬇️ PNG Transparant';
88                    downloadButton.disabled = false;
89                }, 2000);
90            }
91        });
92    }
93
94    // Functie om witte pixels transparant te maken
95    function makeWhiteTransparent(canvas, threshold = 240) {
96        const ctx = canvas.getContext('2d');
97        const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
98        const data = imageData.data;
99
100        // Loop door alle pixels
101        for (let i = 0; i < data.length; i += 4) {
102            const red = data[i];
103            const green = data[i + 1];
104            const blue = data[i + 2];
105            
106            // Als de pixel (bijna) wit is, maak het transparant
107            if (red > threshold && green > threshold && blue > threshold) {
108                data[i + 3] = 0; // Zet alpha naar 0 (transparant)
109            }
110        }
111
112        ctx.putImageData(imageData, 0, 0);
113        return canvas;
114    }
115
116    // Functie om het design te downloaden met transparante achtergrond
117    async function downloadTransparentPNG() {
118        console.log('Start download proces...');
119
120        // Zoek het design viewport element
121        const designViewport = document.querySelector('div[data-page-id="0"]');
122        
123        if (!designViewport) {
124            throw new Error('Kon het design niet vinden. Zorg dat je design volledig geladen is.');
125        }
126
127        console.log('Design viewport gevonden');
128
129        console.log('Maak screenshot van design...');
130        
131        // Maak screenshot met transparante achtergrond en skip oklch kleuren
132        const canvas = await html2canvas(designViewport, {
133            backgroundColor: null,
134            scale: 2,
135            logging: false,
136            useCORS: true,
137            allowTaint: true,
138            ignoreElements: function(element) {
139                // Skip elementen die problemen kunnen veroorzaken
140                const style = window.getComputedStyle(element);
141                const bgColor = style.backgroundColor;
142                const color = style.color;
143                
144                // Check of het oklch gebruikt (geeft parsing errors)
145                if (bgColor && bgColor.includes('oklch')) {
146                    return true;
147                }
148                if (color && color.includes('oklch')) {
149                    return true;
150                }
151                
152                return false;
153            },
154            onclone: function(clonedDoc) {
155                // Fix oklch kleuren in de gekloonde document
156                const allElements = clonedDoc.querySelectorAll('*');
157                allElements.forEach(element => {
158                    const style = window.getComputedStyle(element);
159                    
160                    // Vervang oklch kleuren met fallback kleuren
161                    if (style.backgroundColor && style.backgroundColor.includes('oklch')) {
162                        element.style.backgroundColor = 'transparent';
163                    }
164                    if (style.color && style.color.includes('oklch')) {
165                        element.style.color = '#000000';
166                    }
167                    if (style.borderColor && style.borderColor.includes('oklch')) {
168                        element.style.borderColor = 'transparent';
169                    }
170                    
171                    // Verwijder witte achtergronden
172                    const bgColor = style.backgroundColor;
173                    if (bgColor === 'rgb(255, 255, 255)' || bgColor === '#ffffff' || bgColor === 'white') {
174                        element.style.backgroundColor = 'transparent';
175                    }
176                });
177            }
178        });
179
180        console.log(`Canvas gemaakt: ${canvas.width}x${canvas.height}`);
181
182        // Maak witte pixels transparant
183        console.log('Verwijder witte achtergrond...');
184        makeWhiteTransparent(canvas, 240);
185
186        // Converteer naar PNG blob
187        const blob = await new Promise(resolve => {
188            canvas.toBlob(resolve, 'image/png', 1.0);
189        });
190
191        // Download de afbeelding
192        const url = URL.createObjectURL(blob);
193        const link = document.createElement('a');
194        
195        // Probeer de design naam te krijgen uit de pagina titel
196        const designName = document.title.split(' - ')[0] || 'canva-design';
197        link.download = `${designName}-transparent.png`;
198        link.href = url;
199        link.click();
200
201        // Cleanup
202        setTimeout(() => URL.revokeObjectURL(url), 100);
203
204        console.log('Download succesvol!');
205    }
206
207    // Observeer DOM veranderingen om de knop toe te voegen wanneer de toolbar geladen is
208    const debouncedAddButton = debounce(addDownloadButton, 500);
209    
210    const observer = new MutationObserver(debouncedAddButton);
211    
212    observer.observe(document.body, {
213        childList: true,
214        subtree: true
215    });
216
217    // Probeer de knop direct toe te voegen
218    if (document.readyState === 'loading') {
219        document.addEventListener('DOMContentLoaded', addDownloadButton);
220    } else {
221        setTimeout(addDownloadButton, 2000);
222    }
223
224    console.log('Extensie geïnitialiseerd');
225})();
Canva Transparante Achtergrond Downloader | Robomonkey