核心提示: 因项目功能需要,最近几天开始研究html5,实现对上传的试题图片进行批改对错,批改完保存批改后的图片功能。主要涉及到html5 canvas画布和js的相关知识点。页面代码:!DOCTYPE htm...
因项目功能需要,最近几天开始研究html5,实现对上传的试题图片进行批改对错,批改完保存批改后的图片功能。主要涉及到html5 canvas画布和js的相关知识点。
页面代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>测试</title> <link href="css/zsign.css" rel="stylesheet" type="text/css" /> <script src="js/jquery-2.2.1.min.js" type="text/javascript"></script> <script src="js/zsign.js" type="text/javascript"></script> </head> <body> <p id="test" style="position: relative; width: 80%; height: 500px; border: 1px solid red; margin: 100px auto"> <img src="img/shiti.png" /> </p> <p id="imgBox" style="width:1000px;height:800px;"> </p> <ul id="msg"></ul> <script> var data = []; //吧试题图片和批改图片存储 var a = $("#test").zSign({ img: 'img/true.png', wrongImg: 'img/false.png', isPercentage: true, callBack: function(obj) { var dataobj2={}; dataobj2["img"] = "img/shiti.png"; dataobj2["top"] = 0; dataobj2["left"] = 0; data.push(dataobj2); //存储批改的图片及位置 var html = []; for (var i = 0; i < obj.length; i++) { html.push('<li>img:"' + obj[i].img + '", top:"' + obj[i].top + '", left:"' + obj[i].left + '"</li>'); var imgurl = obj[i].img.match(/\([^\)]+\)/g)[0]; imgurl = imgurl.substring(2, imgurl.length - 2); var left = obj[i].left.substring(0, obj[i].left.length - 2); var top = obj[i].top.substring(0, obj[i].top.length - 2); var dataobj={}; dataobj["img"] = imgurl; dataobj["top"] = parseFloat(top); dataobj["left"] = parseFloat(left); data.push(dataobj); } showImg(); $('#msg').html(html.join('')); } }); //合成最后的批改图片 function showImg(){ var base64=[]; var Mycanvas=document.createElement("canvas"), ct=Mycanvas.getContext("2d"), len=data.length; Mycanvas.width=600; Mycanvas.height=400; ct.rect(0,0,Mycanvas.width,Mycanvas.height); ct.fillStyle='#fff'; ct.fill(); function draw(n){ if(n<len){ var img=new Image; img.crossOrigin = 'Anonymous'; //解决跨域 img.src=data[n].img; img.onload=function(){ ct.drawImage(img,data[n].left,data[n].top); draw(n+1); } } else{ base64.push(Mycanvas.toDataURL("image/png")); document.getElementById("imgBox").innerHTML='<img src="'+base64[0]+'">'; saveAsLocalImage (Mycanvas); } } draw(0) } //吧图片下载本地 function saveAsLocalImage (canvas) { var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); window.location.href=image; } </script> </body> </html>
2、其中需要编写的css样式文件:
.zsign .panel { position: absolute; top:20px; right:50px; } .zsign .btn { display: inline-block; padding: 4px 10px 4px; margin-bottom: 0; font-size: 15px; line-height: 18px; color: #333; text-align: center; text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); vertical-align: middle; background-color: whiteSmoke; background-image: -webkit-gradient(linear, 0 0, 0 100%, from(white), to(#E6E6E6)); background-repeat: repeat-x; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); border: 1px solid #CCC; border-bottom-color: #B3B3B3; -webkit-border-radius: 4px; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); cursor: pointer; -webkit-user-select: none; } .zsign .btn:hover { color: #333; text-decoration: none; background-color: #E6E6E6; background-position: 0 -15px; -webkit-transition: background-position 0.1s linear; } .zsign .btn[disabled] { cursor: default; background-image: none; background-color: #E6E6E6; opacity: 0.65; filter: alpha(opacity=65); -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; } .zsign .btn.add { margin-right:8px; } .zsign .btn.wrong { margin-right:8px; } .zsign .cursor { cursor: none; } .zsign .show { display: block; } .zsign .hide { display: none; } .zsign .sign { position: absolute; top:20px; left:20px; cursor: move; border: 1px dashed #ccc; background-size: contain; background-position: center; background-repeat: no-repeat; } .zsign .sign.ok { cursor: default; border-color:transparent; } .zsign .sign .btn { padding: 2px 6px; font-size: 11px; line-height: 14px; position: absolute; } .zsign .sign .btn.del { bottom: 4px; right: 4px; } .zsign .sign .btn.ok { bottom: 4px; right: 50px; }
3、对对号和错号图片的移动、保存按钮的返回等功能js的编写
$.fn.zSign = function (options) { var _s = $.extend({ img: '', //图片地址 wrongImg:'', width: 100, //签章图片大小 height: 100, btnPanel: true, //是否开启按钮面板,若按钮面板不满足需求可以关闭后通过返回的handle对象直接调用方法 callBack: null, //保存按钮回调函数 list: null, //初始化签章,参数格式参照callBack回调函数返回的数据格式 isPercentage: false //返回结果中的left、top是否以百分比显示,若夫容器是自适应布局推荐 }, options || {}); var _parent = $(this).addClass('zsign'), _pw = _parent.width(), _ph = _parent.height(); var range = { minX: 8, minY: 8, maxX: _pw - _s.width - 2, //扣去2个边框1px maxY: _ph - _s.height - 2 }; //按钮面板 var _btnPanel = $("<p class='panel' ><button class='btn add' >对</button><button class='btn wrong' >错</button><button class='btn save'>保 存</button></p>").appendTo(_parent); _btnPanel.css('display', _s.btnPanel ? 'block' : 'none'); //添加 var _add = $('.add', _btnPanel).click(function (e) { handle.add(); }); //批错 var _wrong= $('.wrong', _btnPanel).click(function (e) { handle.wrong(); }); //保存 $('.save', _btnPanel).click(function () { handle.save(); }); if (_s.list) { handle.init(_s.list); } var handle = { list: [], //初始化签章 init: function (list) { handle.list = []; $('.sign', _parent).remove(); for (var i = 0; i < list.length; i++) { var item = list[i]; _parent.append("<p class='sign ok' style='height:" + _s.height + "px;width:" + _s.width + "px;background-image:" + item.img + ";top:" + item.top + ";left:" + item.left + "'></p>"); } }, //添加签章 add: function () { handle.btnAddToggle(); var sign = $("<p class='sign' style='height:" + _s.height + "px;width:" + _s.width + "px;background-image:url(" + _s.img + ");'><button class='btn ok' >确定</button><button class='btn del' >删除</button></p>").appendTo(_parent); $('.ok', sign).click(function () { //确定 handle.sign(sign); }); $('.del', sign).click(function () { //删除 handle.del(sign); }); handle.move(sign); }, //添加错号 wrong: function () { handle.btnAddToggle(); var sign = $("<p class='sign' style='height:" + _s.height + "px;width:" + _s.width + "px;background-image:url(" + _s.wrongImg + ");'><button class='btn ok' >确定</button><button class='btn del' >删除</button></p>").appendTo(_parent); $('.ok', sign).click(function () { handle.sign(sign); }); $('.del', sign).click(function () { handle.del(sign); }); handle.move(sign); }, //确定 sign: function (obj) { obj.addClass('ok').off('mousedown').find('.btn').css('display', 'none'); handle.btnAddToggle(); handle.list.push({ img: obj.css('background-image') + "", top: obj.css('top'), left: obj.css('left')}); }, //删除 del: function (obj) { obj.remove(); handle.btnAddToggle(); }, //移动 move: function (obj) { //绑定移动事件 obj.on('mousedown', function (e) { obj.data('x', e.clientX); obj.data('y', e.clientY); var position = obj.position(); $(document).on('mousemove', function (e1) { var x = e1.clientX - obj.data('x') + position.left; var y = e1.clientY - obj.data('y') + position.top; x = x < range.minX ? range.minX : x; x = x > range.maxX ? range.maxX : x; y = y < range.minY ? range.minY : y; y = y > range.maxY ? range.maxY : y; obj.css({ left: x, top: y }); }).on('mouseup', function () { $(this).off('mousemove').off('mouseup'); }); }); }, //保存 save: function () { var r = true; if ($('.sign:not(.ok)', _parent).length != 0) { if (!confirm("未点击确认的签章将被移除,确定保存吗?")) { r = false; } } if (r) { //删除未确定位置的签章 $('.sign:not(.ok)', _parent).remove(); _btnPanel.remove(); if (_s.callBack) { if (_s.isPercentage) { for (var i = 0; i < handle.list.length; i++) { var item = handle.list[i]; /*item.top = parseInt(item.top) / _ph * 100 + '%'; item.left = parseInt(item.left) / _pw * 100 + '%'; */ } } else { tmp = handle.list; } _s.callBack.call(this, handle.list); } } }, //盖章按钮的状态切换 btnAddToggle: function () { var disabled = _add.attr('disabled'); if (disabled) { //判断是否有未确定的签章,若有则不切换 if ($('.sign:not(.ok)', _parent).length == 0) { _add.removeAttr('disabled'); } } else { _add.attr('disabled', 'disabled'); } }, //返回参数列表,可以在外部直接修改 s: _s, //签章移动范围 range: range } return handle; }