I'm trying to put image in clipboard when user copies canvas selection:
So I thought the right way would be to convert canvas tu dataURL, dataURL to blob and blob to binary string.
Theoretically it should be possible to skip the blob, but I don't know why.
So this is what I did:
function copy(event) {
console.log("copy");
console.log(event);
//Get DataTransfer object
var items = (event.clipboardData || event.originalEvent.clipboardData);
//Canvas to blob
var blob = Blob.fromDataURL(_this.editor.selection.getSelectedImage().toDataURL("image/png"));
//File reader to convert blob to binary string
var reader = new FileReader();
//File reader is for some reason asynchronous
reader.onloadend = function () {
items.setData(reader.result, "image/png");
}
//This starts the conversion
reader.readAsBinaryString(blob);
//Prevent default copy operation
event.preventDefault();
event.cancelBubble = true;
return false;
}
div.addEventListener('copy', copy);
But when the DataTransfer
object is used out of the paste
event thread the setData
has no longer any chance to take effect.
How can I do the conversion in the same function thread?
Here is a hacky-way to get you synchronously from a blob to its bytes. I'm not sure how well this works for any binary data.
function blobToUint8Array(b) {
var uri = URL.createObjectURL(b),
xhr = new XMLHttpRequest(),
i,
ui8;
xhr.open('GET', uri, false);
xhr.send();
URL.revokeObjectURL(uri);
ui8 = new Uint8Array(xhr.response.length);
for (i = 0; i < xhr.response.length; ++i) {
ui8[i] = xhr.response.charCodeAt(i);
}
return ui8;
}
var b = new Blob(['abc'], {type: 'application/octet-stream'});
blobToUint8Array(b); // [97, 98, 99]
You should consider keeping it async but making it two-stage, though, as you may end up locking up the browser.
Additionally, you can skip Blobs entirely by including a binary-safe Base64 decoder, and you probably don't need to go via Base64 AND Blob, just one of them.
Blob can be converted to binary string by getting Blob as dataURI and then applying atob
. This, however, again [requires FileReader][3]
. In my case, it's best to skip the blob alltogether:
//Canvas to binary
var data = atob(
_this.editor.selection.getSelectedImage() //Canvas
.toDataURL("image/png") //Base64 URI
.split(',')[1] //Base64 code
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With