Google's "Report a Bug" of "Feedback Tool" laat u een gebied van uw browservenster selecteren om een screenshot te maken dat wordt ingediend met uw feedback over een bug.
Google Feedback Tool Screenshot]1 Screenhot door Jason Small, geplaatst in een duplicaat vraag.
Hoe doen ze dit? Google's JavaScript feedback API wordt geladen van hier en hun overzicht van de feedback module zal de screenshot mogelijkheid demonstreren.
JavaScript kan het DOM lezen en een vrij nauwkeurige weergave daarvan renderen met canvas
. Ik ben bezig geweest met een script dat HTML omzet in een canvas afbeelding. Besloot vandaag om een implementatie ervan te maken in het verzenden van feedbacks zoals jij beschreef.
Het script maakt het mogelijk om feedback formulieren te maken die een screenshot, gemaakt op de client's browser, samen met het formulier bevatten. Het screenshot is gebaseerd op het DOM en als zodanig is het misschien niet 100% accuraat met de echte weergave omdat het geen echt screenshot maakt, maar het screenshot opbouwt op basis van de beschikbare informatie op de pagina.
Het heeft geen rendering van de server nodig, aangezien de hele afbeelding op de client's browser wordt gemaakt. Het HTML2Canvas script zelf is nog in een zeer experimentele staat, omdat het nog lang niet zoveel CSS3 attributen parseert als ik zou willen, en ook geen ondersteuning heeft om CORS afbeeldingen te laden, zelfs als er een proxy beschikbaar zou zijn.
Nog steeds vrij beperkte browser compatibiliteit (niet omdat er niet meer ondersteund kunnen worden, maar ik heb nog geen tijd gehad om het meer browser-ondersteund te maken).
Voor meer informatie, kijk eens naar de voorbeelden hier:
http://hertzen.com/experiments/jsfeedback/
edit Het html2canvas script is nu apart beschikbaar hier en enkele voorbeelden hier.
edit 2 Een andere bevestiging dat Google een zeer vergelijkbare methode gebruikt (in feite, gebaseerd op de documentatie, is het enige grote verschil hun async methode van traverseren/tekenen) is te vinden in deze presentatie van Elliott Sprehn van het Google Feedback team: http://www.elliottsprehn.com/preso/fluentconf/
Uw web app kan nu een 'native'screenshot maken van de client's gehele desktop met getUserMedia()
:
Kijk eens naar dit voorbeeld:
https://www.webrtc-experiment.com/Pluginfree-Screen-Sharing/
De client moet (voorlopig) chrome gebruiken en moet de ondersteuning voor screen capture aanzetten onder chrome://flags.
Zoals Niklas zei kun je de html2canvas bibliotheek gebruiken om een screenshot te maken met behulp van JS in de browser. Ik zal zijn antwoord in dit punt uitbreiden door een voorbeeld te geven van het maken van een screenshot met behulp van deze bibliotheek:
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>
In report()
functie in onrendered
na het verkrijgen van beeld als data URI kun je het laten zien aan de gebruiker en hem toestaan om "bug region" te tekenen met de muis en dan een screenshot en regio coördinaten naar de server te sturen.
In [dit voorbeeld][3] is async/await
versie gemaakt: met mooie makeScreenshot()
functie[.][4]
Simpel voorbeeld waarmee je screenshot kunt maken, regio kunt selecteren, bug kunt beschrijven en POST request kunt versturen ([hier jsfiddle][5]) (de hoofdfunctie is 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>