Реализация электронной подписи (рисование/ввод) на сайте

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация электронной подписи (рисование/ввод) на сайте
Простая
от 1 рабочего дня до 3 рабочих дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Реализация электронной подписи (рисование/ввод) на сайте

Электронная подпись в формате «нарисовать или напечатать» — это простейший способ получить согласие пользователя на документ. Не путать с квалифицированной электронной подписью (КЭП): здесь речь о визуальной подписи без криптографии, которая используется в договорах, согласиях, актах выполненных работ.

Три варианта ввода подписи

Нарисовать — пользователь рисует подпись мышью или стилусом на canvas. Самый привычный формат для большинства пользователей.

Напечатать — ввести имя, отображается выбранным «рукописным» шрифтом (Caveat, Dancing Script, Pacifico).

Загрузить изображение — загрузить фото/сканирование собственной подписи.

Реализация через signature_pad

Библиотека signature_pad — стандарт для canvas-подписи:

import SignaturePad from 'signature_pad';
import { useRef, useEffect, useState } from 'react';

function SignatureCanvas({ onSave, onClear }) {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const padRef = useRef<SignaturePad | null>(null);

  useEffect(() => {
    const canvas = canvasRef.current!;
    padRef.current = new SignaturePad(canvas, {
      backgroundColor: 'rgb(255, 255, 255)',
      penColor: 'rgb(0, 0, 0)',
      minWidth: 0.5,
      maxWidth: 2.5,
      throttle: 16,  // ~60fps
    });

    // Масштабирование для Retina дисплеев
    function resizeCanvas() {
      const ratio = Math.max(window.devicePixelRatio || 1, 1);
      canvas.width = canvas.offsetWidth * ratio;
      canvas.height = canvas.offsetHeight * ratio;
      const ctx = canvas.getContext('2d')!;
      ctx.scale(ratio, ratio);
      padRef.current!.clear();
    }

    resizeCanvas();
    window.addEventListener('resize', resizeCanvas);
    return () => window.removeEventListener('resize', resizeCanvas);
  }, []);

  const handleSave = () => {
    if (padRef.current!.isEmpty()) return;
    const dataUrl = padRef.current!.toDataURL('image/png');
    onSave(dataUrl);
  };

  return (
    <div className="border-2 border-dashed border-gray-300 rounded-lg">
      <canvas
        ref={canvasRef}
        className="w-full h-40 touch-none"  // touch-none важно для мобильных
      />
      <div className="flex gap-2 p-2">
        <button onClick={() => { padRef.current!.clear(); onClear(); }}>Очистить</button>
        <button onClick={handleSave} className="btn-primary">Подписать</button>
      </div>
    </div>
  );
}

Ввод текстовой подписи

const SIGNATURE_FONTS = [
  { name: 'Caveat', label: 'Рукописный 1' },
  { name: 'Dancing Script', label: 'Рукописный 2' },
  { name: 'Pacifico', label: 'Каллиграфия' },
];

function TextSignature({ name, onSave }) {
  const [selectedFont, setSelectedFont] = useState(SIGNATURE_FONTS[0]);
  const canvasRef = useRef<HTMLCanvasElement>(null);

  const renderToCanvas = (font: string, text: string) => {
    const canvas = canvasRef.current!;
    const ctx = canvas.getContext('2d')!;
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.font = `48px "${font}"`;
    ctx.fillStyle = '#1a1a1a';
    ctx.fillText(text, 20, 70);
    return canvas.toDataURL('image/png');
  };

  return (
    <div>
      <div className="flex gap-2 mb-3">
        {SIGNATURE_FONTS.map(font => (
          <button
            key={font.name}
            style={{ fontFamily: font.name }}
            onClick={() => setSelectedFont(font)}
            className={selectedFont.name === font.name ? 'border-blue-500 border-2' : ''}
          >
            {name}
          </button>
        ))}
      </div>
      <canvas ref={canvasRef} width={400} height={100} className="border rounded" />
      <button onClick={() => onSave(renderToCanvas(selectedFont.name, name))}>
        Применить подпись
      </button>
    </div>
  );
}

Встройка подписи в документ

После получения подписи как base64 PNG, встраиваем её в документ. Для PDF — через PDF-lib:

import { PDFDocument } from 'pdf-lib';

async function embedSignatureInPdf(pdfBytes, signatureDataUrl, position) {
  const pdfDoc = await PDFDocument.load(pdfBytes);
  const pages = pdfDoc.getPages();
  const targetPage = pages[position.page];

  const signatureBytes = Buffer.from(signatureDataUrl.split(',')[1], 'base64');
  const signatureImage = await pdfDoc.embedPng(signatureBytes);

  targetPage.drawImage(signatureImage, {
    x: position.x,
    y: position.y,
    width: position.width,
    height: position.height,
  });

  return await pdfDoc.save();
}

Хранение и аудит

Подпись как изображение сохраняется в S3. В БД фиксируется: user_id, timestamp, IP-адрес, user-agent, document_id, hash документа. Это обеспечивает базовый аудит-след.

Сроки

Компонент с тремя методами подписи (рисование, текст, загрузка) и встройкой в PDF — 2–3 дня.