AngularJS Example:

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/signature_pad/1.5.3/signature_pad.min.js"></script>
<div ng-app ng-controller="LoginController">
  <div id="signaturePopup" class="modal erpModal fade" role="dialog" data-backdrop="static" data-keyboard="false">
    <div class="modal-dialog">

      <!-- Modal content-->
      <form name="signForm" class="erpForm" ng-submit="" novalidate>
        <div class="modal-content">
          <div class="modal-header greyBg">
            <button type="button" class="close" ng-click="" data-dismiss="modal">&times;</button>
            <h4 class="modal-title" style="font-weight: bold;">Sign Document</h4>
          </div>
          <div class="modal-body longModal">

            <!-- Signature Acceptance section -->
            <div ng-if="!documentPreviewEnabled" class="padd15">
              <ul class="signatureTabs nav nav-tabs">
                <li class="active"><a class="signatureTab" data-toggle="tab" data-target="#typeSign" role="tab" data-toggle="tab">Type</a></li>
                <li><a class="signatureTab" data-toggle="tab" data-target="#drawSign" role="tab" data-toggle="tab">Draw</a></li>
                <li><a class="signatureTab" data-toggle="tab" data-target="#menu2" role="tab" data-toggle="tab">Upload</a></li>
              </ul>

              <div class="tab-content">
                <div id="typeSign" class="tab-pane fade in active">
                  Type section
                </div>
                <div id="drawSign" class="tab-pane fade">
                  <h3>Menu 1</h3>
                  <div id="signature-pad" class="signature-pad">
                    <div class="signature-pad--body">
                     ...

CSS

.signature-pad {
  position: relative;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
      -ms-flex-direction: column;
          flex-direction: column;
  font-size: 10px;
  width: 100%;
  height: 100%;
  max-width: 700px;
  max-height: 460px;
  border: 1px solid #e8e8e8;
  background-color: #fff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.27), 0 0 40px rgba(0, 0, 0, 0.08) inset;
  border-radius: 4px;
  padding: 16px;
}

.signature-pad::before,
.signature-pad::after {
  position: absolute;
  z-index: -1;
  content: "";
  width: 40%;
  height: 10px;
  bottom: 10px;
  background: transparent;
  box-shadow: 0 8px 12px rgba(0, 0, 0, 0.4);
}

.signature-pad::before {
  left: 20px;
  -webkit-transform: skew(-3deg) rotate(-3deg);
          transform: skew(-3deg) rotate(-3deg);
}

.signature-pad::after {
  right: 20px;
  -webkit-transform: skew(3deg) rotate(3deg);
          transform: skew(3deg) rotate(3deg);
}

.signature-pad--body {
  position: relative;
  -webkit-box-flex: 1;
      -ms-flex: 1;
          flex: 1;
  border: 1px solid #f4f4f4;
}

.signature-pad--body
canvas {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  border-radius: 4px;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.02) inset;
}

.signature-pad--footer {
  color: #C3C3C3;
  text-align: center;
  font-size: 1.2em;
  margin-top: 8px;
}

.signature-pad--actions {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: justify;
      -ms-flex-pack: justify;
          justify-content: space-between;
  margin-top: 8px;
}

JavaScript

function LoginController($scope) {
	$scope.showSignaturePopup = (documentData) => {
  $("#signaturePopup").modal("show");

  $scope.signatureName = '';
  $scope.signatureFont = '';
  $scope.documentData = documentData;
  $scope.documentPreviewEnabled = true;


  $scope.wrapper = document.getElementById("signature-pad");
  $scope.canvas = $scope.wrapper.querySelector("canvas");
  $scope.signaturePad = new SignaturePad($scope.canvas, {
    // It's Necessary to use an opaque color when saving image as JPEG;
    // this option can be omitted if only saving as PNG or SVG
    backgroundColor: 'rgb(255, 255, 255)'
  });

  // console.log('$scope.signaturePad, $scope.canvas -------> ', $scope.signaturePad, $scope.canvas);
  window.onresize = $scope.resizeCanvas;
  $scope.resizeCanvas();
}

$scope.resizeCanvas = () => {
  // When zoomed out to less than 100%, for some very strange reason,
  // some browsers report devicePixelRatio as less than 1
  // and only part of the canvas is cleared then.
  $scope.ratio = Math.max(window.devicePixelRatio || 1, 1);

  // This part causes the canvas to be cleared
  $scope.canvas.width = $scope.canvas.offsetWidth * $scope.ratio;
  $scope.canvas.height = $scope.canvas.offsetHeight * $scope.ratio;
  $scope.canvas.getContext("2d").scale($scope.ratio, $scope.ratio);

  console.log('$scope.canvas.width, $scope.canvas.height -------> ', $scope.canvas.width, $scope.canvas.height);
  console.log('$scope.canvas.offsetWidth, $scope.canvas.offsetHeight -------> ', $scope.canvas.offsetWidth, $scope.canvas.offsetHeight);
  console.log('$scope.ratio -------> ', $scope.ratio);
  // This library does not listen for canvas changes, so after the canvas is automatically
  // cleared by the browser, SignaturePad#isEmpty might still return false, even though the
  // canvas looks empty, because the internal data of this library wasn't cleared. To make sure
  // that the state of this library is consistent with visual state of the canvas, you
  // have to...