HTML5 Canvas 實(shí)現(xiàn)在線簽字功能(示例代碼)
前言
在現(xiàn)代互聯(lián)網(wǎng)應(yīng)用中,有時(shí)我們需要讓用戶在網(wǎng)頁上進(jìn)行簽字操作,比如確認(rèn)文件、填寫電子表格或者簽署合同。利用 HTML5 的 canvas 畫布,我們可以輕松地實(shí)現(xiàn)這一功能,為用戶提供方便快捷的在線簽字體驗(yàn)。
一、HTML5 Canvas 簡(jiǎn)介
HTML5 的 canvas 元素是一種強(qiáng)大的圖形渲染工具,它允許開發(fā)者使用 JavaScript 在網(wǎng)頁上繪制各種圖形、動(dòng)畫和交互式內(nèi)容。通過 canvas,開發(fā)者可以創(chuàng)建豐富多彩的視覺效果,并實(shí)現(xiàn)復(fù)雜的用戶交互體驗(yàn)。
HTML5 Canvas的關(guān)鍵特性:
圖形繪制能力:Canvas 元素提供了繪制路徑、矩形、圓形、直線、文本等基本圖形的功能,同時(shí)還支持圖像的繪制和變換操作,使得開發(fā)者能夠輕松地創(chuàng)建各種視覺效果。
動(dòng)畫和交互:借助 JavaScript,開發(fā)者可以在 Canvas 上創(chuàng)建復(fù)雜的動(dòng)畫效果,并添加交互式的操作。這使得 Canvas 成為開發(fā)游戲、數(shù)據(jù)可視化和其他需要?jiǎng)討B(tài)效果的應(yīng)用的理想選擇。
性能優(yōu)勢(shì):由于 Canvas 是基于 GPU 加速的,因此它具有良好的性能表現(xiàn),能夠處理大量的圖形元素和動(dòng)畫效果,而不會(huì)對(duì)頁面的整體性能產(chǎn)生太大影響。
靈活性:Canvas 元素可以輕松地與其他 HTML 元素結(jié)合使用,使得開發(fā)者可以在頁面上創(chuàng)建復(fù)雜的混合媒體效果,同時(shí)還可以響應(yīng)用戶的交互操作。
二、簽字功能的實(shí)現(xiàn)
效果演示

完整代碼
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 () {
// 點(diǎn)擊輸出圖片
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();
}
// 點(diǎn)擊清除
document.querySelector( '.clear' ).onclick = function () {
sign.clear();
}
// 點(diǎn)擊撤銷
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;
} ) ) );到此這篇關(guān)于HTML5 Canvas 實(shí)現(xiàn)在線簽字功能的文章就介紹到這了,更多相關(guān)HTML5 Canvas在線簽字內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持腳本之家!
相關(guān)文章

HTML5 Canvas 實(shí)現(xiàn)K線圖的示例代碼
這篇文章主要介紹了HTML5 Canvas 實(shí)現(xiàn)K線圖的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)2019-12-23
這篇文章主要介紹了HTML5模擬齒輪動(dòng)畫的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)2019-09-24
Html5 Canvas 實(shí)現(xiàn)一個(gè)“刮刮樂”游戲
這篇文章主要介紹了Html5 Canvas 實(shí)現(xiàn)一個(gè)“刮刮樂”游戲,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-09-05
html5 canvas繪制網(wǎng)絡(luò)字體的常用方法
這篇文章主要介紹了html5 canvas繪制網(wǎng)絡(luò)字體的常用方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-26
html5 canvas實(shí)現(xiàn)給圖片添加平鋪水印
這篇文章主要介紹了html5 canvas實(shí)現(xiàn)給圖片添加平鋪水印,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-20導(dǎo)出HTML5 Canvas圖片并上傳服務(wù)器功能
這篇文章主要介紹了導(dǎo)出HTML5 Canvas圖片并上傳服務(wù)器功能,文中通過實(shí)例代碼給大家介紹了HTML5 Canvas轉(zhuǎn)化成圖片后上傳服務(wù)器,代碼簡(jiǎn)單易懂非常不錯(cuò),具有一定的參考借鑒2019-08-16
基于Html5 canvas實(shí)現(xiàn)裁剪圖片和馬賽克功能及又拍云上傳圖片 功能
這篇文章主要介紹了基于Html5 canvas實(shí)現(xiàn)裁剪圖片和馬賽克功能及又拍云上傳圖片 功能,需要的朋友可以參考下2019-07-09







