【问题标题】:Capture Signature using HTML5 and iPad使用 HTML5 和 iPad 捕获签名
【发布时间】:2011-03-07 00:06:45
【问题描述】:

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

【问题讨论】:

    标签: ipad html canvas svg


    【解决方案1】:

    带有一些 JavaScript 的画布元素会很好用。

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

    【讨论】:

    • 我很惊讶这个插件有多漂亮。
    • 太完美了!感谢分享!
    • 我发现这个插件真的很难用。所有的演示都非常具体且难以应用。绝对像其他签名板方法更好:stackoverflow.com/a/17200715/76672 几乎没有文档,我能够让它工作......
    【解决方案2】:

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

    【讨论】:

    • 我想知道如何绘制已保存的签名
    • 如何将签名保存为png文件或以其他方式显示签名?
    【解决方案3】:

    也许这方面最好的两种浏览器技术是 Canvas,以 Flash 作为备份。

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

    通过 jSignature (http://willowsystems.github.com/jSignature/),我们使用 Canvas 作为主要版本,并回退到用于 IE8 及更低版本的基于 Flash 的 Canvas 模拟器 (FlashCanvas)。我说对我们来说效果很好。

    【讨论】:

    • 这真的很好...我喜欢它的平滑效果。我见过的最好的。
    【解决方案4】:

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

    【讨论】:

    • 提前感谢,我见过的最好的 js 签名库。不知道为什么这个答案只有 3 票。 github.com/szimek/signature_pad
    • 我喜欢它不依赖其他 js 库以及它的外观。关于使用它的一个说明对我有帮助:在画​​布上添加一个边框,这样你就可以看到它是如何调整的。另请注意,对画布的 css 更改会做一些疯狂的事情,因此如果失控,只需在画布元素中指定高度和宽度。
    • 杰克,您认为自述文件中提供的文档中究竟缺少什么?我愿意接受如何改进它的建议。
    • 我很抱歉。我认为您的文档实际上是足够的。在我意识到这是多么容易使用之前,它似乎是有限的。我在一个表单中完全实现了它,存储在数据库中并在一小时内检索回页面。我想,我将它与使用起来更复杂的库进行比较,比如上面选择的答案。我以前没有使用过数据 URI,但它确实是一种处理数据存储的绝妙方法。所以,我只需要让自己适应这些,然后在数据库中存储和检索是如此……容易……哇。再次感谢!
    • @RonaldinhoLearnCoding 查看自述文件 - 有一个所有可能选项的列表。你要找的那个叫做“penColor”。
    【解决方案5】:

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

    【讨论】:

      【解决方案6】:

      已经列出的选项非常好,但这里还有一些我研究并遇到的关于这个主题的选项。

      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/

      祝你好运,签约愉快

      【讨论】:

        【解决方案7】:

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

        基本工作流程:

        1. 创建一个功能空白的svg 以包含签名
        2. 在容器svg 中保留一个path 元素
        3. 使用触摸事件(touchstarttouchmovetouchend)让用户使用触摸输入绘制签名
        4. 使用鼠标事件(mousedownmousemovemouseupmouseout)让用户使用鼠标输入来绘制签名
        5. 在每个事件中,检测输入类型(触摸、鼠标)以获取用户正在绘制的路径的 X、Y 坐标
        6. 将每个路径附加到path 元素的d 属性(路径坐标),以便向用户显示
        7. 添加一个辅助函数来输出签名路径(path.d),它只是一个string,您可以稍后插入path.d以恢复签名
        8. 添加帮助函数以清除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.widthrect.height
        • 容器背景:rect.fill
        • 消除“在此处签名”行:line

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-01-04
          • 2015-03-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-12-11
          • 2014-08-29
          相关资源
          最近更新 更多