Friday, January 9, 2026

Create Capture Screen with Vanilla.js

1.index.html

ml

<!DOCTYPE html>
<html>
<head>
  <title>Screen Select to Base64</title>
  <style>
    body { font-family: Arial; }
    #overlay {
      position: fixed;
      top: 0; left: 0;
      width: 100vw; height: 100vh;
      cursor: crosshair;
      background: rgba(0,0,0,0.2);
      display: none;
    }
    #selection {
      position: absolute;
      border: 2px dashed red;
      background: rgba(255,0,0,0.2);
    }
  </style>
</head>
<body>

<button onclick="startCapture()">Capture Screen</button>
<button onclick="downloadImage()">Download</button>

<video id="video" autoplay style="display:none;"></video>
<canvas id="canvas" style="display:none;"></canvas>

<div id="overlay">
  <div id="selection"></div>
</div>

<script src="screen.js"></script>
</body>
</html>

2. screen.js

const video = document.getElementById('video');
const canvas = document.getElementById('canvas');
const overlay = document.getElementById('overlay');
const selection = document.getElementById('selection');

let startX, startY, endX, endY;
let base64Image = null;

/* 1. Capture Screen */
async function startCapture() {
  const stream = await navigator.mediaDevices.getDisplayMedia({
    video: { cursor: "always" }
  });

  video.srcObject = stream;
  video.onloadedmetadata = () => {
    video.play();
    overlay.style.display = 'block';
  };
}

/* 2. Select Area */
overlay.addEventListener('mousedown', e => {
  startX = e.clientX;
  startY = e.clientY;

  selection.style.left = startX + 'px';
  selection.style.top = startY + 'px';
  selection.style.width = 0;
  selection.style.height = 0;

  overlay.addEventListener('mousemove', onMouseMove);
});

overlay.addEventListener('mouseup', e => {
  endX = e.clientX;
  endY = e.clientY;

  overlay.removeEventListener('mousemove', onMouseMove);
  overlay.style.display = 'none';

  cropImage();
});

function onMouseMove(e) {
  const width = e.clientX - startX;
  const height = e.clientY - startY;

  selection.style.width = Math.abs(width) + 'px';
  selection.style.height = Math.abs(height) + 'px';
  selection.style.left = Math.min(startX, e.clientX) + 'px';
  selection.style.top = Math.min(startY, e.clientY) + 'px';
}

/* 3. Crop to Canvas */
function cropImage() {
  const scaleX = video.videoWidth / window.innerWidth;
  const scaleY = video.videoHeight / window.innerHeight;

  const x = Math.min(startX, endX) * scaleX;
  const y = Math.min(startY, endY) * scaleY;
  const width = Math.abs(endX - startX) * scaleX;
  const height = Math.abs(endY - startY) * scaleY;

  canvas.width = width;
  canvas.height = height;

  const ctx = canvas.getContext('2d');
  ctx.drawImage(video, x, y, width, height, 0, 0, width, height);

  base64Image = canvas.toDataURL('image/png');
  console.log(base64Image);
}

/* 4. Download */
function downloadImage() {
  if (!base64Image) {
    alert("Belum ada gambar!");
    return;
  }

  const a = document.createElement('a');
  a.href = base64Image;
  a.download = 'capture.png';
  a.click();
}


No comments:

Post a Comment

Menjadi Programmer Bukan Hanya Tentang Coding, Tapi Tentang Mempermudah Kehidupan

Semenjak menjadi seorang programmer, ada satu cara pandang yang perlahan berubah dalam diri saya. Saya mulai berpikir bahwa ilmu pemrograman...