广告位联系
返回顶部
分享到

HTML5 Canvas实现在线签字功能的介绍

html5 来源:互联网 作者:佚名 发布时间:2024-06-20 21:36:35 人浏览
摘要

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

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

一、HTML5 Canvas 简介

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

HTML5 Canvas的关键特性:

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

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

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

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

二、签字功能的实现

效果演示

完整代码

HTML代码

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

<!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代码

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

( 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;

} ) ) );


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计