您当前的位置:首页 > 文章 > HTML5 Canvas 实现在线签字功能(示例代码)

HTML5 Canvas 实现在线签字功能(示例代码)

作者:孤留光乩 时间:2024-07-12 阅读数:480 人阅读

前言

在现代互联网应用中,有时我们需要让用户在网页上进行签字操作,比如确认文件、填写电子表格或者签署合同。利用 HTML5 的 canvas 画布,我们可以轻松地实现这一功能,为用户提供方便快捷的在线签字体验。

一、HTML5 Canvas 简介

HTML5 的 canvas 元素是一种强大的图形渲染工具,它允许开发者使用 JavaScript 在网页上绘制各种图形、动画和交互式内容。通过 canvas,开发者可以创建丰富多彩的视觉效果,并实现复杂的用户交互体验。

HTML5 Canvas的关键特性:

图形绘制能力:Canvas 元素提供了绘制路径、矩形、圆形、直线、文本等基本图形的功能,同时还支持图像的绘制和变换操作,使得开发者能够轻松地创建各种视觉效果。

动画和交互:借助 JavaScript,开发者可以在 Canvas 上创建复杂的动画效果,并添加交互式的操作。这使得 Canvas 成为开发游戏、数据可视化和其他需要动态效果的应用的理想选择。

性能优势:由于 Canvas 是基于 GPU 加速的,因此它具有良好的性能表现,能够处理大量的图形元素和动画效果,而不会对页面的整体性能产生太大影响。

灵活性:Canvas 元素可以轻松地与其他 HTML 元素结合使用,使得开发者可以在页面上创建复杂的混合媒体效果,同时还可以响应用户的交互操作。

二、签字功能的实现

效果演示

完整代码

HTML代码

<!DOCTYPE html>
<htmlclass="no-js">
<head>
    <metaname="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0,user-scalable=no,viewport-fit=cover">
    <metahttp-equiv="Cache-Control"content="no-cache, no-store, must-revalidate"/>
    <metahttp-equiv="expires"CONTENT="Wed, 26 Feb 1997 08:21:57 GMT">
    <metahttp-equiv="Content-Type"content="text/html; charset=UTF-8">
    <metahttp-equiv="X-UA-Compatible"content="IE=edge">
    <metahttp-equiv="Pragma"content="no-cache">
    <metahttp-equiv="Cache"content="no-cache">
    <metahttp-equiv="Expires"content="0">
    <metacharset="utf-8">
    <title>画图</title>
    <linkrel="stylesheet"href="css/bootstrap.css">
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        html,
        body {
            width: 100%;
            height: 100%;
            text-align: center;
        }
        canvas {
            max-width: 100%;
            border: 2px dotted #ccc;
        }
    </style>
</head>
<body>
    <scriptsrc="./index.js"></script>
    <script>
        //初始化
        var sign = new Draw( {
            // canvas:document.getElementById('canvas'),
            lineWidth: 10, // 线条宽度
            width: 400, // canvas 宽
            height: 400, //canvas 高
            strokeStyle: '#333333' // 线条颜色
        } );
        window.onload = function () {
            // 点击输出图片
            document.querySelector( '.ouput' ).onclick = function () {
                var img = new Image();
                img.style.width = '200px';
                img.src = sign.ouput();
                img.onload = function () {
                    document.body.appendChild( img );
                }
                document.querySelector( 'img' ) && document.querySelector( 'img' ).remove();
            }
            // 点击清除
            document.querySelector( '.clear' ).onclick = function () {
                sign.clear();
            }
            // 点击撤销
            document.querySelector( '.undo' ).onclick = function () {
                if ( sign.state.undopath.length > 0 ) {
                    sign.undo();
                } else {
                    console.log( '还没有签名' );
                }
            }
        }
    </script>
    <divclass="buttons">
        <buttontype="button"class="btn btn-primary ouput">生成图片</button>
        <buttontype="button"class="btn btn-light undo">撤销</button>
        <buttontype="button"class="btn btn-light clear">清除画布</button>
    </div>
</body>
</html>

js代码

