javascriptcanvaspdf.jsdrawrectangle

Loading PDF in Canvas and Drawing rectangles


I am trying to build a web page to display a PDF file inside canvas and allow user to draw rectangles. Below is the code I'm trying. The problem is mouse event is going outside canvas also. How to restrict mouse dragging event only inside the canvas.

var url = 'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/examples/learning/helloworld.pdf';

	//Loaded via <script> tag, create shortcut to access PDF.js exports.
	var pdfjsLib = window['pdfjs-dist/build/pdf'];

	// The workerSrc property shall be specified.
	pdfjsLib.GlobalWorkerOptions.workerSrc = '//mozilla.github.io/pdf.js/build/pdf.worker.js';

	// Asynchronous download of PDF
	var loadingTask = pdfjsLib.getDocument(url);
	loadingTask.promise.then(function(pdf) {
	  console.log('PDF loaded');
	  
	  // Fetch the first page
	  var pageNumber = 1;
	  pdf.getPage(pageNumber).then(function(page) {
		console.log('Page loaded');
		
		var scale = 1.5;
		//var viewport = page.getViewport({scale: scale});
		var viewport = page.getViewport(scale);
		// Prepare canvas using PDF page dimensions
		var canvas = document.getElementById('the-canvas');
		var context = canvas.getContext('2d');
		canvas.height = viewport.height;
		canvas.width = viewport.width;

		// Render PDF page into canvas context
		var renderContext = {
		  canvasContext: context,
		  viewport: viewport
		};
		var renderTask = page.render(renderContext);
		renderTask.promise.then(function () {
		  console.log('Page rendered');
		});
	  });
	}, function (reason) {
	  // PDF loading error
	  console.error(reason);
	});


	$(function () {
		"use strict";
		var startX,
			startY,
			selectedBoxes = [],
			$selectionMarquee = $('#selectionMarquee'),
			$allCords = $('#all-cords'),
			positionBox = function ($box, coordinates) {
				$box.css(
					'top', coordinates.top
				).css(
					'left', coordinates.left
				).css(
					'height', coordinates.bottom - coordinates.top
				).css(
					'width', coordinates.right - coordinates.left
				);
			},

			compareNumbers = function (a, b) {
				return a - b;
			},
			getBoxCoordinates = function (startX, startY, endX, endY) {
				var x = [startX, endX].sort(compareNumbers),
					y = [startY, endY].sort(compareNumbers);

				return {
					top: y[0],
					left: x[0],
					right: x[1],
					bottom: y[1]
				};
			},
			trackMouse = function (event) {
				var position = getBoxCoordinates(startX, startY, event.pageX, event.pageY);
				console.log(position);
				positionBox($selectionMarquee, position);
			},
			displayCoordinates = function () {
				var msg = 'Boxes so far:\n';

				selectedBoxes.forEach(function (box) {
					msg += '<li>(' + box.left + ', ' + box.top + ') - (' + (box.left + box.right) + ', ' + (box.top + box.bottom) + ')</li>';
				});
				$allCords.html(msg);
			};

			var canvas = document.getElementById('the-canvas');
		$(document).on('mousedown', function (event) {
			startX = event.pageX;
			startY = event.pageY;
			positionBox($selectionMarquee, getBoxCoordinates(startX, startY, startX, startY));
			$selectionMarquee.show();
			$(this).on('mousemove', trackMouse);
		}).on('mouseup', function (event) {
			var position,
				$selectedBox;

				$selectionMarquee.hide();

				position = getBoxCoordinates(startX, startY, event.pageX, event.pageY);

				if (position.left !== position.right && position.top !== position.bottom) {
					$selectedBox = $('<div class="selected-box"></div>');
					$selectedBox.hide();
					$('body').append($selectedBox);

					positionBox($selectedBox, position);

					$selectedBox.show();

					selectedBoxes.push(position);
					displayCoordinates();
					$(this).off('mousemove', trackMouse);
				}
		});
	});
body {
			-webkit-touch-callout: none;
			-webkit-user-select: none;
			-khtml-user-select: none;
			-moz-user-select: none;
			-ms-user-select: none;
			user-select: none;
		}
		#selectionMarquee {
			z-position: 1000;
			position: absolute;
			border: 1px solid #FF0000;
		}

		.selected-box {
			z-position: 999;
			position: absolute;
			border: 1px solid #FF0000;
		}
		#all-cords {
			position: fixed;
			right: 0;
			bottom: 0;
			background: #9f9;
		}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<script src=https://mozilla.github.io/pdf.js></script>
<h1>Rectangle In Canvas</h1>
	<div id="selectionMarquee" style="top: 338px; left: 88px; height: 52px; width: 197px; display: none;"></div>
	<div>
	<canvas id="the-canvas" style="border:1px  solid black" width="100%" height="100%"></canvas>
	</div>
	<ol id="all-cords"></ol>

If you are not able to run the above code download pdfjs.js and worker js and include it directly in html. I'm trying something like this. But I want the rectangles to be drawn only inside the canvas.


Solution

  • var canvas = document.getElementById('the-canvas');
            $(the-canvas).on('mousedown', function (event) {
                startX = event.pageX;