我正在开发一个应用程序,我想提供一个复制按钮,以便将 svg 作为图像复制到剪贴板,然后可以粘贴到其他地方。
我尝试使用剪贴板API,但它有很多安全限制,而且它似乎不适用于http并且仅适用于png。
我还尝试了
document.execCommand('copy')
,通过使用图像创建一个div,但它仅在MS Word中对我有用,但在slack或堆栈溢出中不起作用(不知道为什么)。
我想通过 Javascript 复制 chrome/firefox 右键单击上下文菜单的复制图像选项的行为。
有什么办法可以做到这一点吗?我对所有想法持开放态度。谢谢!
只是一些提示,不是真正的答案。我使用评论中的信息设置了一个本地示例:
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" style="border:2px solid green;" width="300" height="300">
</canvas>
<script>
function copyCanvas() {
let canvas = document.getElementById('myCanvas');
canvas.toBlob(function (blob) {
let data = [new ClipboardItem({ [blob.type]: blob })];
navigator.clipboard.write(data).then(function () {
alert('Copied');
}, function (err) {
alert('Not copied');
})
});
}
let canvas = document.getElementById('myCanvas');
let ctx = canvas.getContext('2d');
var data = `<svg xmlns="http://www.w3.org/2000/svg" width="300"
height="200">' +
'<foreignObject width="100%" height="100%">' +
'<div xmlns="http://www.w3.org/1999/xhtml" style="font-size:50px">' +
'Simply Easy ' +
'<span style="color:blue;">' +
'Learning</span>' +
'</div>' +
'</foreignObject>' +
'</svg>`;
var DOMURL = window.URL || window.webkitURL || window;
var img1 = new Image();
var svg = new Blob([data], {type: 'image/svg+xml'});
var url = DOMURL.createObjectURL(svg);
img1.onload = function() {
ctx.drawImage(img1, 25, 70);
DOMURL.revokeObjectURL(url);
}
img1.src = url;
setTimeout(copyCanvas, 3000);
</script>
</body>
</html>
这不起作用,但这可能是一个开始。如果直接调用
copyCanvas()
,而不使用 setTimeout
,我会在 Chrome 中得到一张尺寸合适的黑色图片。我认为这意味着画布仍未绘制。随着延迟,画布显示了图片,但我收到一条错误消息,指出它无法使用 toBlob
进行转换,因为它已被污染。 here对此进行了解释。如果您可以在服务器中设置 CORS 策略,则可以避免这种污染。我仍然不确定该解决方案的可移植性。
您只需复制“,”字符后面的 Base64 代码以结束 (
PHN2ZyB4bWxu...4=
) 并使用任何服务(如 base64.guru)将其转换为 SVG,然后将结果作为图像复制到剪贴板。
data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIiB3aWR0aD0iNDQ4IiBoZWlnaHQ9IjUxMiI+PHBhdGggZmlsbD0iIzNhNWI4NyIgZD0iTTAgNDY0YzAgMjYuNSAyMS41IDQ4IDQ4IDQ4aDM1MmMyNi41IDAgNDgtMjEuNSA0OC00OFYxOTJIMHYyNzJ6bTMyMC0xOTZjMC02LjYgNS40LTEyIDEyLTEyaDQwYzYuNiAwIDEyIDUuNCAxMiAxMnY0MGMwIDYuNi01LjQgMTItMTIgMTJoLTQwYy02LjYgMC0xMi01LjQtMTItMTJ2LTQwem0wIDEyOGMwLTYuNiA1LjQtMTIgMTItMTJoNDBjNi42IDAgMTIgNS40IDEyIDEydjQwYzAgNi42LTUuNCAxMi0xMiAxMmgtNDBjLTYuNiAwLTEyLTUuNC0xMi0xMnYtNDB6TTE5MiAyNjhjMC02LjYgNS40LTEyIDEyLTEyaDQwYzYuNiAwIDEyIDUuNCAxMiAxMnY0MGMwIDYuNi01LjQgMTItMTIgMTJoLTQwYy02LjYgMC0xMi01LjQtMTItMTJ2LTQwem0wIDEyOGMwLTYuNiA1LjQtMTIgMTItMTJoNDBjNi42IDAgMTIgNS40IDEyIDEydjQwYzAgNi42LTUuNCAxMi0xMiAxMmgtNDBjLTYuNiAwLTEyLTUuNC0xMi0xMnYtNDB6TTY0IDI2OGMwLTYuNiA1LjQtMTIgMTItMTJoNDBjNi42IDAgMTIgNS40IDEyIDEydjQwYzAgNi42LTUuNCAxMi0xMiAxMkg3NmMtNi42IDAtMTItNS40LTEyLTEydi00MHptMCAxMjhjMC02LjYgNS40LTEyIDEyLTEyaDQwYzYuNiAwIDEyIDUuNCAxMiAxMnY0MGMwIDYuNi01LjQgMTItMTIgMTJINzZjLTYuNiAwLTEyLTUuNC0xMi0xMnYtNDB6TTQwMCA2NGgtNDhWMTZjMC04LjgtNy4yLTE2LTE2LTE2aC0zMmMtOC44IDAtMTYgNy4yLTE2IDE2djQ4SDE2MFYxNmMwLTguOC03LjItMTYtMTYtMTZoLTMyYy04LjggMC0xNiA3LjItMTYgMTZ2NDhINDhDMjEuNSA2NCAwIDg1LjUgMCAxMTJ2NDhoNDQ4di00OGMwLTI2LjUtMjEuNS00OC00OC00OHoiPjwvcGF0aD48L3N2Zz4=
为了扩展其他答案,这对我有用。
const image = new Image();
image.src = 'data:image/svg+xml,' + encodeURIComponent(svgElement.outerHTML);
await navigator.clipboard.write([new ClipboardItem({
'image/png': new Promise((resolve) => {
const canvas = document.createElement('canvas');
canvas.width = image.naturalWidth;
canvas.height = image.naturalHeight;
const context = canvas.getContext('2d');
context?.drawImage(image, 0, 0);
canvas.toBlob((blob) => {
if (blob) {
resolve(blob);
}
canvas.remove();
}, 'image/png');
})
})]);