L'outil "Report a Bug" ou "Feedback Tool" de Google vous permet de sélectionner une zone de la fenêtre de votre navigateur pour réaliser une capture d'écran qui sera soumise avec vos commentaires sur un bug.
!Capture d'écran de l'outil de feedback de Google][1] Capture d'écran réalisée par Jason Small, publiée dans une [question dupliquée][2].
Comment font-ils cela ? L'API de rétroaction JavaScript de Google est chargée à partir de [ici] (https://ssl.gstatic.com/feedback/api.js) et [leur aperçu du module de rétroaction] (http://www.google.com/tools/feedback/intl/en/learnmore.html) démontrera la capacité de capture d'écran. [1] : http://i.stack.imgur.com/CDhEi.png [2] : https://stackoverflow.com/questions/6608327/google-style-send-feedback
JavaScript peut lire le DOM et en rendre une représentation assez précise en utilisant canvas
. J'ai travaillé sur un script qui convertit le HTML en une image canvas. J'ai décidé aujourd'hui d'en faire une implémentation pour envoyer des feedbacks comme vous l'avez décrit.
Le script vous permet de créer des formulaires de commentaires qui incluent une capture d'écran, créée sur le navigateur du client, avec le formulaire. La capture d'écran est basée sur le DOM et, en tant que telle, peut ne pas être 100% exacte à la représentation réelle, car il ne fait pas une capture d'écran réelle, mais construit la capture d'écran sur la base des informations disponibles sur la page.
Il ne nécessite aucun rendu du serveur, car l'image entière est créée sur le navigateur du client. Le script HTML2Canvas lui-même est encore dans un état très expérimental, car il n'analyse pas autant d'attributs CSS3 que je le souhaiterais, et il ne prend pas en charge le chargement d'images CORS même si un proxy est disponible.
La compatibilité avec les navigateurs est encore assez limitée (non pas parce que d'autres ne pourraient pas être pris en charge, mais parce que je n'ai pas eu le temps de le rendre plus compatible avec les différents navigateurs).
Pour plus d'informations, jetez un coup d'oeil aux exemples ici :
http://hertzen.com/experiments/jsfeedback/
edit Le script html2canvas est maintenant disponible séparément [ici][1] et quelques [exemples ici][2].
edit 2 Une autre confirmation que Google utilise une méthode très similaire (en fait, d'après la documentation, la seule différence majeure est leur méthode asynchrone de traversée/dessin) se trouve dans cette présentation d'Elliott Sprehn de l'équipe Google Feedback : http://www.elliottsprehn.com/preso/fluentconf/
[1] : https://github.com/niklasvh/html2canvas [2] : http://html2canvas.hertzen.com/
Votre application web peut maintenant prendre une capture d'écran "native" de l'ensemble du bureau du client en utilisant getUserMedia()
:
Jetez un coup d'oeil à cet exemple :
https://www.webrtc-experiment.com/Pluginfree-Screen-Sharing/
Le client devra utiliser chrome (pour l'instant) et devra activer la prise en charge de la capture d'écran sous chrome://flags.
Comme Niklas l'a mentionné, vous pouvez utiliser la bibliothèque [html2canvas][2] pour faire une capture d'écran en utilisant JS dans le navigateur. Je vais étendre sa réponse à ce point en fournissant un exemple de capture d'écran en utilisant cette bibliothèque :
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>
Dans la fonction report()
dans onrendered
après avoir obtenu l'image comme URI de données, vous pouvez la montrer à l'utilisateur et lui permettre de dessiner la "région du bug" avec la souris et ensuite envoyer une capture d'écran et les coordonnées de la région au serveur.
Dans [cet exemple][3] la version async/await
a été faite : avec la belle fonction makeScreenshot()
.][4]
Exemple simple qui permet de prendre une capture d'écran, de sélectionner une région, de décrire le bug et d'envoyer une requête POST ([ici jsfiddle][5]) (la fonction principale est 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>
[2] : https://html2canvas.hertzen.com/ [3] :
[4] : https://jsfiddle.net/rnkopL7z/ [5] : https://jsfiddle.net/rnkopL7z/3/