Недавно я получил требование в разработке пользовательского интерфейса, чтобы сообщить об ошибке, используя снимок экрана.

Есть два экрана: экран заявки, на котором сообщается об ошибке, и экран ошибки, на котором пользователь идентифицировал ошибку.

  1. Пользователь должен иметь возможность создать ошибку с изображением на экране тикета.
  2. Изображение можно вырезать из экрана ошибки и вставить на экран тикета.
  3. У нас есть контроль разработки пользовательского интерфейса на обоих экранах.
  4. Эта функция должна поддерживаться в Internet Explorer 11 и Chrome.

API буфера обмена

В браузерах есть API буфера обмена, который помогает получать данные и копировать данные в буфер обмена.

// Fetches the currently selected test to clipboard
clipboardEvent.clipboardData.getData("Text")
// Copies the currently selected text to clipboard
document.execCommand("copy")

Снимок экрана с ошибкой

Я использовал html2canvas для преобразования существующего документа в холст. Тег Canvas помогает рисовать графику в HTML.

html2canvas(document.body).then(function(canvas) {
    document.body.appendChild(canvas);
    console.log("Image src",canvas.toDataURL());
});

2. canvas.toDataURL() преобразует холст в форму URI данных изображения, и его можно передать любому тегу изображения как src для его отображения.

3. Мы можем передать canvas.toDataURL() тегу изображения как src.

Обрезка части изображения

  1. Для этого я использовал React-Image-Crop.
  2. Мы можем передать тег image src из приведенного выше тега, чтобы отреагировать на обрезку изображения.
const imageSrc; // set base64 url to this 
<ReactCrop src={imageSrc} crop={this.state.crop} onChange={this.onChange}/>

3. Мы должны обработать onChange, который будет вызываться при обрезке изображения.

onChange = (crop, pixelCrop) => {
  this.setState({ crop, pixelCrop });
}

4. PixelCrop — это тот, который поможет нам получить изображение обрезанного изображения.

/**
 * @param {File} image - Image File Object from dom.
 * @param {Object} pixelCrop - pixelCrop Object provided by react-image-crop
 */
function getCroppedImg(image, pixelCrop) {

 const canvas = document.createElement('canvas');
  canvas.width = pixelCrop.width;
  canvas.height = pixelCrop.height;
  const ctx = canvas.getContext('2d');

  ctx.drawImage(
    image,
    pixelCrop.x,
    pixelCrop.y,
    pixelCrop.width,
    pixelCrop.height,
    0,
    0,
    pixelCrop.width,
    pixelCrop.height
  );
  // As a dataUrl
  return canvas.toDataUrl()
}

Копирование обрезанного изображения в буфер обмена как строки base64

Копирование изображения было достигнуто с использованием текстовой области, так как трудно скопировать все изображение в виде файла в буфер обмена, но текст будет легко.

  1. Динамическое создание текстового поля.
  2. Установите значение текстового поля на URL-адрес обрезанного изображения, который мы получили на предыдущем шаге.
  3. Сфокусируйтесь и выберите значение в текстовом поле.
textarea=document.createElement(“textarea”);
document.body.appendChild(textarea);
textarea.value=”hi”
textarea.focus();
textarea.select()

Вставка текста изображения или файла изображения из буфера обмена

  1. Я приземлился на эту прекрасную библиотеку после неудачной попытки с несколькими библиотеками, и она работает как мечта в ie11 и chrome.
    https://github.com/layerssss/paste.js/
  2. Это зависит от JQuery.
  3. Это помогает нам обнаруживать события вставки изображения и вставки текста и предоставляет нам данные для обоих в соответствующих форматах.
  4. Мы можем установить URL-адрес изображения в тег изображения.
// Intialising textarea
$('textarea').pastableTextarea();
// On Paste image event we can get the image file from clipboard. $('textarea').on('pasteImage', function (ev, data){
  console.log("dataURL: " + data.dataURL);
  setImageurl(data.dataURL)
})
// On Paste text event we can get the base64 as string from clipboard.
.on('pasteText', function (ev, data){
console.log("text: " + data.text);
if(isBase64(data.text)){
  setImageurl(data.text);
}});

Загрузить URL-адрес изображения base 64 на сервер,

Мы можем преобразовать base64 в файл blob, blob похож на файл и может использоваться вместо него.

function base64toBlob(base64Data, contentType) {
 contentType = contentType || ‘’;
 var sliceSize = 1024;
 var byteCharacters = atob(base64Data);
 var bytesLength = byteCharacters.length;
 var slicesCount = Math.ceil(bytesLength / sliceSize);
 var byteArrays = new Array(slicesCount);
for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
 var begin = sliceIndex * sliceSize;
 var end = Math.min(begin + sliceSize, bytesLength);
var bytes = new Array(end — begin);
 for (var offset = begin, i = 0 ; offset < end; ++i, ++offset) {
 bytes[i] = byteCharacters[offset].charCodeAt(0);
 }
 byteArrays[sliceIndex] = new Uint8Array(bytes);
 }
 return new Blob(byteArrays, { type: contentType });
}

Вот как я достиг этой функции, которая работает на ie11 и chrome. Могут быть лучшие способы, пожалуйста, прокомментируйте, если таковые имеются.