Get Off My Lawn Get Off My Lawn - 10 months ago 61
HTML Question

Crop video on canvas

I am getting

from the user's camera, and displaying it on a 1:1 square. I then have a button that takes a picture and draws it to a 1:1 canvas, the issue is that it isn't drawn in the same location on the canvas. How can I achieve this?

Here is a running example:

Here is the HTML:

<!doctype html>

<meta http-equiv="Content-Security-Policy" content="default-src * data: gap: 'unsafe-inline'; style-src * 'unsafe-eval'; media-src 'self' blob:">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/camera.css">

<div class="container">
<div class="camera">
<video id="monitor" autoplay></video>
<canvas id="photo"></canvas>
<input type=button value="&#x1F4F7;" onclick="snapshot()">
<script type="text/javascript" src="js/plugins/jquery.min.js"></script>
<script type="text/javascript" src="js/dist/pages/camera.js"></script>


Here is the CSS:

video {
width: 500px;
height: 500px;
object-fit: cover;
object-position: center;

.camera {
width: 500px;
height: 500px;
overflow: hidden;

Here is the TypeScript:

let canvas: HTMLCanvasElement;
let video: HTMLVideoElement;
$(window).on('load', async event => {
video = <HTMLVideoElement>document.getElementById('monitor');
canvas = <HTMLCanvasElement>document.getElementById('photo');

video.srcObject = await navigator.mediaDevices.getUserMedia({ video: true });
video.onloadedmetadata = () => {
canvas.width = 500;
canvas.height = 500;


function snapshot() {
canvas.getContext('2d').drawImage(video, 0, 0);

Answer Source

Your problem seems to be caused by the fact that the video element keeps the aspect ratio of the video, while the canvas does not. Also remember that ctx.drawImage takes up to eight positional and size arguments:


I did some testing, and found this to work pretty well, but your mileage may vary: .drawImage(video,80,0,480,500,0,0,500,520);

I made a jsFiddle with these numbers, check it out to see if it works for you.

W3Schools has some great documentation on how these work, I suggest reading that:

You could probably use the video's videoWidth and videoHeight attributes to calculate which numbers you need in drawImage for different aspect ratio source videos