I'm creating graphical editor with copy/paste functionality. I want for user to be able to Ctrl+C a selected zone of an image and copy it to clipboard this way.
I know there is a method which you can use to programmatically set clipboard content, that is Clipboard.write, and in the newest Chrome versions (I have version 80) it allows to copy images too, and I don't need backward compatibility whatsoever. This would work and it works for a case of explicit "Copy" button press. But using that requires getting user's permission to write to clipboard (that is 'clipboard-write'
), though it is allowed by default in Chrome.
I also know there is an event on an element, called oncopy
, and there is a way to modify clipboard content being copied in it, without requesting user's permission, which is a preferred way. So what I tried is something like that:
// placing that listener on the document is a bad practice I suppose
// because it would prevent user from copying anything on the page,
// so consider that just an example code
document.oncopy = async (e) => {
const blob = await new Promise(resolve => areaCanvas.toBlob(resolve))
e.clipboardData.setData('image/png', blob)
}
That presumably wouldn't work because of async function. So then I tried to move blob creation higher and got this code:
let blob
// ... user selects and area ...
blob = await new Promise((resolve) => areaCanvas.toBlob(resolve))
document.oncopy = (e) => {
e.preventDefault()
e.clipboardData.setData('image/png', blob)
}
But this, evidently, results in an empty clipboard. So is there a way to copy an image (or canvas) to clipboard in response to Ctrl+C, without requesting user's permission to write to clipboard?