it编程 > 网页制作 > html5

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

328人参与 2024-06-19 html5

前言

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

一、html5 canvas 简介

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

html5 canvas的关键特性:

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

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

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

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

二、签字功能的实现

效果演示

完整代码

html代码

<!doctype html>
<html class="no-js">
<head>
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0,user-scalable=no,viewport-fit=cover">
    <meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate" />
    <meta http-equiv="expires" content="wed, 26 feb 1997 08:21:57 gmt">
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache" content="no-cache">
    <meta http-equiv="expires" content="0">
    <meta charset="utf-8">
    <title>画图</title>
    <link rel="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>
    <script src="./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>
    <div class="buttons">
        <button type="button" class="btn btn-primary ouput">生成图片</button>
        <button type="button" class="btn btn-light undo">撤销</button>
        <button type="button" class="btn btn-light clear">清除画布</button>
    </div>
</body>
</html>

js代码

( function ( global, factory ) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
        typeof define === 'function' && define.amd ? define( factory ) :
            ( global = global || self, global.draw = factory() );
}( this, ( function () {
    'use strict';
    var classcallcheck = function ( instance, constructor ) {
        if ( !( instance instanceof constructor ) ) {
            throw new typeerror( "cannot call a class as a function" );
        }
    };
    var createclass = function () {
        function defineproperties ( target, props ) {
            for ( var i = 0; i < props.length; i++ ) {
                var descriptor = props[i];
                descriptor.enumerable = descriptor.enumerable || false;
                descriptor.configurable = true;
                if ( "value" in descriptor ) descriptor.writable = true;
                object.defineproperty( target, descriptor.key, descriptor );
            }
        }
        return function ( constructor, protoprops, staticprops ) {
            if ( protoprops ) defineproperties( constructor.prototype, protoprops );
            if ( staticprops ) defineproperties( constructor, staticprops );
            return constructor;
        };
    }();
    /**
     * 
     * @description  手写签字版
     */
    var draw = function () {
        function draw () {
            var params = 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' in window,
                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: function onstart () {
                ++this.state.index;
                this.state.isstart = true;
            }
        }, {
            key: 'onmove',
            value: function onmove ( e ) {
                e.preventdefault();
                if ( !this.state.isstart ) return;
                var pos = this.pos( e );
                var index = 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: function onend () {
                this.state.old = void 0;
                this.state.isstart = false;
            }
        }, {
            key: 'pos',
            value: function pos ( e ) {
                var x = 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: function ouput () {
                // 输出图片
                return this.el.todataurl();
            }
        }, {
            key: 'init',
            value: function init () {
                // 绑定事件
                var istouch = 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: function destroyed () {
                if ( this.el ) {
                    var istouch = 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: function clear () {
                // 清除画布
                this.state.index = -1;
                this.state.undopath = [];
                this.ctx.clearrect( 0, 0, this.el.width, this.el.height );
            }
        }, {
            key: 'undo',
            value: function undo () {
                // 撤销
                this.state.index >= 0 && --this.state.index;
                var undopath = this.state.undopath;
                this.state.undopath.pop();
                this.ctx.clearrect( 0, 0, this.el.width, this.el.height );
                if ( undopath ) {
                    this.ctx.beginpath();
                    for ( var z = 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 ( var i = 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 = [];
                }
            }
        }] );
        return draw;
    }();
    return draw;
} ) ) );

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

(0)
打赏 微信扫一扫 微信扫一扫

您想发表意见!!点此发布评论

推荐阅读

window.open()各参数示例详解

06-19

uniapp在h5页面实现扫码功能(html5-qrcode)

06-11

html5 video 标签 controlslist详细使用

05-15

HTML5 服务器发送事件(Server-Sent Events)使用详解

05-15

HTML5兼容HEVC视频格式且支持本地绝对路径访问的操作方法

05-15

关于document.body.clientHeight返回值为0的完美解决方案

05-16

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论