Foro

Home Forums Apache Cordova jsignature a imagen base 64

This topic contains 6 replies, has 4 voices, and was last updated by  angelusnl 3 meses .

Viendo 7 respuestas - de la 1 a 7 (de 7 en total)
  • jsignature a imagen base 64

    Intervenciones
  • Jorge Tejeda 
    Participant

    Estoy desarrollando un proyecto en donde debe de incluir una firma digital y lo incluya en un pdf ya genere el pdf solo me falta convertir la firma en una imagen base 64 la app debe ser offline.
    En verdad espero y me ayuden se los agrade seria mucho solo falta que la firma se genere en una imagen base 64 para luego incluirlo en el pdf.

    <iframe src=”https://onedrive.live.com/embed?cid=EDFA52DAB16D7244&resid=EDFA52DAB16D7244%21330&authkey=AKm6IyUe5UfoL0g” width=”192″ height=”320″ frameborder=”0″ scrolling=”no”></iframe>

    Aquí pueden descargar el proyecto completo para ver el código mejor
    https://onedrive.live.com/redir?resid=EDFA52DAB16D7244!331&authkey=!AIUH9czmznvjEaA&ithint=file%2crar

    espero su ayuda gracias se los agrede seria mucho si me respondieran


    Jorge Tejeda 
    Participant



    Jorge Tejeda 
    Participant

    Una captura de la app

    Codigo de la firma

     Code: signature_pad.js (select
    1.
    2.
    3.
    4.
    5.
    6.
    7.
    8.
    9.
    10.
    11.
    12.
    13.
    14.
    15.
    16.
    17.
    18.
    19.
    20.
    21.
    22.
    23.
    24.
    25.
    26.
    27.
    28.
    29.
    30.
    31.
    32.
    33.
    34.
    35.
    36.
    37.
    38.
    39.
    40.
    41.
    42.
    43.
    44.
    45.
    46.
    47.
    48.
    49.
    50.
    51.
    52.
    53.
    54.
    55.
    56.
    57.
    58.
    59.
    60.
    61.
    62.
    63.
    64.
    65.
    66.
    67.
    68.
    69.
    70.
    71.
    72.
    73.
    74.
    75.
    76.
    77.
    78.
    79.
    80.
    81.
    82.
    83.
    84.
    85.
    86.
    87.
    88.
    89.
    90.
    91.
    92.
    93.
    94.
    95.
    96.
    97.
    98.
    99.
    100.
    101.
    102.
    103.
    104.
    105.
    106.
    107.
    108.
    109.
    110.
    111.
    112.
    113.
    114.
    115.
    116.
    117.
    118.
    119.
    120.
    121.
    122.
    123.
    124.
    125.
    126.
    127.
    128.
    129.
    130.
    131.
    132.
    133.
    134.
    135.
    136.
    137.
    138.
    139.
    140.
    141.
    142.
    143.
    144.
    145.
    146.
    147.
    148.
    149.
    150.
    151.
    152.
    153.
    154.
    155.
    156.
    157.
    158.
    159.
    160.
    161.
    162.
    163.
    164.
    165.
    166.
    167.
    168.
    169.
    170.
    171.
    172.
    173.
    174.
    175.
    176.
    177.
    178.
    179.
    180.
    181.
    182.
    183.
    184.
    185.
    186.
    187.
    188.
    189.
    190.
    191.
    192.
    193.
    194.
    195.
    196.
    197.
    198.
    199.
    200.
    201.
    202.
    203.
    204.
    205.
    206.
    207.
    208.
    209.
    210.
    211.
    212.
    213.
    214.
    215.
    216.
    217.
    218.
    219.
    220.
    221.
    222.
    223.
    224.
    225.
    226.
    227.
    228.
    229.
    230.
    231.
    232.
    233.
    234.
    235.
    236.
    237.
    238.
    239.
    240.
    241.
    242.
    243.
    244.
    245.
    246.
    247.
    248.
    249.
    250.
    251.
    252.
    253.
    254.
    255.
    256.
    257.
    258.
    259.
    260.
    261.
    262.
    263.
    264.
    265.
    266.
    267.
    268.
    269.
    270.
    271.
    272.
    273.
    274.
    275.
    276.
    277.
    278.
    279.
    280.
    281.
    282.
    283.
    284.
    285.
    286.
    287.
    288.
    289.
    290.
    291.
    292.
    293.
    294.
    295.
    296.
    297.
    298.
    299.
    300.
    301.
    302.
    303.
    304.
    305.
    306.
    307.
    308.
    309.
    310.
    311.
    312.
    313.
    314.
    315.
    316.
    317.
    318.
    319.
    320.
    321.
    322.
    323.
    324.
    325.
    326.
    327.
    328.
    329.
    330.
    331.
    332.
    333.
    334.
    335.
    336.
    337.
    338.
    339.
    340.
    341.
    342.
    343.
    344.
    345.
    346.
    347.
    348.
    349.
    350.
    351.
    352.
    353.
    354.
    355.
    356.
    357.
    358.
    359.
    360.
    361.
    362.
    363.
    364.
    365.
    366.
    367.
    368.
    369.
    370.
    371.
    372.
    373.
    374.
    375.
    376.
    377.
    378.
    379.
    380.
    381.
    382.
    383.
    384.
    385.

    (function (root, factory) {
      if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module unless amdModuleId is set
        define([], function () {
          return (root['SignaturePad'] = factory());
        });
      } else if (typeof exports === 'object') {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like environments that support module.exports,
        // like Node.
        module.exports = factory();
      } else {
        root['SignaturePad'] = factory();
      }
    }(this, function () {

    /*!
    * Signature Pad v1.5.0
    * https://github.com/szimek/signature_pad
    *
    * Copyright 2015 Szymon Nowak
    * Released under the MIT license
    *
    * The main idea and some parts of the code (e.g. drawing variable width Bézier curve) are taken from:
    * http://corner.squareup.com/2012/07/smoother-signatures.html
    *
    * Implementation of interpolation using cubic Bézier curves is taken from:
    * http://benknowscode.wordpress.com/2012/09/14/path-interpolation-using-cubic-bezier-and-control-point-estimation-in-javascript
    *
    * Algorithm for approximated length of a Bézier curve is taken from:
    * http://www.lemoda.net/maths/bezier-length/index.html
    *
    */
    var SignaturePad = (function (document) {
        "use strict";

        var SignaturePad = function (canvas, options) {
            var self = this,
                opts = options || {};

            this.velocityFilterWeight = opts.velocityFilterWeight || 0.7;
            this.minWidth = opts.minWidth || 0.5;
            this.maxWidth = opts.maxWidth || 2.5;
            this.dotSize = opts.dotSize || function () {
                return (this.minWidth + this.maxWidth) / 2;
            };
            this.penColor = opts.penColor || "black";
            this.backgroundColor = opts.backgroundColor || "rgba(0,0,0,0)";
            this.onEnd = opts.onEnd;
            this.onBegin = opts.onBegin;

            this._canvas = canvas;
            this._ctx = canvas.getContext("2d");
            this.clear();

            // we need add these inline so they are available to unbind while still having
            //  access to 'self' we could use _.bind but it's not worth adding a dependency
            this._handleMouseDown = function (event) {
                if (event.which === 1) {
                    self._mouseButtonDown = true;
                    self._strokeBegin(event);
                }
            };

            this._handleMouseMove = function (event) {
                if (self._mouseButtonDown) {
                    self._strokeUpdate(event);
                }
            };

            this._handleMouseUp = function (event) {
                if (event.which === 1 && self._mouseButtonDown) {
                    self._mouseButtonDown = false;
                    self._strokeEnd(event);
                }
            };

            this._handleTouchStart = function (event) {
                var touch = event.changedTouches[0];
                self._strokeBegin(touch);
            };

            this._handleTouchMove = function (event) {
                // Prevent scrolling.
                event.preventDefault();

                var touch = event.changedTouches[0];
                self._strokeUpdate(touch);
            };

            this._handleTouchEnd = function (event) {
                var wasCanvasTouched = event.target === self._canvas;
                if (wasCanvasTouched) {
                    self._strokeEnd(event);
                }
            };

            this._handleMouseEvents();
            this._handleTouchEvents();
        };

        SignaturePad.prototype.clear = function () {
            var ctx = this._ctx,
                canvas = this._canvas;

            ctx.fillStyle = this.backgroundColor;
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            this._reset();
        };

        SignaturePad.prototype.toDataURL = function (imageType, quality) {
            var canvas = this._canvas;
            return canvas.toDataURL.apply(canvas, arguments);
        };

        SignaturePad.prototype.fromDataURL = function (dataUrl) {
            var self = this,
                image = new Image(),
                ratio = window.devicePixelRatio || 1,
                width = this._canvas.width / ratio,
                height = this._canvas.height / ratio;

            this._reset();
            image.src = dataUrl;
            image.onload = function () {
                self._ctx.drawImage(image, 0, 0, width, height);
            };
            this._isEmpty = false;
        };

        SignaturePad.prototype._strokeUpdate = function (event) {
            var point = this._createPoint(event);
            this._addPoint(point);
        };

        SignaturePad.prototype._strokeBegin = function (event) {
            this._reset();
            this._strokeUpdate(event);
            if (typeof this.onBegin === 'function') {
                this.onBegin(event);
            }
        };

        SignaturePad.prototype._strokeDraw = function (point) {
            var ctx = this._ctx,
                dotSize = typeof(this.dotSize) === 'function' ? this.dotSize() : this.dotSize;

            ctx.beginPath();
            this._drawPoint(point.x, point.y, dotSize);
            ctx.closePath();
            ctx.fill();
        };

        SignaturePad.prototype._strokeEnd = function (event) {
            var canDrawCurve = this.points.length > 2,
                point = this.points[0];

            if (!canDrawCurve && point) {
                this._strokeDraw(point);
            }
            if (typeof this.onEnd === 'function') {
                this.onEnd(event);
            }
        };

        SignaturePad.prototype._handleMouseEvents = function () {
            this._mouseButtonDown = false;

            this._canvas.addEventListener("mousedown", this._handleMouseDown);
            this._canvas.addEventListener("mousemove", this._handleMouseMove);
            document.addEventListener("mouseup", this._handleMouseUp);
        };

        SignaturePad.prototype._handleTouchEvents = function () {
            // Pass touch events to canvas element on mobile IE.
            this._canvas.style.msTouchAction = 'none';

            this._canvas.addEventListener("touchstart", this._handleTouchStart);
            this._canvas.addEventListener("touchmove", this._handleTouchMove);
            document.addEventListener("touchend", this._handleTouchEnd);
        };

        SignaturePad.prototype.on = function () {
            this._handleMouseEvents();
            this._handleTouchEvents();
        };

        SignaturePad.prototype.off = function () {
            this._canvas.removeEventListener("mousedown", this._handleMouseDown);
            this._canvas.removeEventListener("mousemove", this._handleMouseMove);
            document.removeEventListener("mouseup", this._handleMouseUp);

            this._canvas.removeEventListener("touchstart", this._handleTouchStart);
            this._canvas.removeEventListener("touchmove", this._handleTouchMove);
            document.removeEventListener("touchend", this._handleTouchEnd);
        };

        SignaturePad.prototype.isEmpty = function () {
            return this._isEmpty;
        };

        SignaturePad.prototype._reset = function () {
            this.points = [];
            this._lastVelocity = 0;
            this._lastWidth = (this.minWidth + this.maxWidth) / 2;
            this._isEmpty = true;
            this._ctx.fillStyle = this.penColor;
        };

        SignaturePad.prototype._createPoint = function (event) {
            var rect = this._canvas.getBoundingClientRect();
            return new Point(
                event.clientX - rect.left,
                event.clientY - rect.top
            );
        };

        SignaturePad.prototype._addPoint = function (point) {
            var points = this.points,
                c2, c3,
                curve, tmp;

            points.push(point);

            if (points.length > 2) {
                // To reduce the initial lag make it work with 3 points
                // by copying the first point to the beginning.
                if (points.length === 3) points.unshift(points[0]);

                tmp = this._calculateCurveControlPoints(points[0], points[1], points[2]);
                c2 = tmp.c2;
                tmp = this._calculateCurveControlPoints(points[1], points[2], points[3]);
                c3 = tmp.c1;
                curve = new Bezier(points[1], c2, c3, points[2]);
                this._addCurve(curve);

                // Remove the first element from the list,
                // so that we always have no more than 4 points in points array.
                points.shift();
            }
        };

        SignaturePad.prototype._calculateCurveControlPoints = function (s1, s2, s3) {
            var dx1 = s1.x - s2.x, dy1 = s1.y - s2.y,
                dx2 = s2.x - s3.x, dy2 = s2.y - s3.y,

                m1 = {x: (s1.x + s2.x) / 2.0, y: (s1.y + s2.y) / 2.0},
                m2 = {x: (s2.x + s3.x) / 2.0, y: (s2.y + s3.y) / 2.0},

                l1 = Math.sqrt(dx1*dx1 + dy1*dy1),
                l2 = Math.sqrt(dx2*dx2 + dy2*dy2),

                dxm = (m1.x - m2.x),
                dym = (m1.y - m2.y),

                k = l2 / (l1 + l2),
                cm = {x: m2.x + dxm*k, y: m2.y + dym*k},

                tx = s2.x - cm.x,
                ty = s2.y - cm.y;

            return {
                c1: new Point(m1.x + tx, m1.y + ty),
                c2: new Point(m2.x + tx, m2.y + ty)
            };
        };

        SignaturePad.prototype._addCurve = function (curve) {
            var startPoint = curve.startPoint,
                endPoint = curve.endPoint,
                velocity, newWidth;

            velocity = endPoint.velocityFrom(startPoint);
            velocity = this.velocityFilterWeight * velocity
                + (1 - this.velocityFilterWeight) * this._lastVelocity;

            newWidth = this._strokeWidth(velocity);
            this._drawCurve(curve, this._lastWidth, newWidth);

            this._lastVelocity = velocity;
            this._lastWidth = newWidth;
        };

        SignaturePad.prototype._drawPoint = function (x, y, size) {
            var ctx = this._ctx;

            ctx.moveTo(x, y);
            ctx.arc(x, y, size, 0, 2 * Math.PI, false);
            this._isEmpty = false;
        };

        SignaturePad.prototype._drawCurve = function (curve, startWidth, endWidth) {
            var ctx = this._ctx,
                widthDelta = endWidth - startWidth,
                drawSteps, width, i, t, tt, ttt, u, uu, uuu, x, y;

            drawSteps = Math.floor(curve.length());
            ctx.beginPath();
            for (i = 0; i < drawSteps; i++) {
                // Calculate the Bezier (x, y) coordinate for this step.
                t = i / drawSteps;
                tt = t * t;
                ttt = tt * t;
                u = 1 - t;
                uu = u * u;
                uuu = uu * u;

                x = uuu * curve.startPoint.x;
                x += 3 * uu * t * curve.control1.x;
                x += 3 * u * tt * curve.control2.x;
                x += ttt * curve.endPoint.x;

                y = uuu * curve.startPoint.y;
                y += 3 * uu * t * curve.control1.y;
                y += 3 * u * tt * curve.control2.y;
                y += ttt * curve.endPoint.y;

                width = startWidth + ttt * widthDelta;
                this._drawPoint(x, y, width);
            }
            ctx.closePath();
            ctx.fill();
        };

        SignaturePad.prototype._strokeWidth = function (velocity) {
            return Math.max(this.maxWidth / (velocity + 1), this.minWidth);
        };


        var Point = function (x, y, time) {
            this.x = x;
            this.y = y;
            this.time = time || new Date().getTime();
        };

        Point.prototype.velocityFrom = function (start) {
            return (this.time !== start.time) ? this.distanceTo(start) / (this.time - start.time) : 1;
        };

        Point.prototype.distanceTo = function (start) {
            return Math.sqrt(Math.pow(this.x - start.x, 2) + Math.pow(this.y - start.y, 2));
        };

        var Bezier = function (startPoint, control1, control2, endPoint) {
            this.startPoint = startPoint;
            this.control1 = control1;
            this.control2 = control2;
            this.endPoint = endPoint;
        };

        // Returns approximated length.
        Bezier.prototype.length = function () {
            var steps = 10,
                length = 0,
                i, t, cx, cy, px, py, xdiff, ydiff;

            for (i = 0; i <= steps; i++) {
                t = i / steps;
                cx = this._point(t, this.startPoint.x, this.control1.x, this.control2.x, this.endPoint.x);
                cy = this._point(t, this.startPoint.y, this.control1.y, this.control2.y, this.endPoint.y);
                if (i > 0) {
                    xdiff = cx - px;
                    ydiff = cy - py;
                    length += Math.sqrt(xdiff * xdiff + ydiff * ydiff);
                }
                px = cx;
                py = cy;
            }
            return length;
        };

        Bezier.prototype._point = function (t, start, c1, c2, end) {
            return          start * (1.0 - t) * (1.0 - t)  * (1.0 - t)
                   + 3.0 *  c1    * (1.0 - t) * (1.0 - t)  * t
                   + 3.0 *  c2    * (1.0 - t) * t          * t
                   +        end   * t         * t          * t;
        };

        return SignaturePad;
    })(document);

    return SignaturePad;

    }));

     Code: app.js (select
    1.
    2.
    3.
    4.
    5.
    6.
    7.
    8.
    9.
    10.
    11.
    12.
    13.
    14.
    15.
    16.
    17.
    18.
    19.
    20.
    21.
    22.
    23.
    24.
    25.
    26.
    27.
    28.
    29.
    30.
    31.
    32.
    33.
    34.
    35.

    var wrapper = document.getElementById("signature-pad"),
        clearButton = wrapper.querySelector("[data-action=clear]"),
        saveButton = wrapper.querySelector("[data-action=save]"),
        canvas = wrapper.querySelector("canvas"),
        signaturePad;

    // Adjust canvas coordinate space taking into account pixel ratio,
    // to make it look crisp on mobile devices.
    // This also causes canvas to be cleared.
    function 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.
        var ratio =  Math.max(window.devicePixelRatio || 1, 1);
        canvas.width = canvas.offsetWidth * ratio;
        canvas.height = canvas.offsetHeight * ratio;
        canvas.getContext("2d").scale(ratio, ratio);
    }

    window.onresize = resizeCanvas;
    resizeCanvas();

    signaturePad = new SignaturePad(canvas);

    clearButton.addEventListener("click", function (event) {
        signaturePad.clear();
    });

    saveButton.addEventListener("click", function (event) {
        if (signaturePad.isEmpty()) {
            alert("Aun no a firmado");
        } else {
            window.open(signaturePad.toDataURL());
        }
    });

     Code: index.html (select
    1.
    2.
    3.
    4.
    5.
    6.
    7.
    8.
    9.
    10.
    11.
    12.
    13.
    14.
    15.
    16.
    17.
    18.
    19.
    20.
    21.
    22.
    23.
    24.
    25.
    26.
    27.
    28.
    29.
    30.
    31.
    32.
    33.
    34.
    35.
    36.
    37.
    38.
    39.
    40.
    41.
    42.
    43.
    44.
    45.
    46.
    47.
    48.
    49.
    50.
    51.
    52.
    53.
    54.
    55.
    56.
    57.
    58.
    59.
    60.
    61.
    62.
    63.
    64.
    65.
    66.
    67.
    68.

    <!DOCTYPE html>
    <html>
        <head>
             <meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval' http://localhost:1337 " >
            <meta name="format-detection" content="telephone=no">
            <meta name="msapplication-tap-highlight" content="no">
            <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
            
            <title>Hello World</title>
            <link rel="stylesheet" href="css/signature-pad.css">
            
            <script type="text/javascript" src="cordova.js"></script>
            <script type="text/javascript" src="js/index.js"></script>
            <script type="text/javascript" src="js/jspdf.js"></script>
            <script type="text/javascript" src="js/jspdf.debug.js"></script><!---->
        <script type="text/javascript" src="plugins/cordoba-plugin-file/FileSystem.js"></script>
            
         <script type="text/javascript" src="js/minuta.js"></script>
        
         <script type="text/javascript">
            var _gaq = _gaq || [];
            _gaq.push(['_setAccount', 'UA-39365077-1']);
            _gaq.push(['_trackPageview']);

            (function() {
            var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
           ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
          var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
             })();
           </script>
        
            
        </head>
        <body onselectstart="return false">
        
          <p align="center"><strong>Firma en PDF</p>
           <br />
           <b>
           <label  style="color: blue" for="fecha">Fecha</label>
           </b>
           <input type="date"   id="fecha" value="" required>
           </label>
           <br>

           <div id="signature-pad">
            <div>
            <canvas></canvas>
            </div>
            <div>
            <div>Firma</div>
            <button class="button clear" data-action="clear">Borrar</button>
            <button class="button save" data-action="save">Aceptar</button>
            </div>
            </div>
            
            <script src="js/signature_pad.js"></script>
            <script src="js/app.js"></script>
          
          
           <button onClick="javascript:imprimir();">
           Enviar por Correo
           </button>
          
          
          
            
        </body>
    </html>


    Jorge Tejeda 
    Participant

    Bueno en busca de que nadie me respondió estuve investigando sobre el asunto y gracias a Dios por fin pude lograr hacerlo me costo un poco ya que soy nuevo en esto pero a qui les comparto mi solución por si alguien le interesa Gracias de antemano… :wink:

    Descargue el plugin jSignature y lo modifique con forme a mis necesidades. demo about


    Funcionando en el Móvil


    Visualizando la firma en Imagen

    Convirtiendo la imagen en base64 para capturar la firma en el pdf

    Seleccionando EL checkbox correspondiente al personal que firmo en este caso firma del SUPERVISOR para capturar el dodigo generado de la imagen base64

    Caprurando la firma del CIA. Contratista ó Particular.

    Seleccionando el checkbox correspondiente de la persona que firmo

    Después con con un simple código javascript fui capturando los datos que generaba cuando pasaba la firma a base64 dependiendo que firma iba a capturar

    Y ya para darle el toque final use la librería jspdf para generar mi pdf firmado con las capturas de las firmas demo

    Generando el PDF ya con las capturas de las firmas


    Opción para enviarlo por correo

    Entrando al gestor de archivos para ver el pdf generado

    Y por fin Visualizando el PDF ya con las firmas este es el momento mas alegre :lol:


    Bueno espero y le sirva a alguien que este desarrollando un proyecto maso menos al mio Saludos…………………
    Proyecto Completo Link


    Solidux
    Solidux 
    Participant

    Gracias por compartir


    alex_0a2 
    Participant

    Buenas Tardes, me ayudarías con tu proyecto final?
    el link está caído
    Gracias !!


    angelusnl 
    Participant

    Serias tan amable de compartir nuevamente tu proyecto, gracias.


Viendo 7 respuestas - de la 1 a 7 (de 7 en total)

You must be logged in to reply to this topic.