Недавно я получил требование в разработке пользовательского интерфейса, чтобы сообщить об ошибке, используя снимок экрана.
Есть два экрана: экран заявки, на котором сообщается об ошибке, и экран ошибки, на котором пользователь идентифицировал ошибку.
- Пользователь должен иметь возможность создать ошибку с изображением на экране тикета.
- Изображение можно вырезать из экрана ошибки и вставить на экран тикета.
- У нас есть контроль разработки пользовательского интерфейса на обоих экранах.
- Эта функция должна поддерживаться в 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.
Обрезка части изображения
- Для этого я использовал React-Image-Crop.
- Мы можем передать тег 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
Копирование изображения было достигнуто с использованием текстовой области, так как трудно скопировать все изображение в виде файла в буфер обмена, но текст будет легко.
- Динамическое создание текстового поля.
- Установите значение текстового поля на URL-адрес обрезанного изображения, который мы получили на предыдущем шаге.
- Сфокусируйтесь и выберите значение в текстовом поле.
textarea=document.createElement(“textarea”); document.body.appendChild(textarea); textarea.value=”hi” textarea.focus(); textarea.select()
Вставка текста изображения или файла изображения из буфера обмена
- Я приземлился на эту прекрасную библиотеку после неудачной попытки с несколькими библиотеками, и она работает как мечта в ie11 и chrome.
https://github.com/layerssss/paste.js/ - Это зависит от JQuery.
- Это помогает нам обнаруживать события вставки изображения и вставки текста и предоставляет нам данные для обоих в соответствующих форматах.
- Мы можем установить 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. Могут быть лучшие способы, пожалуйста, прокомментируйте, если таковые имеются.