(function( global, factory ) {
    typeofexports ==='object'&&typeofmodule !=='undefined'? module.exports = factory() :
        typeofdefine ==='function'&& define.amd ? define( factory ) :
            ( global = global || self, global.Draw = factory() );
}(this, (function() {
    'use strict';
    varclassCallCheck =function( instance, Constructor ) {
        if( !( instanceinstanceofConstructor ) ) {
            thrownewTypeError("Cannot call a class as a function");
        }
    };
    varcreateClass =function() {
        functiondefineProperties ( target, props ) {
            for(vari = 0; i < props.length; i++ ) {
                vardescriptor = props[i];
                descriptor.enumerable = descriptor.enumerable ||false;
                descriptor.configurable =true;
                if("value"indescriptor ) descriptor.writable =true;
                Object.defineProperty( target, descriptor.key, descriptor );
            }
        }
        returnfunction( Constructor, protoProps, staticProps ) {
            if( protoProps ) defineProperties( Constructor.prototype, protoProps );
            if( staticProps ) defineProperties( Constructor, staticProps );
            returnConstructor;
        };
    }();
    /**
     *
     * @description  手写签字版
     */
    varDraw =function() {
        functionDraw () {
            varparams = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
            classCallCheck(this, Draw );
            this.el = params.el || document.createElement('canvas');
            this.state = {
                undopath: [],
                index: -1,
                old: void 0,
                isStart:false,
                width: params.width || 400,
                height: params.height || 400,
                lineWidth: params.lineWidth || 1,
                isTouch:'ontouchstart'inwindow,
                strokeStyle: params.strokeStyle ||'#333333'
            };
            var_state =this.state,
                width = _state.width,
                height = _state.height,
                lineWidth = _state.lineWidth;
            this.el.width = width * 2;
            this.el.height = height * 2;
            document.body.appendChild(this.el );
            this.ctx =this.el.getContext('2d');
            this.ctx.scale( 2, 2 );
            this.ctx.lineWidth = lineWidth;
            this.ctx.lineJoin ='round';
            this.ctx.lineCap ='round';
            this.init();
        }
        createClass( Draw, [{
            key:'onStart',
            value:functiononStart () {
                ++this.state.index;
                this.state.isStart =true;
            }
        }, {
            key:'onMove',
            value:functiononMove ( e ) {
                e.preventDefault();
                if( !this.state.isStart )return;
                varpos =this.pos( e );
                varindex =this.state.index;
                this.ctx.strokeStyle =this.state.strokeStyle;
                if(this.state.old ) {
                    this.ctx.beginPath();
                    this.ctx.moveTo(this.state.old.x,this.state.old.y );
                    this.ctx.lineTo( pos.x, pos.y );
                    this.ctx.stroke();
                }
                this.state.old = pos;
                if(this.state.undopath[index] ) {
                    this.state.undopath[index].push( { x:this.state.old.x, y:this.state.old.y } );
                }else{
                    this.state.undopath[index] = [{
                        x:this.state.old.x,
                        y:this.state.old.y,
                        strokeStyle:this.ctx.strokeStyle,
                        lineWidth:this.ctx.lineWidth
                    }];
                }
            }
        }, {
            key:'onEnd',
            value:functiononEnd () {
                this.state.old = void 0;
                this.state.isStart =false;
            }
        }, {
            key:'pos',
            value:functionpos ( e ) {
                varx = 0,
                    y = 0;
                if( e.touches ) {
                    x = e.touches[0].pageX;
                    y = e.touches[0].pageY;
                }else{
                    x = e.offsetX / 2;
                    y = e.offsetY / 2;
                }
                return{ x: x, y: y };
            }
        }, {
            key:'ouput',
            value:functionouput () {
                // 输出图片
                returnthis.el.toDataURL();
            }
        }, {
            key:'init',
            value:functioninit () {
                // 绑定事件
                varisTouch =this.state.isTouch;
                this.el.addEventListener( isTouch ?'touchstart':'mousedown',this.onStart.bind(this),false);
                this.el.addEventListener( isTouch ?'touchmove':'mousemove',this.onMove.bind(this),false);
                this.el.addEventListener( isTouch ?'touchend':'mouseup',this.onEnd.bind(this),false);
                this.el.addEventListener( isTouch ?'touchcancel':'mouseout',this.onEnd.bind(this),false);
            }
        }, {
            key:'destroyed',
            value:functiondestroyed () {
                if(this.el ) {
                    varisTouch =this.state.isTouch;
                    this.el.removeEventListener( isTouch ?'touchstart':'mousedown',this.onStart.bind(this) );
                    this.el.removeEventListener( isTouch ?'touchmove':'mousemove',this.onMove.bind(this) );
                    this.el.removeEventListener( isTouch ?'touchend':'mouseup',this.onEnd.bind(this) );
                    this.el.removeEventListener( isTouch ?'touchcancel':'mouseout',this.onEnd.bind(this) );
                }
            }
        }, {
            key:'clear',
            value:functionclear () {
                // 清除画布
                this.state.index = -1;
                this.state.undopath = [];
                this.ctx.clearRect( 0, 0,this.el.width,this.el.height );
            }
        }, {
            key:'undo',
            value:functionundo () {
                // 撤销
                this.state.index >= 0 && --this.state.index;
                varundopath =this.state.undopath;
                this.state.undopath.pop();
                this.ctx.clearRect( 0, 0,this.el.width,this.el.height );
                if( undopath ) {
                    this.ctx.beginPath();
                    for(varz = 0; z < undopath.length; ++z ) {
                        this.ctx.moveTo( undopath[z][0].x, undopath[z][0].y );
                        this.ctx.lineWidth = undopath[z][0].lineWidth;
                        this.ctx.strokeStyle = undopath[z][0].strokeStyle;
                        for(vari = 0; i < undopath[z].length; ++i ) {
                            this.ctx.lineTo( undopath[z][i].x, undopath[z][i].y );
                        }
                    }
                    this.ctx.stroke();
                    this.ctx.closePath();
                }else{
                    this.state.undopath = [];
                }
            }
        }] );
        returnDraw;
    }();
    returnDraw;
} ) ) );

到此这篇关于HTML5 Canvas 实现在线签字功能的文章就介绍到这了,更多相关HTML5 Canvas在线签字内容请搜索脚本之家以前的文章或继续浏览下面的相关文章,希望大家以后多多支持脚本之家!

本站大部分文章、数据、图片均来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了您的权益请来信告知我们删除。邮箱:1451803763@qq.com