Responsive Signautre Pad

by Julian Witzel

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/signature_pad/1.5.3/signature_pad.min.js"></script>
<div class="form_field-wrapper">
  <div class="form_label">Signature</div>
  <div class="form_signature-wrapper">
    <canvas
            id="signature-pad"
            class="form_signature-canvas"
            width=""
            height=""
            style="touch-action: none"></canvas
      ><button
               data-action="clear"
               type="button"
               class="form_signature-btn is-clear">
    Delete
    </button>
  </div>
  <div class="form_info-wrapper is-signature form_label">
    <div class="form_info-icon">
      <svg
           fill="none"
           xmlns="http://www.w3.org/2000/svg"
           viewBox="0 0 14 14">
        <path
              d="M7 14a7 7 0 1 1 7-7 7.007 7.007 0 0 1-7 7ZM7 1.167A5.833 5.833 0 1 0 12.833 7 5.84 5.84 0 0 0 7 1.167Z"
              fill="currentColor"></path>
        <path
              d="M7.583 8.75H6.416v-.434a2.306 2.306 0 0 1 1.146-2.041A1.167 1.167 0 1 0 5.833 5.25H4.666a2.333 2.333 0 1 1 3.46 2.044 1.156 1.156 0 0 0-.543 1.022v.434ZM7.583 9.916H6.416v1.167h1.167V9.916Z"
              fill="currentColor"></path>
      </svg>
    </div>
    <div class="form_info">Please add your signature</div>
  </div>
</div>

CSS

<style>
			html,
			body {
				margin: 0;
				padding: 0;
			}
			body {
				background: #0c0c0c;
				font-family: sans-serif;
			}

			.form_field-wrapper {
				max-width: 600px;
				margin: 0 auto;
				padding: 2rem 0;
			}

			.form_label {
				color: #fff;
				margin-bottom: 0.5rem;
			}

			.form_signature-wrapper {
				width: 100%;
				height: auto;
				aspect-ratio: 5/3;
			}
			.form_signature-canvas {
				height: 100%;
				width: 100%;
				display: block;
				box-sizing: border-box;
				border: 1px solid rgba(255, 255, 255, 0.1);
				border-radius: 0.25rem 0.25rem 0 0;
			}

			.form_signature-wrapper {
				position: relative;
			}
			.form_signature-wrapper button {
				appearance: none;
				outline: none;
				border: none;
				box-shadow: none;

				font-weight: 600;
				color: #fff;
				background: rgba(255, 255, 255, 0.1);
				padding: 0.5rem;
				border-radius: 0.25rem;

				position: absolute;
				top: 0.75rem;
				right: 0.75rem;

				transition: 100ms ease-in-out background;
			}
			.form_signature-wrapper button:hover {
				background: rgba(255, 255, 255, 0.2);
				cursor: pointer;
			}

			.form_info-wrapper {
				display: flex;
				gap: 0.5rem;
				padding: 0.5rem;
				background: rgba(255, 255, 255, 0.1);
				border-radius: 0 0 0.25rem 0.25rem;
				font-size: 0.875rem;
			}
			.form_info-icon {
				height: 1rem;
				width: 1rem;
			}
			.form_info-icon svg {
				display: flex;
				height: auto;
				width: 100%;
			}
		</style>

JavaScript

function initializeSignaturePad() {
				const wrapper = document.querySelector('.form_signature-wrapper');
				const canvas = wrapper.querySelector('#signature-pad');
				const clearButton = wrapper.querySelector('[data-action=clear]');

				let signaturePad;

				function resizeCanvas() {
					const ratio = Math.max(window.devicePixelRatio || 1, 1);
					const rect = wrapper.getBoundingClientRect();

					canvas.width = rect.width * ratio;
					canvas.height = rect.height * ratio;
					canvas.getContext('2d').scale(ratio, ratio);

					// signaturePad.fromData(signaturePad.toData());
				}

				function initPad() {
					signaturePad = new SignaturePad(canvas, {
						penColor: 'rgb(255, 255, 255)',
						minWidth: 0.5,
						maxWidth: 2.5,
						throttle: 0,
						minDistance: 0,
						velocityFilterWeight: 0.4,
					});

					updateMousePosition();
				}

				function updateMousePosition() {
					const rect = canvas.getBoundingClientRect();
					const scaleX = canvas.width / rect.width;
					const scaleY = canvas.height / rect.height;

					function getPointFromEvent(event) {
						let x, y;
						if (event.touches && event.touches.length > 0) {
							const touch = event.touches[0];
							x = touch.clientX;
							y = touch.clientY;
						} else {
							x = event.clientX;
							y = event.clientY;
						}
						x = (x - rect.left) * scaleX;
						y = (y - rect.top) * scaleY;
						return new SignaturePad.Point(x, y);
					}

					const originalOnMouseDown = signaturePad._handleMouseDown;
					signaturePad._handleMouseDown = function (event) {
						const point = getPointFromEvent(event);
						originalOnMouseDown.call(signaturePad, event, point);
					};

					const originalOnMouseMove = signaturePad._handleMouseMove;
					signaturePad._handleMouseMove = function (event) {
						const point = getPointFromEvent(event);
						originalOnMouseMove.call(signaturePad, event, point);
					};

					const originalOnTouchStart =...