因项目功能需要,最近几天开始研究html5,实现对上传的试题图片进行批改对错,批改完保存批改后的图片功能。主要涉及到html5 canvas画布和js的相关知识点。
参考:http://www.xwcms.net/js/qttx/26316.html 作者写的功能,修改后能保存盖章后的图片。

(图片略丑,不要嫌弃)
效果图:

点击保存后在下面显示的效果图:

页面代码:

<!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><div id="test" style="position: relative; width: 80%; height: 500px; border: 1px solid red;  margin: 100px auto"><img src="img/shiti.png" /></div><div id="imgBox" style="width:1000px;height:800px;">  </div>  <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 = $("<div class='panel' ><button class='btn add' >对</button><button class='btn wrong' >错</button><button class='btn save'>保 存</button></div>").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("<div class='sign ok' style='height:" + _s.height + "px;width:" + _s.width + "px;background-image:" + item.img + ";top:" + item.top + ";left:" + item.left + "'></div>");  }  },  //添加签章  add: function () {  handle.btnAddToggle();  var sign = $("<div 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></div>").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 = $("<div 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></div>").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;
}  

html5实现对试题图片批改效果,类似盖章效果相关推荐

  1. html实现图片加载动画效果,HTML5+javascript实现图片加载进度动画效果

    在网上找资料的时候,看到网上有图片加载进度的效果,手痒就自己也写了一个. 图片加载完后,隐藏loading效果. 想看加载效果,请ctrel+F5强制刷新或者清理缓存. 效果预览: 0% 代码如下: ...

  2. Android开发-优雅的实现动态图片排版(类似微信图片展示效果)

    介绍 效果展示 说明 上面的图片排版 - 实现了动态布局,针对不同图片的数量展示不同的排版布局.效果类似微信朋友圈的图片排版,效果略有不同. - 正方形的图片控件,高度会随着宽度一起变化. 实现这样的 ...

  3. js怎么在一个div中嵌入另一网站_好程序员web前端学习路线分享HTML5常见面试题集锦一...

    好程序员web前端学习路线分享HTML5常见面试题集锦,接下来将会持续为大家分享几篇HTML5常见面试题. 1.布局 左边20% 中间自适应 右边200px 不能用定位 答案:圣杯布局/双飞翼布局或者 ...

  4. 前端 input怎么显示null_小猿圈WEB前端之HTML5+CSS3面试题(一)

    学习是一件非常充实的过程,特别是把自己的乐趣变成工作的时候,很多朋友就喜欢学习web前端,所以学习前端,也希望从事前端的工作,但是因为缺少实战经验,所以很多都是卡在面试这关上,下面小猿圈总结了web前 ...

  5. 小猿圈WEB前端之HTML5+CSS3面试题(一)

    越来越多人喜欢前端岗位,毕业季已经悄然来临,很多毕业生面临找工作,那你们在狂欢快乐最后恋恋不舍之际,是否想着过几天招工作的危机.如果想要毕业之后,走向前端的岗位,那看到小编的文章后好好做一下这套题,今 ...

  6. 图片(旋转/缩放/翻转)变换效果(ccs3/滤镜/canvas)

    以前要实现图片的旋转或翻转,只能用ie的滤镜来实现,虽然canvas也实现,但ie不支持而且不是html标准. css3出来后,终于可以用标准的transform来实现变换,而canvas也已成为ht ...

  7. 分享一个非常有用的HTML5+CSS3响应式图片案例

    随着Retina屏幕的逐渐普及,网页中对图片的适配要求也越来越高.如何让图片在放大了两倍的 Retina 屏幕显示依然清晰,曾经一度困扰着网页开发者,好在 CSS3 与 HTML5 已经着力在改变这种 ...

  8. html5作品源码,码农网:12个效果奇特的HTML5动画赏析 | 附:源码演示

    本文由码农网 – 小峰原创,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划! 本文将为大家分享12个效果奇特的HTML5动画,HTML5强大的动画特性可以让你的网页变得更加生动和富有活力,交互性 ...

  9. html5退出全屏触发的方法_好程序员web前端分享HTML5常见面试题集锦二

    web前端分享HTML5常见面试题集锦第二篇,希望对大家有所帮助. 1. 方法1: html,body{height: 100%;} body{ margin: 0;display: flex; ju ...

  10. [css] 使用css将图片转换成黑白的效果

    [css] 使用css将图片转换成黑白的效果 filter: saturate(0); 个人简介 我是歌谣,欢迎和大家一起交流前后端知识.放弃很容易, 但坚持一定很酷.欢迎大家一起讨论 主目录 与歌谣 ...

最新文章

  1. 深入理解BP神经网络的细节
  2. mysql 技术交流群_二进制部署MySQL(运维技术交流群:926402931,欢迎大家一起来交流。)...
  3. oracle11g安装成功
  4. 产品经理懂技术=流氓会武术(zz)
  5. php下载当前页面,php实现当前页面点击下载文件的简单方法
  6. 计算机会考补考时间安排,2019-2020学年第二学期初补考考试安排(实时更新)
  7. Hoodie旨在成为开源最多样化和包容性社区之一
  8. java 枚举 大小_Java枚举入门
  9. 基于JAVA+Servlet+JSP+MYSQL的毕业生离校管理系统
  10. VS2005最近项目和最近文件清除
  11. Linux下安装并启动MongoDB
  12. 关于PCBLayout的一些具体细节的认识(能力有限,请大家多多指点)
  13. Cadence PSpice 仿真1: 三极管传输特性曲线直流仿真图文教程
  14. koa教程--busboy模块
  15. Tomcat SSL配置 Connector attribute SSLCertificateFile must be defined when using SSL with APR解决 作者:孤风一
  16. 手机序列号和IMEI号的区别
  17. 猕猴桃的红色果肉受到特定的激活-抑制系统的控制
  18. 【注意力机制集锦2】BAMSGEDAN原文、结构、源码详解
  19. java实现电子签名技术_h5实现电子签名
  20. pixi的使用之创建和操作精灵

热门文章

  1. Matlab imfilter函数
  2. 事实表 的指标 维度表_事实表和维度表 | Power BI星球
  3. 电厂计算机监控系统的结构及功能,水电厂计算机监控系统
  4. 清北复交人浙南 计算机交叉学科项目大盘点!
  5. win7剪切板_Win7系统打开剪切板windows找不到clipbrd.exe文件如何解决?
  6. 机械设计二级减速器设计
  7. usb芯片+android+驱动,PL2303芯片驱动
  8. ubuntu显卡测试软件,Linux显卡性能测试程序Unigine Valley 和 Unigine Heaven
  9. 怎样用计算机粉碎文件夹,文件无法删除也无法粉碎怎么解决(电脑系统文件夹无法删除的常见解决方法)...
  10. 使用python开发的GUI可视化界面植物名录查询系统,使用python读取xls文件,读取xlsx文件。tkinter使用