使用HTML5和iPad捕获签名

时间:2010-06-22 19:34:45

标签: ipad html5 canvas svg

任何人都知道如何做到这一点?你会使用canvas对象,svg,jQuery等吗?

7 个答案:

答案 0 :(得分:289)

这是另一个基于画布的版本,具有可变宽度(基于绘制速度)曲线:http://szimek.github.io/signature_pad处的演示和https://github.com/szimek/signature_pad处的代码。

signature sample

答案 1 :(得分:58)

带有一些JavaScript的canvas元素可以很好用。

事实上,Signature Pad(一个jQuery插件)已经实现了这一点。

答案 2 :(得分:15)

我刚刚做过a quickly hacked up version of this using SVG。在我的iPhone上适合我。也适用于使用普通鼠标事件的桌面浏览器。

答案 3 :(得分:12)

也许最好的两个浏览器技术是Canvas,Flash作为备份。

我们尝试在IE上使用VML作为Canvas的备份,但它比Flash慢得多。 SVG比其他所有人都慢。

使用jSignature(http://willowsystems.github.com/jSignature/)我们使用Canvas作为主要内容,并使用基于Flash的Canvas模拟器(FlashCanvas)回退IE8。我说'对我们说得很好。

答案 4 :(得分:1)

已经列出的选项非常好,但是我已经研究过并且遇到过这个主题的更多内容。

    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/

祝你好运,签字快乐

答案 5 :(得分:1)

@szimek(选择的答案)为那些想要一个带有 MIT 许可证的全功能模块的人提供了一个有据可查的解决方案。 @heycam 有一个更简单的解决方案,不需要库或插件,没有许可证,并且可以轻松定制;所有这些都使它更适合我的需求。这篇文章试图解释他的解决方案究竟是如何工作的。

基本工作流程:

  1. 创建一个功能空白的 svg 以包含签名
  2. 在容器内保留一个 path 元素 svg
  3. 使用触摸事件(touchstarttouchmovetouchend)让用户使用触摸输入绘制签名
  4. 使用鼠标事件(mousedownmousemovemouseupmouseout)让用户使用鼠标输入绘制签名
  5. 在每个事件中,检测输入类型(触摸、鼠标)以获取用户正在绘制的路径的 X、Y 坐标
  6. 将每个路径附加到 d 元素的 path 属性(路径坐标),以便向用户显示
  7. 添加一个辅助函数来输出签名路径 (path.d),它只是一个 string,您可以稍后重新插入 path.d 以恢复签名
  8. 添加一个辅助函数来清除 path.d

这是@heycam 的解决方案,作为可运行的代码段:

//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.widthrect.height
  • 容器背景:rect.fill
  • 消除“在此处签名”行:line

答案 6 :(得分:0)

另一个OpenSource签名字段是https://github.com/applicius/jquery.signfield/,使用Sketch.js注册了jQuery插件。