#javascript #image #svg #clipboard #copy-paste
#javascript #изображение #svg #буфер обмена #копировать-вставить
Вопрос:
Я работаю над приложением, в котором я хочу предоставить кнопку копирования для копирования svg в виде изображения в буфер обмена, которое можно вставить в другие места.
Я пытался использовать clipboard API, но у него много ограничений безопасности, более того, он, похоже, не работает с http и работает только с png.
Я также попробовал document.execCommand('copy')
, создав div с изображением, но у меня это сработало только в MS Word, но не в slack или stack overflow (не уверен, почему).
Я хочу воспроизвести поведение опции копирования изображения контекстного меню правой кнопки мыши Chrome / Firefox с помощью Javascript.
Есть ли какой-то способ, которым это возможно? Я открыт для всех идей. Спасибо!
Комментарии:
1. Было бы неплохо иметь некоторый код для обработки. В зависимости от ваших потребностей, вы можете попробовать нарисовать
svg
внутреннюю часть acanvas
с помощью javascript, как в этом примере: tutorialspoint.com/How-to-draw-an-SVG-file-on-an-HTML5-canvas2. Я изучил вариант написания canvas, но как скопировать это как изображение в буфер обмена?
3. Извините, меня смутило предложение о щелчке правой кнопкой мыши. Для вашей проблемы я не вижу способа обойти API буфера обмена.
execCommand
Стратегия экспортирует не изображение, а HTML-код. Вот почему он работает в Word, но не в процессорах обработки изображений. Вы можете найти полезные примеры на developer.mozilla.org/en-US/docs/Web/API/Clipboard/write , но с оговорками. Я боюсь, что это головная боль, а не переносимая.4. Спасибо @vqf. Есть идеи, как это делает chrome / firefox? Я сомневаюсь, что они, вероятно, используют некоторые API, отличные от тех, которые предоставлены в JS. Любые идеи или ссылки были бы замечательными.
5. Какое изображение вы ожидаете, что оно будет копировать / вставлять? Изображение SVG? Тогда разметка, которую вы имеете, — это изображение svg. Растровое изображение? Если да, то в каких размерах и почему? В каком состоянии? (помните, что svg-изображения могут быть анимированы с помощью SMIL или CSS и даже интерактивны)
Ответ №1:
Просто несколько указателей, а не фактический ответ. Я создал локальный пример, используя информацию в комментариях:
<!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
поскольку оно испорчено. Это объясняется здесь . Вы можете избежать этой проблемы, если сможете установить политику CORS на своем сервере. Я все еще не уверен в переносимости решения.
Ответ №2:
Вы можете просто скопировать код Base64 после символа ‘,’ в end ( PHN2ZyB4bWxu...4=
) и преобразовать его в SVG с помощью любых сервисов (например, base64.guru), а затем скопировать результат в буфер обмена в виде изображения.
data:image/svg xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIiB3aWR0aD0iNDQ4IiBoZWlnaHQ9IjUxMiI PHBhdGggZmlsbD0iIzNhNWI4NyIgZD0iTTAgNDY0YzAgMjYuNSAyMS41IDQ4IDQ4IDQ4aDM1MmMyNi41IDAgNDgtMjEuNSA0OC00OFYxOTJIMHYyNzJ6bTMyMC0xOTZjMC02LjYgNS40LTEyIDEyLTEyaDQwYzYuNiAwIDEyIDUuNCAxMiAxMnY0MGMwIDYuNi01LjQgMTItMTIgMTJoLTQwYy02LjYgMC0xMi01LjQtMTItMTJ2LTQwem0wIDEyOGMwLTYuNiA1LjQtMTIgMTItMTJoNDBjNi42IDAgMTIgNS40IDEyIDEydjQwYzAgNi42LTUuNCAxMi0xMiAxMmgtNDBjLTYuNiAwLTEyLTUuNC0xMi0xMnYtNDB6TTE5MiAyNjhjMC02LjYgNS40LTEyIDEyLTEyaDQwYzYuNiAwIDEyIDUuNCAxMiAxMnY0MGMwIDYuNi01LjQgMTItMTIgMTJoLTQwYy02LjYgMC0xMi01LjQtMTItMTJ2LTQwem0wIDEyOGMwLTYuNiA1LjQtMTIgMTItMTJoNDBjNi42IDAgMTIgNS40IDEyIDEydjQwYzAgNi42LTUuNCAxMi0xMiAxMmgtNDBjLTYuNiAwLTEyLTUuNC0xMi0xMnYtNDB6TTY0IDI2OGMwLTYuNiA1LjQtMTIgMTItMTJoNDBjNi42IDAgMTIgNS40IDEyIDEydjQwYzAgNi42LTUuNCAxMi0xMiAxMkg3NmMtNi42IDAtMTItNS40LTEyLTEydi00MHptMCAxMjhjMC02LjYgNS40LTEyIDEyLTEyaDQwYzYuNiAwIDEyIDUuNCAxMiAxMnY0MGMwIDYuNi01LjQgMTItMTIgMTJINzZjLTYuNiAwLTEyLTUuNC0xMi0xMnYtNDB6TTQwMCA2NGgtNDhWMTZjMC04LjgtNy4yLTE2LTE2LTE2aC0zMmMtOC44IDAtMTYgNy4yLTE2IDE2djQ4SDE2MFYxNmMwLTguOC03LjItMTYtMTYtMTZoLTMyYy04LjggMC0xNiA3LjItMTYgMTZ2NDhINDhDMjEuNSA2NCAwIDg1LjUgMCAxMTJ2NDhoNDQ4di00OGMwLTI2LjUtMjEuNS00OC00OC00OHoiPjwvcGF0aD48L3N2Zz4=