Google's "Report a Bug" o "Feedback Tool" le permite seleccionar un área de la ventana del navegador para crear una captura de pantalla que se envía con sus comentarios sobre un error.
Captura de pantalla de la herramienta de comentarios de Google]1 Captura de pantalla de Jason Small, publicada en una pregunta duplicada;
¿Cómo lo hacen? La API de retroalimentación de JavaScript de Google's se carga desde aquí y su visión general del módulo de retroalimentación demostrará la capacidad de captura de pantalla.
JavaScript puede leer el DOM y renderizar una representación bastante precisa de eso usando canvas
. He estado trabajando en un script que convierte el HTML en una imagen canvas. Decidí hoy hacer una implementación de la misma en el envío de retroalimentación como usted describió.
El script permite crear formularios de feedback que incluyen una captura de pantalla, creada en el navegador del cliente, junto con el formulario. La captura de pantalla se basa en el DOM y como tal puede no ser 100% exacta a la representación real ya que no hace una captura de pantalla real, sino que construye la captura de pantalla basada en la información disponible en la página.
No requiere ningún tipo de renderización del servidor**, ya que toda la imagen se crea en el navegador del cliente. El script HTML2Canvas en sí mismo está todavía en un estado muy experimental, ya que no analiza la mayor parte de los atributos CSS3 que yo querría, ni tiene ningún soporte para cargar imágenes CORS incluso si un proxy estuviera disponible.
La compatibilidad con los navegadores sigue siendo bastante limitada (no porque no se pueda soportar más, simplemente no he tenido tiempo de hacerlo más compatible con los navegadores).
Para más información, eche un vistazo a los ejemplos aquí:
http://hertzen.com/experiments/jsfeedback/
**Editar El script html2canvas está ahora disponible por separado aquí y algunos ejemplos aquí.
edición 2 Otra confirmación de que Google utiliza un método muy similar (de hecho, basado en la documentación, la única diferencia importante es su método asíncrono de atravesar/dibujar) se puede encontrar en esta presentación de Elliott Sprehn del equipo de Google Feedback: http://www.elliottsprehn.com/preso/fluentconf/
Tu aplicación web puede ahora tomar una captura de pantalla "nativa" de todo el escritorio del cliente utilizando getUserMedia()
:
Echa un vistazo a este ejemplo:
https://www.webrtc-experiment.com/Pluginfree-Screen-Sharing/
El cliente tendrá que usar chrome (por ahora) y tendrá que habilitar el soporte de captura de pantalla en chrome://flags.
Como Niklas mencionó puedes usar la librería html2canvas para tomar una captura de pantalla usando JS en el navegador. Voy a ampliar su respuesta en este punto proporcionando un ejemplo de tomar una captura de pantalla utilizando esta biblioteca:
function report() {
let region = document.querySelector("body"); // whole screen
html2canvas(region, {
onrendered: function(canvas) {
let pngUrl = canvas.toDataURL(); // png in dataURL format
let img = document.querySelector(".screen");
img.src = pngUrl;
// here you can allow user to set bug-region
// and send it with 'pngUrl' to server
},
});
}
.container {
margin-top: 10px;
border: solid 1px black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<div>Screenshot tester</div>
<button onclick="report()">Take screenshot</button>
<div class="container">
<img width="75%" class="screen">
</div>
En la función report()
en onrendered
después de obtener la imagen como URI de datos puedes mostrarla al usuario y permitirle dibujar la "región del error" con el ratón y luego enviar una captura de pantalla y las coordenadas de la región al servidor.
En [este ejemplo][3] se hizo la versión async/await
: con la bonita función makeScreenshot()
[.][4]
Ejemplo sencillo que permite hacer una captura de pantalla, seleccionar la región, describir el fallo y enviar una petición POST ([aquí jsfiddle][5]) (la función principal es report()
).
async function report() {
let screenshot = await makeScreenshot(); // png dataUrl
let img = q(".screen");
img.src = screenshot;
let c = q(".bug-container");
c.classList.remove('hide')
let box = await getBox();
c.classList.add('hide');
send(screenshot,box); // sed post request with bug image, region and description
alert('To see POST requset with image go to: chrome console > network tab');
}
// ----- Helper functions
let q = s => document.querySelector(s); // query selector helper
window.report = report; // bind report be visible in fiddle html
async function makeScreenshot(selector="body")
{
return new Promise((resolve, reject) => {
let node = document.querySelector(selector);
html2canvas(node, { onrendered: (canvas) => {
let pngUrl = canvas.toDataURL();
resolve(pngUrl);
}});
});
}
async function getBox(box) {
return new Promise((resolve, reject) => {
let b = q(".bug");
let r = q(".region");
let scr = q(".screen");
let send = q(".send");
let start=0;
let sx,sy,ex,ey=-1;
r.style.width=0;
r.style.height=0;
let drawBox= () => {
r.style.left = (ex > 0 ? sx : sx+ex ) +'px';
r.style.top = (ey > 0 ? sy : sy+ey) +'px';
r.style.width = Math.abs(ex) +'px';
r.style.height = Math.abs(ey) +'px';
}
//console.log({b,r, scr});
b.addEventListener("click", e=>{
if(start==0) {
sx=e.pageX;
sy=e.pageY;
ex=0;
ey=0;
drawBox();
}
start=(start+1)%3;
});
b.addEventListener("mousemove", e=>{
//console.log(e)
if(start==1) {
ex=e.pageX-sx;
ey=e.pageY-sy
drawBox();
}
});
send.addEventListener("click", e=>{
start=0;
let a=100/75 //zoom out img 75%
resolve({
x:Math.floor(((ex > 0 ? sx : sx+ex )-scr.offsetLeft)*a),
y:Math.floor(((ey > 0 ? sy : sy+ey )-b.offsetTop)*a),
width:Math.floor(Math.abs(ex)*a),
height:Math.floor(Math.abs(ex)*a),
desc: q('.bug-desc').value
});
});
});
}
function send(image,box) {
let formData = new FormData();
let req = new XMLHttpRequest();
formData.append("box", JSON.stringify(box));
formData.append("screenshot", image);
req.open("POST", '/upload/screenshot');
req.send(formData);
}
.bug-container { background: rgb(255,0,0,0.1); margin-top:20px; text-align: center; }
.send { border-radius:5px; padding:10px; background: green; cursor: pointer; }
.region { position: absolute; background: rgba(255,0,0,0.4); }
.example { height: 100px; background: yellow; }
.bug { margin-top: 10px; cursor: crosshair; }
.hide { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<body>
<div>Screenshot tester</div>
<button onclick="report()">Report bug</button>
<div class="example">Lorem ipsum</div>
<div class="bug-container hide">
<div>Select bug region</div>
<div class="bug">
<img width="75%" class="screen" >
<div class="region"></div>
</div>
<div>
<textarea class="bug-desc">Describe bug here...</textarea>
</div>
<div class="send">SEND BUG</div>
</div>
</body>