【发布时间】:2011-03-07 00:06:45
【问题描述】:
任何人都知道如何做到这一点?你会使用画布对象、svg、jQuery 等吗?
【问题讨论】:
任何人都知道如何做到这一点?你会使用画布对象、svg、jQuery 等吗?
【问题讨论】:
带有一些 JavaScript 的画布元素会很好用。
事实上,Signature Pad(一个 jQuery 插件)已经实现了这个。
【讨论】:
这里是a quickly hacked up version of this using SVG 我刚刚做了。在我的 iPhone 上非常适合我。也适用于使用普通鼠标事件的桌面浏览器。
【讨论】:
也许这方面最好的两种浏览器技术是 Canvas,以 Flash 作为备份。
我们尝试在 IE 上使用 VML 作为 Canvas 的备份,但它比 Flash 慢得多。 SVG 比其他的都慢。
通过 jSignature (http://willowsystems.github.com/jSignature/),我们使用 Canvas 作为主要版本,并回退到用于 IE8 及更低版本的基于 Flash 的 Canvas 模拟器 (FlashCanvas)。我说对我们来说效果很好。
【讨论】:
这是另一个基于画布的版本,具有可变宽度(基于绘制速度)曲线:http://szimek.github.io/signature_pad 的演示和https://github.com/szimek/signature_pad 的代码。
【讨论】:
另一个开源签名字段是 https://github.com/applicius/jquery.signfield/ ,使用 Sketch.js 注册的 jQuery 插件。
【讨论】:
已经列出的选项非常好,但这里还有一些我研究并遇到的关于这个主题的选项。
1) http://perfectionkills.com/exploring-canvas-drawing-techniques/
2) http://mcc.id.au/2010/signature.html
3) https://zipso.net/a-simple-touchscreen-sketchpad-using-javascript-and-html5/
和往常一样,您可能希望将画布保存到图像:
http://www.html5canvastutorials.com/advanced/html5-canvas-save-drawing-as-an-image/
祝你好运,签约愉快
【讨论】:
@szimek(选择的答案)为那些想要一个功能齐全的模块和一个很好用的 MIT 许可证的人提供了一个有据可查的解决方案。 @heycam 有一个更简单的解决方案,不需要库或插件,没有许可证,并且可以轻松定制;所有这些使它更适合我的需求。这篇文章试图解释他的解决方案是如何工作的。
基本工作流程:
svg 以包含签名svg 中保留一个path 元素
touchstart、touchmove、touchend)让用户使用触摸输入绘制签名mousedown、mousemove、mouseup、mouseout)让用户使用鼠标输入来绘制签名path 元素的d 属性(路径坐标),以便向用户显示path.d),它只是一个string,您可以稍后插入path.d以恢复签名path.d 值这是@heycam 作为可运行 sn-p 的解决方案:
//init
let r = document.getElementById('r'),
p = document.getElementById('p'),
signaturePath = '',
isDown = false,
svg = document.getElementById('sig_panel'),
b_show = document.getElementById('show'),
b_clear = document.getElementById('clear'),
pathdata = document.getElementById('pathdata');
//drawing functions
function isTouchEvent(e) {
return e.type.match(/^touch/);
}
function getCoords(e) {
if (isTouchEvent(e)) {
return e.targetTouches[0].clientX + ',' + e.targetTouches[0].clientY;
}
return e.clientX + ',' + e.clientY;
}
function down(e) {
signaturePath += 'M' + getCoords(e) + ' ';
p.setAttribute('d', signaturePath);
isDown = true;
if (isTouchEvent(e)) e.preventDefault();
}
function move(e) {
if (isDown) {
signaturePath += 'L' + getCoords(e) + ' ';
p.setAttribute('d', signaturePath);
}
if (isTouchEvent(e)) e.preventDefault();
}
function up(e) {
isDown = false;
if (isTouchEvent(e)) e.preventDefault();
}
//input handlers
r.addEventListener('touchstart', down, false);
r.addEventListener('touchmove', move, false);
r.addEventListener('touchend', up, false);
r.addEventListener('mousedown', down, false);
r.addEventListener('mousemove', move, false);
r.addEventListener('mouseup', up, false);
r.addEventListener('mouseout', up, false);
//helper functions
function clearSignature() {
pathdata.textContent = '';
signaturePath = '';
p.setAttribute('d', '');
}
function getSignature() {
pathdata.textContent = signaturePath;
return signaturePath;
}
//button handlers
b_show.addEventListener('click', getSignature);
b_clear.addEventListener('click', clearSignature);
svg {
margin: .5em;
border: 1px solid gray;
border-radius: .5em;
}
.flex {
display: flex;
}
button {
margin: .5em;
}
#pathdata {
font-family: monospace;
background: #ddd;
padding: 1em;
margin: 1em .5em;
}
<svg id="sig_panel" xmlns="http://www.w3.org/2000/svg" width="300" height="100" viewBox="0 0 300 100">
<rect id="r" width="300" height="100" fill="#ffa"/>
<line x1="0" y1="80" x2="300" y2="80" stroke="#666" stroke-width="1" stroke-dasharray="3" shape-rendering="crispEdges" pointer-events="none"/>
<path id="p" stroke="navy" stroke-width="2" fill="none" pointer-events="none"/>
</svg>
<div class="flex">
<button id="show">Show signaure path data</button>
<button id="clear">Clear signature</button>
</div>
<div id="pathdata"></div>
我只需要在服务器(和客户端缓存)上保存 path.d 值。其他人可能需要保存整个 svg 本身并填写 path.d,或使用适当的转换器(此处未介绍)将其转换为其他格式(JPEG、PNG、PDF)。
我计划更进一步,添加用户控件来管理以下内容:
path.stroke-width
path.stroke
path.shape-rendering
并将签名字段作为主题(作为我的自定义表单库的一部分):
rect.width,rect.height
rect.fill
line
【讨论】: