JSFiddle - React, Tailwind, and code Playground
HTML
<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>
CSS
.bug-container {
background: rgb(255,0,0,0.1);
margin-top:20px;
text-align: center;
}
.bug {
margin-top: 10px;
cursor: crosshair;
/* border: solid 1px black; */
}
.hide {
display: none;
}
.example {
height: 100px;
background: yellow;
}
.region {
position: absolute;
background: rgba(255,0,0,0.4);
}
.send {
border-radius:5px;
padding:10px;
background: green;
cursor: pointer;
}
JavaScript
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;
console.log({b,r, scr});
b.addEventListener("click", e=>{
if(start==0) {
sx=e.offsetX+scr.offsetLeft;
sy=e.offsetY+b.offsetTop;
ex=0;
ey=0;
r.style.top = sy +'px';
r.style.left =sx +'px';
r.style.width = 0;
r.style.height = 0;
}
start=(start+1)%3;
});
b.addEventListener("mousemove", e=>{
//console.log(e)
if(start==1) {
ex=e.offsetX+scr.offsetLeft-sx;
ey=e.offsetY+b.offsetTop-sy
r.style.width = ex +'px';
r.style.height = ey +'px';
}
});
send.addEventListener("click", e=>{
start=0;
let a=100/75 //zoom out img 75%
resolve({
x:Math.floor((sx-scr.offsetLeft)*a),
y:Math.floor((sy-b.offsetTop)*a),
...