Wie kann ich Benutzer Bilddaten aus der Zwischenablage in Firefox in reinem Javascript in ein Canvas-Element einfügen lassen?
Lesezeit: 5 Minuten
DG.
Ich habe mein Bestes getan, um ein einfaches, relevantes und aktuelles Beispiel zu finden, das für die neueste Version von Firefox funktioniert, und ich habe wirklich Probleme.
Titel sagt eigentlich alles. Ich möchte, dass der Benutzer einen Teil eines Bildes aus einem Editor wie Windows Paint kopieren oder die Schaltfläche „Drucken“ verwenden und dann in ein Canvas-Element einfügen kann. Bonuspunkte, wenn die Größe der Leinwand genau an das eingefügte Bild angepasst wird (buchstäblich).
Flash- oder Java-basierte Lösungen vermeiden möchten, wenn dies sinnvoll ist.
Ich bin halbwegs anständig in Javascript, aber relativ unerfahren mit den neuesten HTML5-Funktionen und völlig neu im Canvas-Element. Bitte helfen Sie!
Wie verwaltet man das Einfügen von Bildern aus der Zwischenablage in HTML5?
–Andreas
22. August 2013 um 10:34 Uhr
ViliusL
Version 2.0: Kleinerer, saubererer Code funktioniert auf Chrome, Firefox, Edge, Opera. Keine Hacks mehr. Wenn Sie jedoch Unterstützung für IE und Safari benötigen, überprüfen Sie die v1-Version.
Version 1.0
Die Chrome-Implementierung ist einfach. Firefox (und IE) hat Einschränkungen, dass der Benutzer den Befehl zum Einfügen geben muss, wie ein Tastaturereignis, und bearbeitbare Eingaben müssen fokussiert sein, also machen wir hier Tricks – bei gedrückter Strg-Taste fokussieren wir das Eingabefeld, bei Freigabe wird der Fokus aufgehoben.
Browserunterstützung (Bilddaten):
Feuerfuchs
Chrom
Rand
IE-11
Oper
var CLIPBOARD = new CLIPBOARD_CLASS("my_canvas", true);
/**
* image pasting into canvas
*
* @param {string} canvas_id - canvas id
* @param {boolean} autoresize - if canvas will be resized
*/
function CLIPBOARD_CLASS(canvas_id, autoresize) {
var _self = this;
var canvas = document.getElementById(canvas_id);
var ctx = document.getElementById(canvas_id).getContext("2d");
var ctrl_pressed = false;
var command_pressed = false;
var paste_event_support;
var pasteCatcher;
//handlers
document.addEventListener('keydown', function (e) {
_self.on_keyboard_action(e);
}, false); //firefox fix
document.addEventListener('keyup', function (e) {
_self.on_keyboardup_action(e);
}, false); //firefox fix
document.addEventListener('paste', function (e) {
_self.paste_auto(e);
}, false); //official paste handler
//constructor - we ignore security checks here
this.init = function () {
pasteCatcher = document.createElement("div");
pasteCatcher.setAttribute("id", "paste_ff");
pasteCatcher.setAttribute("contenteditable", "");
pasteCatcher.style.cssText="opacity:0;position:fixed;top:0px;left:0px;width:10px;margin-left:-20px;";
document.body.appendChild(pasteCatcher);
// create an observer instance
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (paste_event_support === true || ctrl_pressed == false || mutation.type != 'childList'){
//we already got data in paste_auto()
return true;
}
//if paste handle failed - capture pasted object manually
if(mutation.addedNodes.length == 1) {
if (mutation.addedNodes[0].src != undefined) {
//image
_self.paste_createImage(mutation.addedNodes[0].src);
}
//register cleanup after some time.
setTimeout(function () {
pasteCatcher.innerHTML = '';
}, 20);
}
});
});
var target = document.getElementById('paste_ff');
var config = { attributes: true, childList: true, characterData: true };
observer.observe(target, config);
}();
//default paste action
this.paste_auto = function (e) {
paste_event_support = false;
if(pasteCatcher != undefined){
pasteCatcher.innerHTML = '';
}
if (e.clipboardData) {
var items = e.clipboardData.items;
if (items) {
paste_event_support = true;
//access data directly
for (var i = 0; i < items.length; i++) {
if (items[i].type.indexOf("image") !== -1) {
//image
var blob = items[i].getAsFile();
var URLObj = window.URL || window.webkitURL;
var source = URLObj.createObjectURL(blob);
this.paste_createImage(source);
}
}
e.preventDefault();
}
else {
//wait for DOMSubtreeModified event
//https://bugzilla.mozilla.org/show_bug.cgi?id=891247
}
}
};
//on keyboard press
this.on_keyboard_action = function (event) {
k = event.keyCode;
//ctrl
if (k == 17 || event.metaKey || event.ctrlKey) {
if (ctrl_pressed == false)
ctrl_pressed = true;
}
//v
if (k == 86) {
if (document.activeElement != undefined && document.activeElement.type == 'text') {
//let user paste into some input
return false;
}
if (ctrl_pressed == true && pasteCatcher != undefined){
pasteCatcher.focus();
}
}
};
//on kaybord release
this.on_keyboardup_action = function (event) {
//ctrl
if (event.ctrlKey == false && ctrl_pressed == true) {
ctrl_pressed = false;
}
//command
else if(event.metaKey == false && command_pressed == true){
command_pressed = false;
ctrl_pressed = false;
}
};
//draw pasted image to canvas
this.paste_createImage = function (source) {
var pastedImage = new Image();
pastedImage.onload = function () {
if(autoresize == true){
//resize
canvas.width = pastedImage.width;
canvas.height = pastedImage.height;
}
else{
//clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
ctx.drawImage(pastedImage, 0, 0);
};
pastedImage.src = source;
};
}
1. Copy image data into clipboard or press Print Screen <br>
2. Press Ctrl+V (page/iframe must be focused):
<br /><br />
<canvas style="border:1px solid grey;" id="my_canvas" width="300" height="300"></canvas>
Vielen Dank! Was für eine Erleichterung!
– DG.
23. August 2013 um 2:48 Uhr
Gibt es eine einfachere Lösung im April 2014? ohne Browser zu unterscheiden?
– Iwan Kuckir
4. April 2014 um 19:20 Uhr
Es sollte einfach sein: jsfiddle.net/KJW4E/222 – vorerst nur Chrom. In Zukunft besteht die Möglichkeit, dass dieses Beispiel auf allen Browsern funktioniert. Leider haben andere Browser einige Einschränkungen, die umgangen werden müssen.
– ViliusL
29. April 2014 um 12:09 Uhr
Strg + v funktioniert manchmal nicht im Firefox v-29-Browser. Wenn ich die Größe des Browserfensters verändere, kann ich einfügen. (Paste-Ereignis wird ausgelöst). Gibt es ein Problem mit Firefox 29 Browser mit Contenteditable oder Paste Event mit Tastaturkürzeln?
– Jak
15. Mai 2014 um 20:13 Uhr
@Jak, ich konnte deine Situation auf Firefox v29 nicht reproduzieren. Plugins, viele HTML-Elemente oder vielleicht ungültiger Code?
– ViliusL
20. Mai 2014 um 12:42 Uhr
Die Antwort von ViliusL ist großartig, aber für diejenigen, die nach einer einfachen browserübergreifenden Möglichkeit suchen, ein eingefügtes Bild zu erfassen:
window.addEventListener("paste", async function(e) {
e.preventDefault();
e.stopPropagation();
let file = e.clipboardData.items[0].getAsFile();
let objectUrl = URL.createObjectURL(file);
// do something with url here
});
Wahrscheinlich möchten Sie eine Fehlerprüfung durchführen (wie in ViliusLs Antwort), falls sie etwas einfügen, das kein Bild ist. Laut MDN, ZwischenablageDaten funktioniert in allen modernen Browsern. Ich habe auf Chrome und Firefox getestet, und sie funktionieren gut.
14062700cookie-checkWie kann ich Benutzer Bilddaten aus der Zwischenablage in Firefox in reinem Javascript in ein Canvas-Element einfügen lassen?yes
Wie verwaltet man das Einfügen von Bildern aus der Zwischenablage in HTML5?
–Andreas
22. August 2013 um 10:34 Uhr