图片.png图片.png

以前是使用小程序来处理手写签字的问题,后来发现每做一个系统都需要申请一个小程序,而且小程序的审核时间实在是跟网页没法比啊。所以就搜索了一下html页面实现手写签字的方法。记录一下,以后方便自己用。

网上流行的一个基于jquery 的js插件。叫 jSignature.js 感谢 github 其实看他的有点儿懵,而且文件也比较多。其实我用到的也就是只有 一个文件 jSignature.js 而已。下面是代码。不要眨眼睛 我的代码里面用到了layui 可以根据情况自己剔除;

<div class="layui-form-item">
    <label class="layui-form-label">店长签字:</label>
    <div class="layui-input-block">
        <a href="javascript:void(0);" class="layui-btn layui-btn-xs" onclick="openSign()">打开签字</a>
        <div id="signImg"><if condition="$order['sign_path']"><img src="{$order.sign_path|sp_get_image_url}" alt=""></if></div>
        <input type="hidden" name="sign_path" value="{$order.sign_path}">
    </div>
</div>
<div id="signdiv" style="display:none;">
    <div id="canvas"> </div>
</div>

这里只用到一个 #canvas 的div。其他的都是打酱油的。后面要用到。

<script>
    layui.use(["form",'layer'],function(){
        form = layui.form
        layer = layui.layer
    });
    function openSign(){
        layer.open({
            title:"店长签字",
            type:1,
            area:["100%","380px"],
            content:$('#signdiv'),
            success: function(layero, index){
                $("#canvas").jSignature({width:"100%",height:260,"decor-color": "transparent",lineWidth: '2'});
            },
            btn:['完成','重置'],
            yes:function(){
                savePic();
            },
            btn2:function(){
                resetCanvas();
                return false;
            }
        });
    }
    function savePic(){
        var $sigdiv = $("#canvas");
        var length = $sigdiv.jSignature('getData', 'native').length;
        //判断是否有签名
        if(length == 0){
            layer.msg('请先签名再提交',{icon:5});
            return;
        }
        var datapair = $sigdiv.jSignature("getData");
        $.ajax({
            url:"{:U('asset/asset/base64_upload')}",
            data:{base64:datapair,app:'sign'},
            dataType:"json",
            type:"POST",
            success:function(res){
                if(res.status == 1){
                    $('#signImg').html("<img src='"+res.preview_url+"'>");
                    $('input[name="sign_path"]').val(res.filepath);
                }
            }
        });
        layer.closeAll();
    }
    function resetCanvas(){
        var $sigdiv = $("#canvas");
        $sigdiv.jSignature("reset");
    }
</script>

JS部分写了三个方法 第一个openSign()是打开弹窗,让在弹窗里面签字,所以可以不用这么麻烦,我就说了那些多余的代码是打酱油的。真正的签字是第二个方法savePic() 这个方法就是将签字的生成图片然后异步上传到服务器,生成真是的网络地址。 resetCanvas() 就是没用的清除之前的签字重新签字的 用的时候看着办吧。因为savePic() 里面生成的签字图片是base64格式的 所以要写一个接受base64上传图片的后台方法。

public function base64_upload() {
        $base64 = I("post.base64");
        $app=I('post.app/s','');

        if(!$app){
            $app='default';
        }else{
            $app= strtolower($app);
        }

        $savepath= $app.'/'.date('Ymd').'/';
        $uploadpath = './'.C("UPLOADPATH").$savepath;
        if(!is_dir($uploadpath)){
            $flag = mkdir($uploadpath,0777,true);
        }

        $base64_image = str_replace(' ', '+', $base64);
        //post的数据里面,加号会被替换为空格,需要重新替换回来,如果不是post的数据,则注释掉这一行
        if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image, $result)){
            //匹配成功
            $image_name = uniqid().'.'.$result[2];
            $image_file = $savepath.$image_name;
            $file_path = $uploadpath.$image_name;
            //服务器文件存储路径
            if (file_put_contents($file_path, base64_decode(str_replace($result[1], '', $base64_image)))){
                $url=C("TMPL_PARSE_STRING.__UPLOAD__").$image_file;
                $this->ajaxReturn(array('preview_url'=>$url,'filepath'=>$image_file,'url'=>$url,'name'=>$image_name,'status'=>1,'message'=>'success'));
            }else{
                $this->ajaxReturn(array('name'=>'','status'=>0,'message'=>'error'));
                return false;
            }
        }else{
            $this->ajaxReturn(array('name'=>'','status'=>0,'message'=>'error2'));
            return false;
        }
    }
}

最主要的两段话

$base64_image = str_replace(' ', '+', $base64);
//post的数据里面,加号会被替换为空格,需要重新替换回来,如果不是post的数据,则注释掉这一行
file_put_contents($file_path, base64_decode(str_replace($result[1], '', $base64_image)));

然后就保存成图片了。