root преди 2 години
родител
ревизия
4f92a0eb95
променени са 94 файла, в които са добавени 3457 реда и са изтрити 0 реда
  1. 3 0
      drawingboard-master/.gitattributes
  2. 2 0
      drawingboard-master/.gitignore
  3. 49 0
      drawingboard-master/README.md
  4. 215 0
      drawingboard-master/drawingboard/check-bak.html
  5. 487 0
      drawingboard-master/drawingboard/check.html
  6. 66 0
      drawingboard-master/drawingboard/css/api.css
  7. 320 0
      drawingboard-master/drawingboard/css/check.css
  8. 332 0
      drawingboard-master/drawingboard/css/index.css
  9. 296 0
      drawingboard-master/drawingboard/css/style.css
  10. 125 0
      drawingboard-master/drawingboard/css/swiper.css
  11. 48 0
      drawingboard-master/drawingboard/demo/loadimg.html
  12. 121 0
      drawingboard-master/drawingboard/demo/writingpad.html
  13. 70 0
      drawingboard-master/drawingboard/doc.html
  14. BIN
      drawingboard-master/drawingboard/favicon.ico
  15. BIN
      drawingboard-master/drawingboard/image/canvas_bg.jpg
  16. BIN
      drawingboard-master/drawingboard/image/check/all-true.png
  17. BIN
      drawingboard-master/drawingboard/image/check/all-wrong.png
  18. BIN
      drawingboard-master/drawingboard/image/check/app-logo.png
  19. BIN
      drawingboard-master/drawingboard/image/check/arrow-left.png
  20. BIN
      drawingboard-master/drawingboard/image/check/arrow-right.png
  21. BIN
      drawingboard-master/drawingboard/image/check/cancel-icon.png
  22. BIN
      drawingboard-master/drawingboard/image/check/change-icon.png
  23. BIN
      drawingboard-master/drawingboard/image/check/classroom-not-full.png
  24. BIN
      drawingboard-master/drawingboard/image/check/close-icon.png
  25. BIN
      drawingboard-master/drawingboard/image/check/confirm-icon.png
  26. BIN
      drawingboard-master/drawingboard/image/check/correct-details-bg.png
  27. BIN
      drawingboard-master/drawingboard/image/check/default-head-blue.png
  28. BIN
      drawingboard-master/drawingboard/image/check/default-head-gray.png
  29. BIN
      drawingboard-master/drawingboard/image/check/delete-icon.png
  30. BIN
      drawingboard-master/drawingboard/image/check/enlarge-icon.png
  31. BIN
      drawingboard-master/drawingboard/image/check/erasure-icon.png
  32. BIN
      drawingboard-master/drawingboard/image/check/error-icon.png
  33. BIN
      drawingboard-master/drawingboard/image/check/error-tag.png
  34. BIN
      drawingboard-master/drawingboard/image/check/help-icon.png
  35. BIN
      drawingboard-master/drawingboard/image/check/homework-answer-icon.png
  36. BIN
      drawingboard-master/drawingboard/image/check/homework-correct-icon.png
  37. BIN
      drawingboard-master/drawingboard/image/check/homework-entry-icon.png
  38. BIN
      drawingboard-master/drawingboard/image/check/homework-inspect-icon.png
  39. BIN
      drawingboard-master/drawingboard/image/check/homework-review-icon.png
  40. BIN
      drawingboard-master/drawingboard/image/check/label-icon.png
  41. BIN
      drawingboard-master/drawingboard/image/check/loading_more.gif
  42. BIN
      drawingboard-master/drawingboard/image/check/logo.png
  43. BIN
      drawingboard-master/drawingboard/image/check/modify-password-icon.png
  44. BIN
      drawingboard-master/drawingboard/image/check/pop-icon.png
  45. BIN
      drawingboard-master/drawingboard/image/check/pwd0.png
  46. BIN
      drawingboard-master/drawingboard/image/check/pwd1.png
  47. BIN
      drawingboard-master/drawingboard/image/check/right-tag.png
  48. BIN
      drawingboard-master/drawingboard/image/check/select-icon.png
  49. BIN
      drawingboard-master/drawingboard/image/check/sign-out-icon.png
  50. BIN
      drawingboard-master/drawingboard/image/check/test1.jpg
  51. BIN
      drawingboard-master/drawingboard/image/check/test2.jpg
  52. BIN
      drawingboard-master/drawingboard/image/check/test3.jpg
  53. BIN
      drawingboard-master/drawingboard/image/check/test4.jpg
  54. BIN
      drawingboard-master/drawingboard/image/check/test5.jpg
  55. BIN
      drawingboard-master/drawingboard/image/check/true-icon.png
  56. BIN
      drawingboard-master/drawingboard/image/check/user-info-icon.png
  57. BIN
      drawingboard-master/drawingboard/image/check/user0.png
  58. BIN
      drawingboard-master/drawingboard/image/check/user1.png
  59. BIN
      drawingboard-master/drawingboard/image/check/work-original.jpg
  60. BIN
      drawingboard-master/drawingboard/image/check/work-total-icon.png
  61. BIN
      drawingboard-master/drawingboard/image/check/work.png
  62. BIN
      drawingboard-master/drawingboard/image/check/wrong-icon.png
  63. BIN
      drawingboard-master/drawingboard/image/check/开始批改-效果图.png
  64. BIN
      drawingboard-master/drawingboard/image/demoPreview.gif
  65. BIN
      drawingboard-master/drawingboard/image/right-sel.png
  66. BIN
      drawingboard-master/drawingboard/image/right-small-sel.png
  67. BIN
      drawingboard-master/drawingboard/image/right-small.png
  68. BIN
      drawingboard-master/drawingboard/image/right.png
  69. BIN
      drawingboard-master/drawingboard/image/submit-sel.png
  70. BIN
      drawingboard-master/drawingboard/image/submit.png
  71. BIN
      drawingboard-master/drawingboard/image/tools-28.png
  72. BIN
      drawingboard-master/drawingboard/image/wrong-sel.png
  73. BIN
      drawingboard-master/drawingboard/image/wrong-small-sel.png
  74. BIN
      drawingboard-master/drawingboard/image/wrong-small.png
  75. BIN
      drawingboard-master/drawingboard/image/wrong.png
  76. 68 0
      drawingboard-master/drawingboard/index.html
  77. 47 0
      drawingboard-master/drawingboard/js/canvasZoom.js
  78. 305 0
      drawingboard-master/drawingboard/js/check-bak.js
  79. 269 0
      drawingboard-master/drawingboard/js/check/canvas.js
  80. 9 0
      drawingboard-master/drawingboard/js/check/config.js
  81. 17 0
      drawingboard-master/drawingboard/js/check/fontsize.js
  82. 0 0
      drawingboard-master/drawingboard/js/check/qiniu.min.js
  83. 287 0
      drawingboard-master/drawingboard/js/demo.js
  84. 0 0
      drawingboard-master/drawingboard/js/fabric.min.js
  85. 1 0
      drawingboard-master/drawingboard/js/jquery.min.js
  86. 0 0
      drawingboard-master/drawingboard/js/tools/md5.min.js
  87. 109 0
      drawingboard-master/drawingboard/js/tools/upload.js
  88. 5 0
      drawingboard-master/drawingboard/js/tools/uuid.js
  89. 29 0
      drawingboard-master/drawingboard/test.html
  90. 134 0
      drawingboard-master/fabricjs使用笔记.md
  91. BIN
      drawingboard-master/res/check.png
  92. 11 0
      drawingboard-master/res/作业批改传入参数.txt
  93. BIN
      drawingboard-master/res/作业批改数据传输-参数说明.docx
  94. 32 0
      drawingboard-master/res/作业批改数据传输.json

+ 3 - 0
drawingboard-master/.gitattributes

@@ -0,0 +1,3 @@
+*.js linguist-language=JavaScript
+*.css linguist-language=JavaScript
+*.html linguist-language=JavaScript

+ 2 - 0
drawingboard-master/.gitignore

@@ -0,0 +1,2 @@
+/drawingboard/web.config
+/drawingboard/proxy.html

+ 49 - 0
drawingboard-master/README.md

@@ -0,0 +1,49 @@
+## 简介 ##
+基于canvas的高级画板程序.
+
+## 在线演示 ##
+
+高级画板:https://vipstone.github.io/drawingboard/drawingboard/index.html
+
+作业批改:https://vipstone.github.io/drawingboard/drawingboard/check.html
+
+## 功能 ##
+- 全局绘制颜色选择<br />
+- 护眼模式、网格模式切换<br />
+- 自由绘制<br />
+- 画箭头<br />
+- 画直线<br />
+- 画虚线<br />
+- 画圆/椭圆/矩形/直角三角形/普通三角形/等边三角形<br />
+- 文字输入<br />
+- 图片展示及相关移动、缩放等操作<br />
+- 删除功能<br />
+- 支持画板同比缩放
+- 支持图形即时显示
+
+## 高级功能 ##
+<br /> 按Shift键,画垂直、水平直线;
+<br /> 按Shift键,椭圆和正圆自由切换;
+<br /> 按Shift键,等腰三角形和等边自由切换;
+<br /> 按Shift键,等边直角三角形和直角三角形自由切换;
+<br /> 按Shift键,正方形和长方形自由切换;
+
+**附fabric.js使用笔记:**[点击打开](https://github.com/vipstone/drawingboard/blob/master/fabricjs%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0.md)
+
+
+
+## 功能预览 ##
+![](https://raw.githubusercontent.com/vipstone/drawingboard/master/drawingboard/image/demoPreview.gif)
+
+
+<br />
+<br />
+<font color=red size=4 face="宋体">各位大侠如果觉得不错,欢迎点击star!</font>
+
+## todo ##
+
+mac下样式问题兼容
+
+添加撤销功能
+
+

+ 215 - 0
drawingboard-master/drawingboard/check-bak.html

@@ -0,0 +1,215 @@
+<html>
+
+<head>
+    <meta charset="UTF-8">
+    <title>作业批改 - 旧版</title>
+    <link rel="stylesheet" href="css/index.css">
+    <link rel="stylesheet" href="http://cdn.staticfile.org/semantic-ui/2.3.1/semantic.css">
+</head>
+
+<body style="background-color: #E5E4E5;overflow-x: hidden;">
+
+    <div style="margin-top:10px;">
+        <div style="width:50px;float:left;">
+            <ul id="toolsul" class="tools">
+
+                <li data-type="right" class="active" title="整题正确">
+                    <i class="icon-right-select" data-default='icon-right-black'></i>
+                </li>
+                <li data-type="wrong" title="整题错误">
+                    <i class="icon-wrong-black" data-default='icon-wrong-black'></i>
+                </li>
+                <li data-type="smallright" title="题目内单个正确">
+                    <i class="icon-right-small-black" data-default='icon-right-small-black'></i>
+                </li>
+                <li data-type="smallwrong" title="题目内单个错误">
+                    <i class="icon-wrong-small-black" data-default='icon-wrong-small-black'></i>
+                </li>
+                <li data-type="rectangle" title="错题圈定">
+                    <i class="icon-tools icon-square-black" data-default="icon-tools icon-square-black"></i>
+                </li>
+
+                <li data-type="remove" title="橡皮擦">
+                    <i class="icon-tools icon-remove-black" data-default='icon-tools icon-remove-black'></i>
+                </li>
+
+                <li onclick="cutFun()" title="成绩查看">
+                    <i class="icon-submit-black" data-default='icon-submit-black'></i>
+                </li>
+            </ul>
+
+        </div>
+        <div id="canvasDiv" class="canvasDiv" style="width:auto;height: auto;">
+            <canvas id="c" height="890">请使用支持HTML5的浏览器</canvas>
+        </div>
+        <div style="color:red;margin-top: 10px;margin-left: 60px;">注意:错题必须使用工具栏“错题圈定”圈定错题。</div>
+        <div id="wrongImg"></div>
+
+
+
+    </div>
+
+    <script src="/js/jquery.min.js"></script>
+    <script src="/js/fabric.min.js"></script>
+    <script src="js/check-bak.js"></script>
+    <script src="js/canvasZoom.js"></script>
+    <script src="https://unpkg.com/qiniu-js@2.2.2/dist/qiniu.min.js"></script>
+    <script src="http://cdn.staticfile.org/semantic-ui/2.3.1/semantic.js"></script>
+    <script>
+
+        var qiniuToken = undefined;
+        jQuery.ajax({
+            type: "GET",
+            cache: false,
+            dataType: "jsonp",
+            url: 'http://127.0.0.1:8360/qiniu/gettoken',
+            data: {},
+            success: function (res) {
+                qiniuToken = res.token;
+            }
+        });
+
+
+        canvas.on("mouse:up", function () {
+            if (window.drawType && (window.drawType == "wrong" || window.drawType == "smallwrong")) {
+                //错题批注
+                // $('.ui.modal').modal();
+            }
+        });
+
+        function cutFun() {
+            var objs = canvas.getObjects();
+            var checkObj = [];
+            for (var i = 0; i < objs.length; i++) {
+                if (objs[i].type && objs[i].type != 'image') {
+                    checkObj.push(objs[i]);
+                }
+            }
+            checkObj.sort(function (x, y) { return x.top - y.top; }); //根据控件top排序
+
+            var checkJson = [];
+            var itemSmallRight = 0, itemSmallWrong = 0, prevSmallType = true;
+            for (var i = 0; i < checkObj.length; i++) {
+                switch (checkObj[i].type) {
+                    case 'smallright':
+                        ++itemSmallRight;
+                        break;
+                    case 'smallwrong':
+                        ++itemSmallWrong;
+                        break;
+                    case 'right':
+                    case 'wrong':
+                    case 'rectangle': //框
+                        prevSmallType = false;
+                        break;
+                    default:
+                        break;
+                }
+                if (prevSmallType == false || i == (checkObj.length - 1)) {
+                    //上一个为整题对/错 || 最后一题
+                    if (itemSmallRight > 0 || itemSmallWrong > 0) {
+                        checkJson.push({ 'r': 0, 'w': 0, 'sr': itemSmallRight, 'sw': itemSmallWrong, 'url': '' });
+                        itemSmallRight = 0, itemSmallWrong = 0;
+                    }
+                    prevSmallType = true;
+                }
+                //录入本次大题
+                if (checkObj[i].type == 'right') {
+                    checkJson.push({ 'r': 1, 'w': 0, 'sr': 0, 'sw': 0, 'url': '' });
+                } else if (checkObj[i].type == 'wrong') {
+                    checkJson.push({ 'r': 0, 'w': 1, 'sr': 0, 'sw': 0, 'url': '' });
+                }
+                //圈定的错图上传
+                if (checkObj[i].type == 'rectangle') {
+                    toImgUpload(checkObj[i], checkObj[i].left, checkObj[i].top, checkObj[i].width, checkObj[i].height);
+                }
+            }
+
+            // var msg = "";
+            // for (var i = 0; i < checkJson.length; i++) {
+            //     msg += ("第" + (i + 1) + "题:");
+            //     if (checkJson[i].r) {
+            //         msg += "全对";
+            //     } else if (checkJson[i].w) {
+            //         msg += "全错";
+            //     } else {
+            //         msg += "对:" + checkJson[i].sr + "个" + ",错:" + checkJson[i].sw + "个";
+            //     }
+            //     msg += "\n";
+            // }
+            // if (msg) {
+            //     alert(msg);
+            // }
+
+        }
+
+        //转换成图片并上传
+        function toImgUpload(cObj, left, top, width, height) {
+            canvas.remove(cObj);
+            var base64 = canvas.toDataURL({
+                format: 'png',
+                left: left - 12,
+                top: top - 10,
+                width: width,
+                height: height
+            });
+
+            // data:image/png;base64,
+
+            jQuery("#wrongImg").append('<img src="' + base64 + '"/><br />');
+            canvas.add(cObj);
+
+            //上传,返回地址
+            var putExtra = {
+                fname: "",
+                params: {},
+                mimeType: [] || null
+            };
+            var config = {
+                useCdnDomain: true
+            };
+            // var contentType = 'image/png';
+            // var blob = base64ToBlob(base64.replace('data:image/png;base64,', ''), contentType);
+
+            // var observable = qiniu.upload(blob, "test5.png", qiniuToken, putExtra, config);
+            // var subscription = observable.subscribe({
+            //     next(res) {
+            //         console.log(res);
+            //     },
+            //     error(err) {
+            //         console.log(err);
+            //     },
+            //     complete(res) {
+            //         console.log(res);
+            //     }
+            // });
+
+            // return "";
+        }
+
+        //base64转blob
+        function base64ToBlob(base64, contentType, sliceSize) {
+            contentType = contentType || '';
+            sliceSize = sliceSize || 512;
+            var byteCharacters = atob(base64);
+            var byteArrays = [];
+
+            for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
+                var slice = byteCharacters.slice(offset, offset + sliceSize);
+                var byteNumbers = new Array(slice.length);
+                for (var i = 0; i < slice.length; i++) {
+                    byteNumbers[i] = slice.charCodeAt(i);
+                }
+                var byteArray = new Uint8Array(byteNumbers);
+                byteArrays.push(byteArray);
+            }
+            var blob = new Blob(byteArrays, { type: contentType });
+            return blob;
+        }
+
+
+    </script>
+
+</body>
+
+</html>

+ 487 - 0
drawingboard-master/drawingboard/check.html

@@ -0,0 +1,487 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"
+    />
+    <title>作业批改</title>
+    <link rel="stylesheet" type="text/css" href="../css/api.css" />
+    <link rel="stylesheet" type="text/css" href="../css/style.css" />
+    <link rel="stylesheet" type="text/css" href="../css/check.css" />
+</head>
+
+<body id="data-box">
+    <div class="container">
+        <div class="fn-left handle_menu_wrap">
+            <div class="menu_title">
+                工具
+            </div>
+            <div id="tools" class="handle_btn_list">
+                <div class="handle_btn active" data-type="right">
+                    <div class="handle_btn_img">
+                        <img src="../image/check/all-true.png" class="center-self" alt="">
+                    </div>
+                    <div class="handle_btn_name">
+                        全对
+                    </div>
+                </div>
+                <div class="handle_btn" data-type="rectangle">
+                    <div class="handle_btn_img">
+                        <img src="../image/check/label-icon.png" class="center-self" alt="">
+                    </div>
+                    <div class="handle_btn_name">
+                        错题标注
+                    </div>
+                </div>
+                <div class="handle_btn" data-type="wrong">
+                    <div class="handle_btn_img">
+                        <img src="../image/check/all-wrong.png" class="center-self" alt="">
+                    </div>
+                    <div class="handle_btn_name">
+                        全错
+                    </div>
+                </div>
+                <div class="handle_btn" data-type="smallright">
+                    <div class="handle_btn_img">
+                        <img src="../image/check/true-icon.png" class="center-self" alt="">
+                    </div>
+                    <div class="handle_btn_name">
+                        正确处
+                    </div>
+                </div>
+                <div class="handle_btn" data-type="smallwrong">
+                    <div class="handle_btn_img">
+                        <img src="../image/check/wrong-icon.png" class="center-self" alt="">
+                    </div>
+                    <div class="handle_btn_name">
+                        错误处
+                    </div>
+                </div>
+                <div class="handle_btn" data-type="remove">
+                    <div class="handle_btn_img">
+                        <img src="../image/check/erasure-icon.png" class="center-self" alt="">
+                    </div>
+                    <div class="handle_btn_name">
+                        擦除
+                    </div>
+                </div>
+                <div class="handle_btn" data-type="help">
+                    <div class="handle_btn_img">
+                        <img src="../image/check/help-icon.png" class="center-self" alt="">
+                    </div>
+                    <div class="handle_btn_name">
+                        帮助
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="fn-right correct_main">
+            <div class="wrong_list_wrap">
+                <div class="wrong_list_title">
+                    <i class="before_icon fn-left"></i>
+                    <div>错题</div>
+                </div>
+                <div class="wrong_list">
+                    <div id="errMsg" class="wrong_list_inner">
+
+                    </div>
+                </div>
+            </div>
+            <div class="main_score">
+                <div class="main_score_title">
+                    <i class="before_icon fn-left"></i>
+                    <div>字迹评分</div>
+                </div>
+                <div id="fontScore" class="main_score_num_list fn-clear">
+                    <div class="main_score_num_item fn-left active">1</div>
+                    <div class="main_score_num_item fn-left">2</div>
+                    <div class="main_score_num_item fn-left">3</div>
+                    <div class="main_score_num_item fn-left">4</div>
+                    <div class="main_score_num_item fn-left">5</div>
+                    <div class="main_score_num_item fn-left">6</div>
+                    <div class="main_score_num_item fn-left">7</div>
+                    <div class="main_score_num_item fn-left">8</div>
+                    <div class="main_score_num_item fn-left">9</div>
+                    <div class="main_score_num_item fn-left">10</div>
+                </div>
+            </div>
+            <div id="subBut" class="small_btn_blue confirm">
+                确认完成
+            </div>
+            <div id="moreBtn" class="more_btn"></div>
+            <div id="moreDiv" class="other_btn_wrap fn-hide">
+                <div id="expBtn" class="mark_exce">
+                    异常标记
+                </div>
+                <div id="giveupBtn" class="give_up">
+                    放弃任务
+                </div>
+            </div>
+        </div>
+        <div class="fn-right preview">
+            <div id="simgDiv" class="swiper-container">
+
+            </div>
+            <div class="homework_total center-self-x">
+                <span id="currentNum">1</span>/
+                <span id="sumNum">1</span>
+            </div>
+        </div>
+        <div class="view">
+            <div id="canvasDiv" class="swiper-container center-self-x">
+            </div>
+        </div>
+    </div>
+
+    <div id="maskDiv" class="mask_modal" style="display: none;">
+        <div class="top">
+            <div style="width: 100%;padding-left: 30%;padding-top: 20%">数据提交中,请稍等...</div>
+        </div>
+    </div>
+
+
+    <div id="errModal" class="mark_error_modal fn-hide">
+        <div class="top"></div>
+        <div class="mark_error_box center-self">
+            <div class="mark_error_box_title">
+                <div class="fn-left">
+                    选择错误标签
+                </div>
+                <div id="hideModal" class="fn-right close_icon fn-clear fn-hide">
+                    <img src="../image/check/close-icon.png" class="fn-left" alt="">
+                </div>
+            </div>
+            <div id="errTags" class="wrong_label_list">
+
+            </div>
+            <div id="errVerify" class="small_btn_blue center-self-x confirm_mark">
+                确认
+            </div>
+        </div>
+    </div>
+    <div id="testImg">
+
+    </div>
+</body>
+<script type="text/javascript" src="../js/check/fontsize.js"></script>
+<script type="text/javascript" src="../js/jquery.min.js"></script>
+<script type="text/javascript" src="../js/check/qiniu.min.js"></script>
+<script type="text/javascript" src="js/fabric.min.js"></script>
+<script type="text/javascript" src="js/check/canvas.js"></script>
+<script type="text/javascript" src="js/check/config.js"></script>
+<script type="text/javascript" src="js/tools/md5.min.js"></script>
+<script type="text/javascript" src="js/tools/uuid.js"></script>
+<script type="text/javascript" src="js/tools/upload.js"></script>
+
+<script type="text/javascript">
+    jQuery(function () {
+        var canvasInit = []; //已经初始化的canvas
+        var uploadImageArray = []; //需要上传的图片集合{"name":"xxx","base64":"xxx"}
+        var errTagType = {
+            '语文': ['遗漏', '理解不清晰', '粗心大意', '审题不清', '基础不牢', '积累不够', '运用错误', '区分错误', '缺乏逻辑'],
+            '数学': ['计算错误', '审题错误', '遗漏', '基础不牢固', '粗心大意', '概念不清', '换算错误', '公式不熟练', '缺乏解题技巧', '书写不端正'],
+            '英语': ['粗心大意', '审题错误', '基础不牢固', '书写不规范', '单词拼写错误', '遗漏', '介词搭配错误', '单复数错误']
+        };
+
+        var img = decodeURIComponent(getUrlParam('img')); //图片集合
+        var subject = decodeURIComponent(getUrlParam('subject')); //科目
+        if (!img && JSON.parse(img)) {
+            alert("网络错误");
+        }
+        img = JSON.parse(img);
+        jQuery('#sumNum').text(img.length);
+        var simgEle = "";
+        for (var i = 0; i < img.length; i++) {
+            if (i == 0) {
+                jQuery("#canvasDiv").append('<canvas id="c0" height="1100" width="825"></canvas>');
+                canvasInit.push("c0");
+                switchCanvas(img[i].i, 0);
+                simgEle += '<div class="swiper-slide swiper-slide-visible swiper-slide-active active-nav">';
+            } else {
+                simgEle += '<div class="swiper-slide swiper-slide-visible">';
+            }
+            simgEle += ('<div class="slide_inner"><img src="' + img[i].s + '" class="center-self"></div></div>');
+        }
+        jQuery("#simgDiv").append(simgEle);
+
+        //点击缩略图
+        jQuery(".swiper-slide-visible").on("click", function () {
+            var _index = jQuery(this).index(),
+                _cid = "c" + _index;
+            if (canvasInit.indexOf(_cid) == -1) {
+                jQuery("#canvasDiv").append('<canvas id="' + _cid + '" height="1100" width="825"></canvas>');
+                canvasInit.push(_cid);
+            }
+            jQuery(this).addClass("active-nav").siblings().removeClass("active-nav");
+            switchCanvas(img[_index].i, _index);
+            jQuery("#currentNum").text(1 + _index);
+        });
+
+        //隐藏弹窗
+        jQuery("#hideModal").on("click", function () {
+            jQuery("#errModal").addClass("fn-hide");
+        });
+
+        //弹窗科目错误设置
+        if (subject && errTagType[subject] && errTagType[subject].length > 0) {
+            for (var i = 0; i < errTagType[subject].length; i++) {
+                jQuery('#errTags').append('<div name="etag" class="wrong_label fn-left">' + errTagType[subject][i] + '</div>');
+            }
+        }
+
+        //错误标签点击
+        jQuery("div[name=etag]").on("click", function () {
+            jQuery(this).toggleClass("active");
+        });
+
+        //错误标签选定
+        jQuery("#errVerify").on("click", function () {
+            var errTags = jQuery('#errTags').find(".active");
+            if (errTags.length <= 0) {
+                alert('请先选中标签!');
+                return false;
+            }
+            var errSonEle = '<div class="wrong_item">';
+            errSonEle += ' <i class="serial_number fn-left" value="' + appErrCount + '">' + appErrCount + '</i>';
+            errSonEle += '<div class="wrong_content fn-clear">';
+            for (var i = 0; i < errTags.length; i++) {
+                errSonEle += '<div class="wrong_label fn-left">' + jQuery(errTags[i]).text() + '</div>';
+            }
+            errSonEle += '</div></div>';
+            jQuery("#errMsg").prepend(errSonEle);
+            jQuery("#errModal").addClass("fn-hide");
+        });
+
+        //绑定工具事件
+        jQuery("#tools").find(".handle_btn").on("click", function () {
+            //设置样式
+            jQuery(this).addClass("active").siblings().removeClass("active");
+            drawType = jQuery(this).attr("data-type");
+            // window.drawType = drawType;
+            canvas.isDrawingMode = false;
+            if (drawType == "pen") {
+                canvas.isDrawingMode = true;
+            } else if (drawType == "remove") {
+                canvas.selection = true;
+                canvas.skipTargetFind = false;
+                canvas.selectable = true;
+            } else if (drawType == "help") {
+                jQuery("#c").toggleClass("fn-hide");
+            }
+            else {
+                canvas.skipTargetFind = true; //画板元素不能被选中
+                canvas.selection = false; //画板不显示选中
+            }
+        });
+
+        //get七牛token
+        var qiniuToken = undefined;
+        jQuery.ajax({
+            type: "GET",
+            cache: false,
+            dataType: "jsonp",
+            url: config.tokenURL,
+            data: {},
+            success: function (res) {
+                qiniuToken = res.token;
+            }
+        });
+
+        //提交作业
+        jQuery("#subBut").on("click", function () {
+            jQuery("#maskDiv").show();
+            var fs = jQuery("#fontScore").find("div.active").index() + 1;
+            if (fs <= 0) {
+                alert("操作失败,请先选择字迹评分!");
+                return false;
+            }
+            if (true) { //TODO:confirm("确认作业批改完成?")
+                var checkJson = {
+                    "pages": [],
+                    "font": fs,
+                    "callback": {
+                        "task_id": (getUrlParam("task_id") || ""),
+                        "task_list_id": (getUrlParam("task_list_id") || ""),
+                        "userinfo": (getUrlParam("userinfo") || ""),
+                        "type": (getUrlParam("type") || "")
+                    }
+                };
+                window.checkJson = undefined;
+                for (var i = 0; i < canvasArr.length; i++) {
+                    if (canvasArr[i]) {
+                        var canvasJson = {
+                            "question": [],
+                            "page": {
+                                "img": "",
+                                "imgorg": "",
+                                "w": 0,
+                                "h": 0,
+                                "index": i
+                            }
+                        };
+                        var objs = canvasArr[i].getObjects();
+                        var checkObj = [];
+                        for (var j = 0; j < objs.length; j++) {
+                            if (objs[j].type && objs[j].type != 'image') {
+                                checkObj.push(objs[j]);
+                            } else {
+                                var _imgName = md5(uuid.uuid() + new Date().getTime()) + ".png";
+                                canvasJson.page.imgorg = objs[j]._element.src;
+                                canvasJson.page.img = config.imgDomain + _imgName;
+                                canvasJson.page.w = objs[j].width;
+                                canvasJson.page.h = objs[j].height;
+                                addUploadImg(canvasArr[i], objs[j], _imgName, false);
+                            }
+                        }
+
+                        checkObj.sort(function (x, y) { return x.top - y.top; }); //根据控件top排序
+
+                        var itemSmallRight = 0, itemSmallWrong = 0, prevSmallType = true, errImg = "", errIndexs = [];
+                        for (var j = 0; j < checkObj.length; j++) {
+                            switch (checkObj[j].type) {
+                                case 'smallright':
+                                    ++itemSmallRight;
+                                    errIndexs.push(checkObj[j].eindex);
+                                    break;
+                                case 'smallwrong':
+                                    ++itemSmallWrong;
+                                    errIndexs.push(checkObj[j].eindex);
+                                    break;
+                                case 'right':
+                                case 'wrong':
+                                    prevSmallType = false;
+                                    break;
+                                case 'rectangle': //框
+                                    var _imgName = md5(uuid.uuid() + new Date().getTime()) + ".png";
+                                    errImg = config.imgDomain + _imgName;
+                                    addUploadImg(canvasArr[i], checkObj[j], _imgName, true);
+                                    prevSmallType = false;
+                                    break;
+                                default:
+                                    break;
+                            }
+                            if (prevSmallType == false || j == (checkObj.length - 1)) {
+                                //下一题为整题对/错 || 最后一题 (结算上一题[小错/对])
+                                if (itemSmallRight > 0 || itemSmallWrong > 0) {
+                                    var errJson = [];
+                                    if (errIndexs.length > 0) {
+                                        for (var m = 0; m < errIndexs.length; m++) {
+                                            var _eindex = errIndexs[m];
+                                            var txt = getErrTagsByIndex(_eindex);
+                                            errJson.push({
+                                                "id": _eindex + 1,
+                                                "desc": txt,
+                                                "x": checkObj[m].left,
+                                                "y": checkObj[m].top
+                                            });
+                                        }
+                                    }
+                                    canvasJson.question.push({ 'r': 0, 'w': 0, 'sr': itemSmallRight, 'sw': itemSmallWrong, 'eimg': errImg, 'err': errJson });
+                                    errImg = "";
+                                    errIndexs = [];
+                                    itemSmallRight = 0, itemSmallWrong = 0;
+                                }
+                                prevSmallType = true;
+                            }
+                            //录入本次大题
+                            if (checkObj[j].type == 'right') {
+                                canvasJson.question.push({ 'r': 1, 'w': 0, 'sr': 0, 'sw': 0, 'eimg': '', 'err': [] });
+                            } else if (checkObj[j].type == 'wrong') {
+                                var errJson = [];
+                                var _eindex = checkObj[j].eindex;
+                                var txt = getErrTagsByIndex(_eindex);
+                                errJson[0] = {
+                                    "id": _eindex + 1,
+                                    "desc": txt,
+                                    "x": checkObj[j].left,
+                                    "y": checkObj[j].top
+                                };
+                                canvasJson.question.push({ 'r': 0, 'w': 1, 'sr': 0, 'sw': 0, 'eimg': errImg, 'err': errJson });
+                                errImg = "";
+                            }
+                        }
+                        checkJson.pages.push(canvasJson);
+                    } else {
+                        //这里的图片没有点击初始化
+                    }
+                }
+                window.checkJson = JSON.stringify(checkJson);
+
+                //上传图片+请求服务器
+                uploadImg(uploadImageArray, qiniuToken);
+            }
+        });
+        //更多操作
+        jQuery("#moreBtn").on("click", function () {
+            jQuery("#moreDiv").toggleClass("fn-hide");
+        });
+        //异常订单
+        jQuery("#expBtn").on("click", function () {
+            jQuery("#moreDiv").toggleClass("fn-hide");
+            if (confirm("确认为异常订单?")) {
+                //TODO:业务
+            }
+        });
+        //放弃订单
+        jQuery("#giveupBtn").on("click", function () {
+            jQuery("#moreDiv").toggleClass("fn-hide");
+            if (confirm("确认为放弃订单?")) {
+                //TODO:业务
+            }
+        });
+        //字体打分
+        jQuery("#fontScore").find("div").on("click", function () {
+            jQuery(this).addClass("active").siblings().removeClass("active");
+
+        });
+        //获取url中的参数
+        function getUrlParam(name) {
+            var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
+            var r = window.location.search.substr(1).match(reg);
+            if (r != null) return decodeURI(r[2]);
+            return null;
+        }
+        //添加上传图片 (isRemove:类型bool,是否需要移除截图在添加)
+        function addUploadImg(canvas, canvasControl, imgName, isRemove) {
+            if (isRemove) {
+                canvas.remove(canvasControl);
+            }
+            var base64 = canvas.toDataURL({
+                format: 'png',
+                left: canvasControl.left,
+                top: canvasControl.top,
+                width: canvasControl.width,
+                height: canvasControl.height
+            });
+
+            uploadImageArray.push({ "name": imgName, "base64": base64 });
+
+            // jQuery("#testImg").append('<img src="' + base64 + '"/><br />');
+
+            if (isRemove) {
+                canvas.add(canvasControl);
+            }
+        }
+        //获取错误标签描述集合(根据标号)
+        function getErrTagsByIndex(eindex) {
+            var txt = "";
+            var txtCt = jQuery('#errMsg').find('.wrong_item > i[value="' + (eindex + 1) + '"]').siblings().find('div');
+            for (var k = 0; k < txtCt.length; k++) {
+                txt += txtCt.eq(k).text();
+
+                if (k != (txtCt.length - 1)) {
+                    txt += ",";
+                }
+            }
+            return txt;
+        }
+
+    });
+
+
+
+
+</script>
+
+</html>

+ 66 - 0
drawingboard-master/drawingboard/css/api.css

@@ -0,0 +1,66 @@
+html{
+	font-family: sans-serif;
+}
+html,body,header,section,footer,div,ul,ol,li,img,a,span,em,del,legend,center,strong,var,fieldset,form,label,dl,dt,dd,cite,input,hr,time,mark,code,figcaption,figure,textarea,h1,h2,h3,h4,h5,h6,p{
+	margin:0;
+	border:0;
+	padding:0;
+	font-style:normal;
+}
+html,body {
+	-webkit-touch-callout:none;
+	-webkit-text-size-adjust:none;
+	-webkit-tap-highlight-color:rgba(0, 0, 0, 0);
+	/* -webkit-user-select:none; */
+	background-color: #fff;
+}
+nav,article,aside,details,main,header,footer,section,fieldset,figcaption,figure{
+	display: block;
+}
+img,a,button,em,del,strong,var,label,cite,small,time,mark,code,textarea{
+	display:inline-block;
+}
+header,section,footer {
+	position:relative;
+}
+ol,ul{
+	list-style:none;
+}
+input,button,textarea {
+	border:0;
+	margin:0;
+	padding:0;
+	font-size:1em;
+	line-height:1em;
+	/*-webkit-appearance:none;*/
+	background-color:rgba(0, 0, 0, 0);
+}
+span{
+	display:inline-block;
+}
+a:active, a:hover {
+  outline: 0;
+}
+a, a:visited{
+	text-decoration:none;
+}
+
+label, .wordWrap{
+    word-wrap: break-word;
+    word-break: break-all;
+}
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+td,th {
+  padding: 0;
+}
+.clearfix:after{
+	content: ' ';
+	display: block;
+	clear: both;
+	visibility:hidden;
+	line-height: 0;
+	height:0;
+}

+ 320 - 0
drawingboard-master/drawingboard/css/check.css

@@ -0,0 +1,320 @@
+html,
+    body {
+      height: 100%;
+    }
+
+    .container {
+      height: 100%;
+      box-sizing: border-box;
+    }
+
+    .handle_menu_wrap {
+      width: 1.52rem;
+      height: 100%;
+    }
+
+    .menu_title {
+      font-size: 0.32rem;
+      padding: 0.35rem 0;
+      text-align: center;
+      border-bottom: solid 1px #dddddd;
+    }
+
+    .handle_btn {
+      padding: 0.3rem;
+      cursor: pointer;
+    }
+
+    .handle_btn.active {
+        background-color: #ededed;
+      }
+
+    .handle_btn_img {
+      height: 0.44rem;
+      position: relative;
+    }
+
+    .handle_btn_img img {
+      height: 100%;
+    }
+
+    .handle_btn_name {
+      text-align: center;
+      margin-top: 0.2rem;
+      font-size: 0.22rem;
+      color: #999;
+    }
+
+    .correct_main {
+      width: 5.7rem;
+      height: 100%;
+      position: relative;
+    }
+
+    .before_icon {
+      width: 0.2rem;
+      height: 0.2rem;
+      background-color: #f36d00;
+      margin-top: 0.08rem;
+    }
+
+    .preview {
+      position: relative;
+      width: 2rem;
+      height: 100%;
+      border-right: 1px solid #ddd;
+      padding: 0.3rem 0 1.65rem 0;
+      overflow: auto;
+      box-sizing: border-box;
+    }
+
+    .preview .swiper-container {
+      width: 100%;
+    }
+
+    .preview .swiper-container .swiper-slide {
+      height: 1.5rem;
+      width: 100%;
+      padding: 0.25rem 0.3rem;
+      box-sizing: border-box;
+    }
+
+    .preview .swiper-container .swiper-slide.active-nav .slide_inner {
+      border-color: #28a0ff;
+    }
+
+    .preview .swiper-container .swiper-slide .slide_inner {
+      width: 100%;
+      height: 100%;
+      overflow: hidden;
+      position: relative;
+      border: 3px solid transparent;
+    }
+
+    .preview .swiper-container .swiper-slide .slide_inner img {
+      width: 100%;
+    }
+
+    .homework_total {
+      bottom: 0.8rem;
+      font-size: 0.36rem;
+    }
+
+    .view {
+      overflow: auto;
+      position: relative;
+      height: 100%;
+      background-color: #333;
+    }
+
+    .view .swiper-container {
+      width: 825px;
+      height: 1100px;
+      top: 0;
+    }
+
+    .view .swiper-container img {
+      width: 100%;
+      height: 100%;
+    }
+
+    .wrong_list_wrap {
+      padding: 0.3rem;
+      border-bottom: 1px solid #ddd;
+    }
+
+    .wrong_list_title div {
+      overflow: hidden;
+      padding-left: 0.3rem;
+      margin-bottom: 0.3rem;
+    }
+
+    i {
+      font-style: normal;
+    }
+
+    .wrong_list .serial_number {
+      font-size: 0.3rem;
+    }
+
+    .wrong_list {
+      padding-top: 0.1rem;
+      overflow: auto;
+      height: 6.5rem;
+    }
+
+    .wrong_item {
+      padding-top: 0.1rem;
+    }
+
+    .wrong_content {
+      overflow: hidden;
+      padding-left: 0.2rem;
+    }
+
+    .wrong_label {
+      padding: 0 0.3rem;
+      height: 0.44rem;
+      background-color: #cfe9fb;
+      border-radius: 999px;
+      font-size: 0.24rem;
+      color: #28a0f2;
+      text-align: center;
+      line-height: 0.44rem;
+      margin-left: 0.2rem;
+      margin-bottom: 0.2rem;
+      border: 1px solid transparent;
+    }
+
+    .main_score {
+      padding: 0.3rem 0.3rem 0;
+    }
+
+    .main_score_title {
+      margin-bottom: 0.4rem;
+    }
+
+    .main_score_title div {
+      padding-left: 0.3rem;
+      overflow: hidden;
+    }
+
+    .main_score_num_list {
+      padding: 0 0.6rem;
+    }
+
+    .main_score_num_item {
+      cursor: pointer;
+      width: 0.9rem;
+      height: 0.9rem;
+      background-color: #ededed;
+      border-radius: 0.03rem;
+      text-align: center;
+      font-size: 0.44rem;
+      box-sizing: border-box;
+      line-height: 0.9rem;
+      margin-bottom: 0.5rem;
+      margin-right: 0.6rem;
+    }
+
+    .main_score_num_item.active {
+      background-color: #28a0f2;
+      border: solid 0px #309ff8;
+      color: #fff;
+    }
+
+    .main_score_num_item:nth-child(3n) {
+      margin-right: 0;
+    }
+
+    .main_score_num_item:last-child {
+      margin-left: 1.5rem;
+    }
+
+    .correct_main .small_btn_blue.confirm {
+      position: absolute;
+      left: 0.85rem;
+      bottom: 0.4rem;
+    }
+
+    .correct_main .more_btn {
+      cursor: pointer;
+      width: 0.6rem;
+      height: 0.6rem;
+      background: url('../image/check/pop-icon.png') no-repeat;
+      background-size: 100%;
+      position: absolute;
+      right: 0.85rem;
+      bottom: 0.6rem;
+    }
+
+    .mark_error_modal {
+      position: fixed;
+      height: 100%;
+      width: 75%;
+      top: 0;
+      left: 0;
+      z-index: 9999;
+    }
+
+    .mask_modal {
+      position: fixed;
+      height: 100%;
+      width: 100%;
+      top: 0;
+      left: 0;
+      z-index: 9999;
+    }
+
+    .mark_error_box {
+      width: 11.2rem;
+      height: 7.2rem;
+      z-index: 999;
+      background-color: #fff;
+      border-radius: 0.1rem
+    }
+
+    .mark_error_box_title {
+      height: 1.1rem;
+      border-bottom: 1px solid #28a0f2;
+      padding: 0 0.3rem;
+      line-height: 1.1rem;
+      font-size: 0.36rem;
+      box-sizing: border-box;
+    }
+
+    .wrong_label_list {
+      padding: 0.6rem 0.2rem 0.2rem 0.6rem;
+      box-sizing: border-box;
+      height: 6.1rem;
+      overflow: auto;
+    }
+
+    .wrong_label_list .wrong_label {
+      margin-right: 0.4rem;
+      margin-bottom: 0.4rem;
+      margin-left: 0;
+      border-color: #49aff3;
+      background-color: #fff;
+    }
+
+    .wrong_label_list .wrong_label.active {
+      border-color: transparent;
+      background-color: #cfe9fb;
+    }
+
+    .close_icon {
+      width: 0.45rem;
+      height: 0.45rem;
+      cursor: pointer;
+      margin-top: 0.325rem;
+    }
+
+    .close_icon img {
+      width: 100%;
+      height: 100%;
+    }
+
+    .mark_error_box .confirm_mark.small_btn_blue {
+      bottom: 1.2rem;
+    }
+
+    .other_btn_wrap {
+      width: 2.7rem;
+      padding: 0.6rem 0;
+      font-size: 0.36rem;
+      position: absolute;
+      bottom: 1.47rem;
+      right: 1.4rem;
+      border: solid 1px #dddddd;
+      box-shadow: 0 0.06rem 0.07rem 0 rgba(56, 78, 133, 0.1);
+      border-radius: 0.05rem;
+      text-align: center;
+      background-color: #fff;
+    }
+
+    .other_btn_wrap div {
+      padding: 0.25rem 0;
+    }
+
+    .top {height:100%;background-color:#fff;filter:Alpha(Opacity=60);opacity:0.6;}

+ 332 - 0
drawingboard-master/drawingboard/css/index.css

@@ -0,0 +1,332 @@
+.tools {
+  list-style: none;
+  margin: 0;
+  padding: 0;
+}
+
+.tools li {
+  width: 100%;
+  height: 50px;
+  text-align: center;
+  line-height: 50px;
+  font-size: 28px;
+  border-top: #dad7d9 solid 1px;
+  background: #fefefe;
+  cursor: pointer;
+  position: relative;
+}
+
+.tools li:hover {
+  background: #f2f1f2;
+}
+
+.tools li.active {
+  background: #e34f51;
+}
+
+.hide {
+  display: none;
+}
+
+.canvasDiv {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  background: url(../image/canvas_bg.jpg) repeat;
+  margin-left: 60px;
+}
+
+.icon-tools {
+  display: inline-block;
+  width: 28px;
+  height: 28px;
+  background-image: url("../image/tools-28.png");
+  background-repeat: no-repeat;
+  margin-top: 10px;
+}
+
+.icon-color-gray {
+  background-position: -0px -0px;
+}
+
+.icon-color-red {
+  background-position: -28px -0px;
+}
+
+.icon-color-black {
+  background-position: -56px -0px;
+}
+
+.icon-color-blue {
+  background-position: -84px -0px;
+}
+
+.icon-color-select {
+  background-position: -112px -0px;
+}
+
+.icon-eye-black {
+  background-position: -140px -0px;
+}
+
+.icon-eye-select {
+  background-position: -168px -0px;
+}
+
+.icon-noeye-black {
+  background-position: -196px -0px;
+}
+
+.icon-noeye-select {
+  background-position: -0px -28px;
+}
+
+.icon-grids-black {
+  background-position: -28px -28px;
+}
+
+.icon-grids-select {
+  background-position: -56px -28px;
+}
+
+.icon-nogrids-black {
+  background-position: -84px -28px;
+}
+
+.icon-nogrids-select {
+  background-position: -112px -28px;
+}
+
+.icon-pen-black {
+  background-position: -140px -28px;
+}
+
+.icon-pen-select {
+  background-position: -168px -28px;
+}
+
+.icon-move-black {
+  background-position: -196px -28px;
+}
+
+.icon-move-select {
+  background-position: -0px -56px;
+}
+
+.icon-text-black {
+  background-position: -28px -56px;
+}
+
+.icon-text-select {
+  background-position: -56px -56px;
+}
+
+.icon-dottedline-arrow-black {
+  background-position: -84px -56px;
+}
+
+.icon-dottedline-arrow-select {
+  background-position: -112px -56px;
+}
+
+.icon-line-black {
+  background-position: -140px -56px;
+}
+
+.icon-line-select {
+  background-position: -168px -56px;
+}
+
+.icon-dottedline-black {
+  background-position: -196px -56px;
+}
+
+.icon-dottedline-select {
+  background-position: -0px -84px;
+}
+
+.icon-arrow-black {
+  background-position: -28px -84px;
+}
+
+.icon-arrow-select {
+  background-position: -56px -84px;
+}
+
+.icon-circle-black {
+  background-position: -84px -84px;
+}
+
+.icon-circle-select {
+  background-position: -112px -84px;
+}
+
+.icon-ellipse-black {
+  background-position: -140px -84px;
+}
+
+.icon-ellipse-select {
+  background-position: -168px -84px;
+}
+
+.icon-square-black {
+  background-position: -196px -84px;
+}
+
+.icon-square-select {
+  background-position: -0px -112px;
+}
+
+.icon-rectangle-black {
+  background-position: -28px -112px;
+}
+
+.icon-rectangle-select {
+  background-position: -56px -112px;
+}
+
+.icon-rightangle-black {
+  background-position: -84px -112px;
+}
+
+.icon-rightangle-select {
+  background-position: -112px -112px;
+}
+
+.icon-equilateral-black {
+  background-position: -140px -112px;
+}
+
+.icon-equilateral-select {
+  background-position: -168px -112px;
+}
+
+.icon-isosceles-black {
+  background-position: -196px -112px;
+}
+
+.icon-isosceles-select {
+  background-position: -0px -140px;
+}
+
+.icon-isoscelesrighttriangle-black {
+  background-position: -28px -140px;
+}
+
+.icon-isoscelesrighttriangle-select {
+  background-position: -56px -140px;
+}
+
+.icon-remove-black {
+  background-position: -84px -140px;
+}
+
+.icon-remove-select {
+  background-position: -112px -140px;
+}
+
+.icon-clear-black {
+  background-position: -140px -140px;
+}
+
+.icon-clear-select {
+  background-position: -168px -140px;
+}
+
+.video-preview-modal-div {
+  width: 69%;
+  margin: 5% auto 0;
+  text-align: center;
+  background-color: #ffffff;
+}
+
+/********* 添加对错号 **************/
+.icon-right-black{
+  display: inline-block;
+  width: 26px;
+  height: 26px;
+  background-image: url(../image/right.png);
+  background-repeat: no-repeat;
+  margin-top: 10px;
+}
+
+.icon-right-select{
+  display: inline-block;
+  width: 26px;
+  height: 26px;
+  background-image: url(../image/right-sel.png);
+  background-repeat: no-repeat;
+  margin-top: 10px;
+}
+
+.icon-wrong-black{
+  display: inline-block;
+  width: 26px;
+  height: 26px;
+  background-image: url(../image/wrong.png);
+  background-repeat: no-repeat;
+  margin-top: 10px;
+}
+
+.icon-wrong-select{
+  display: inline-block;
+  width: 26px;
+  height: 26px;
+  background-image: url(../image/wrong-sel.png);
+  background-repeat: no-repeat;
+  margin-top: 10px;
+}
+
+.icon-right-small-black{
+  display: inline-block;
+  width: 28px;
+  height: 28px;
+  background-image: url(../image/right-small.png);
+  background-repeat: no-repeat;
+  margin-top: 10px;
+}
+
+.icon-right-small-select{
+  display: inline-block;
+  width: 28px;
+  height: 28px;
+  background-image: url(../image/right-small-sel.png);
+  background-repeat: no-repeat;
+  margin-top: 10px;
+}
+
+.icon-wrong-small-black{
+  display: inline-block;
+  width: 28px;
+  height: 28px;
+  background-image: url(../image/wrong-small.png);
+  background-repeat: no-repeat;
+  margin-top: 10px;
+}
+
+.icon-wrong-small-select{
+  display: inline-block;
+  width: 28px;
+  height: 28px;
+  background-image: url(../image/wrong-small-sel.png);
+  background-repeat: no-repeat;
+  margin-top: 10px;
+}
+
+.icon-submit-black{
+  display: inline-block;
+  width: 28px;
+  height: 28px;
+  background-image: url(../image/submit.png);
+  background-repeat: no-repeat;
+  margin-top: 10px;
+}
+
+.icon-submit-select{
+  display: inline-block;
+  width: 28px;
+  height: 28px;
+  background-image: url(../image/submit-sel.png);
+  background-repeat: no-repeat;
+  margin-top: 10px;
+}

+ 296 - 0
drawingboard-master/drawingboard/css/style.css

@@ -0,0 +1,296 @@
+html, body {
+  min-height: 100%;
+  font-family: "黑体";
+  color: #000;
+  font-size: 0.32rem;
+}
+
+.fn-left {
+  float: left;
+}
+
+
+.fn-right {
+  float: right;
+}
+
+.fn-clear:after {
+  content: ' ';
+  display: block;
+  clear: both;
+  visibility: hidden;
+  line-height: 0;
+  height: 0;
+}
+
+.fn-hide {
+  display: none !important;
+}
+
+.center-self {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, -50%)
+}
+
+.center-self-x {
+  position: absolute;
+  left: 50%;
+  transform: translateX(-50%);
+}
+
+.center-self-y {
+  position: absolute;
+  top: 50%;
+  transform: translateY(-50%);
+}
+
+.flex-wrap {
+  display: -webkit-box;
+  display: -webkit-flex;
+  display: flex;
+}
+
+.flex-con {
+  -webkit-box-flex: 1;
+  -webkit-flex: 1;
+  flex: 1;
+}
+
+.flex-vertical {
+  -webkit-box-orient: vertical;
+  -webkit-flex-flow: column;
+  flex-flow: column;
+}
+
+.one-text-cut {
+  text-overflow: ellipsis;
+  overflow: hidden;
+  white-space: nowrap;
+}
+
+.two-text-cut {
+  overflow: hidden;
+  display: -webkit-box;
+  -webkit-line-clamp: 2;
+  -webkit-box-orient: vertical;
+}
+
+.three-text-cut {
+  overflow: hidden;
+  display: -webkit-box;
+  -webkit-line-clamp: 3;
+  -webkit-box-orient: vertical;
+}
+
+.font_54 {
+  font-size: 0.54rem;
+}
+
+.font_48 {
+  font-size: 0.48rem;
+}
+
+.font_36 {
+  font-size: 0.36rem;
+}
+
+.font_34 {
+  font-size: 0.34rem;
+}
+
+.font_32 {
+  font-size: 0.32rem;
+}
+
+.font_30 {
+  font-size: 0.30rem;
+}
+
+.font_28 {
+  font-size: 0.28rem;
+}
+
+.font_24 {
+  font-size: 0.24rem;
+}
+
+.color_long {
+  color: #999999 !important;
+}
+
+.color_secondary {
+  color: #4a4a4a !important;
+}
+
+.color_important {
+  color: #000000 !important;
+}
+
+.color_blue {
+  color: #28a0ff;
+}
+
+.color_white {
+  color: #ffffff;
+}
+
+.color_danger {
+  color: #f74c31;
+}
+
+.color_orange{
+  color:#f36d00
+}
+
+.color_deep_blue {
+  color: #0073e6;
+}
+
+.bg_blue {
+  background-color: #28a0ff;
+}
+
+.bg_danger {
+  background-color: #f74c30;
+}
+
+.bg_orange {
+  background-color: #f36d00;
+}
+
+.bg_yellow {
+  background-color: #fec05d;
+}
+
+.text-left{
+    text-align: left;
+}
+
+.text-center{
+    text-align: center;
+}
+
+.text-right{
+    text-align: right;
+}
+
+.disabled {
+  color: #c8c8c8 !important;
+}
+
+.small_btn_blue {
+  width: 2.7rem;
+  padding: 0.25rem 0;
+  background-color: #28a0f2;
+  border-radius: 0.08rem;
+  text-align: center;
+  color: #fff;
+  font-size: 0.36rem;
+  line-height: 0.5rem;
+  cursor: pointer;
+}
+
+.small_btn_blue_240 {
+  width: 2.4rem;
+  padding: 0.25rem 0;
+  background-color: #28a0f2;
+  border-radius: 0.08rem;
+  text-align: center;
+  color: #fff;
+  font-size: 0.36rem;
+  line-height: 0.5rem;
+  cursor: pointer;
+}
+
+.small_btn_gray_240 {
+  width: 2.4rem;
+  padding: 0.25rem 0;
+  background-color: #cccccc;
+  border-radius: 0.08rem;
+  text-align: center;
+  color: #fff;
+  font-size: 0.36rem;
+  line-height: 0.5rem;
+  cursor: pointer;
+}
+
+input:-webkit-autofill , textarea:-webkit-autofill, select:-webkit-autofill {
+  -webkit-box-shadow: 0 0 0px 1000px transparent  inset !important;
+  background-color:transparent;
+  background-image: none;
+  transition: background-color 50000s ease-in-out 0s;
+}
+
+#point_message {
+  padding: 0 0.5rem;
+  height: 0.8rem;
+  line-height: 0.8rem;
+  background-color: rgba(0, 0, 0, 0.1);
+  font-size: 0.36rem;
+  position: fixed;
+  bottom: 1.5rem;
+  left: 50%;
+  transform: translateX(-50%);
+  color: #000;
+  border-radius: 9999px;
+  z-index: 9999;
+}
+
+#point_message.white {
+  background-color: rgba(255, 255, 255, 0.7);
+}
+
+#confirm_modal {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(0, 0, 0, 0.7);
+  z-index: 999;
+}
+
+#confirm_box {
+  width: 11.18rem;
+  height: 6.63rem;
+  background: #fff url('../image/check/select-icon.png') no-repeat 1.24rem 1.54rem;
+  background-size: 1.2rem 1.5rem;
+  border-radius: 0.2rem;
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%,-50%);
+}
+
+#confirm_box #confirm_btn,#confirm_box #close_btn {
+  position: absolute;
+  bottom: 1.2rem;
+  width: 2.7rem;
+  height: 1.1rem;
+  border-radius: 0.08rem;
+  color: #fff;
+  line-height: 1.1rem;
+  text-align: center;
+  cursor: pointer;
+}
+
+#confirm_box #confirm_btn {
+  background-color: #28a0f2;
+  right: 1.5rem;
+}
+
+#confirm_box #close_btn {
+  background-color: #cccccc;
+  left: 1.5rem;
+}
+
+#confirm_box #confirm_text {
+  position: absolute;
+  left: 3.14rem;
+  top: 1.66rem;
+  width: 6.81rem;
+  color: #000000;
+  font-size: 0.36rem;
+}

+ 125 - 0
drawingboard-master/drawingboard/css/swiper.css

@@ -0,0 +1,125 @@
+/*
+ * Swiper 2.7.6
+ * Mobile touch slider and framework with hardware accelerated transitions
+ *
+ * http://www.idangero.us/sliders/swiper/
+ *
+ * Copyright 2010-2015, Vladimir Kharlampidi
+ * The iDangero.us
+ * http://www.idangero.us/
+ *
+ * Licensed under GPL & MIT
+ *
+ * Released on: February 11, 2015
+*/
+/* ===============================================================
+Basic Swiper Styles 
+================================================================*/
+.swiper-container {
+	margin:0 auto;
+	position:relative;
+	overflow:hidden;
+	direction:ltr;
+	-webkit-backface-visibility:hidden;
+	-moz-backface-visibility:hidden;
+	-ms-backface-visibility:hidden;
+	-o-backface-visibility:hidden;
+	backface-visibility:hidden;
+	/* Fix of Webkit flickering */
+	z-index:1;
+}
+.swiper-wrapper {
+	position:relative;
+	width:100%;
+	-webkit-transition-property:-webkit-transform, left, top;
+	-webkit-transition-duration:0s;
+	-webkit-transform:translate3d(0px,0,0);
+	-webkit-transition-timing-function:ease;
+	
+	-moz-transition-property:-moz-transform, left, top;
+	-moz-transition-duration:0s;
+	-moz-transform:translate3d(0px,0,0);
+	-moz-transition-timing-function:ease;
+	
+	-o-transition-property:-o-transform, left, top;
+	-o-transition-duration:0s;
+	-o-transform:translate3d(0px,0,0);
+	-o-transition-timing-function:ease;
+	-o-transform:translate(0px,0px);
+	
+	-ms-transition-property:-ms-transform, left, top;
+	-ms-transition-duration:0s;
+	-ms-transform:translate3d(0px,0,0);
+	-ms-transition-timing-function:ease;
+	
+	transition-property:transform, left, top;
+	transition-duration:0s;
+	transform:translate3d(0px,0,0);
+	transition-timing-function:ease;
+
+	-webkit-box-sizing: content-box;
+	-moz-box-sizing: content-box;
+	box-sizing: content-box;
+}
+.swiper-free-mode > .swiper-wrapper {
+	-webkit-transition-timing-function: ease-out;
+	-moz-transition-timing-function: ease-out;
+	-ms-transition-timing-function: ease-out;
+	-o-transition-timing-function: ease-out;
+	transition-timing-function: ease-out;
+	margin: 0 auto;
+}
+.swiper-slide {
+	float: left;
+	-webkit-box-sizing: content-box;
+	-moz-box-sizing: content-box;
+	box-sizing: content-box;
+}
+
+/* IE10 Windows Phone 8 Fixes */
+.swiper-wp8-horizontal {
+	-ms-touch-action: pan-y;
+}
+.swiper-wp8-vertical {
+	-ms-touch-action: pan-x;
+}
+
+/* ===============================================================
+Your custom styles, here you need to specify container's and slide's
+sizes, pagination, etc.
+================================================================*/
+.swiper-container {
+	/* Specify Swiper's Size: */
+
+	/*width:200px;
+	height: 100px;*/
+}
+.swiper-slide {
+	/* Specify Slides's Size: */
+	
+	/*width: 100%;
+	height: 100%;*/
+}
+.swiper-slide-active {
+	/* Specific active slide styling: */
+	
+}
+.swiper-slide-visible {
+	/* Specific visible slide styling: */	
+
+}
+/* ===============================================================
+Pagination Styles
+================================================================*/
+.swiper-pagination-switch {
+	/* Stylize pagination button: */	
+
+}
+.swiper-active-switch {
+	/* Specific active button style: */	
+	
+}
+.swiper-visible-switch {
+	/* Specific visible button style: */	
+	
+}

+ 48 - 0
drawingboard-master/drawingboard/demo/loadimg.html

@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <meta http-equiv="X-UA-Compatible" content="ie=edge">
+    <title>画板</title>
+    <style>
+        .canvas {
+            border: 1px solid rgb(170, 170, 170);
+            cursor: pointer;
+        }
+
+        .mgTop {
+            margin-top: 30px;
+            text-align: center;
+        }
+    </style>
+    <script src="https://cdn.bootcss.com/fabric.js/2.2.3/fabric.min.js"></script>
+</head>
+
+<body style="padding-left: 10px;text-align:center;">
+
+    <h1>图片加载</h1>
+
+    <div class="mgTop">
+        <canvas id="freeCanvas" class="canvas"></canvas>
+    </div>
+
+    <script>
+        var canvas = new fabric.Canvas("freeCanvas", {
+            isDrawingMode: false,
+            selection: false,
+            width: 1000,
+            height: 600
+        });
+
+        fabric.Image.fromURL('../image/tools-28.png', function (img) {
+            img.scaleToHeight(224 / 2, false);  //缩放图片高度
+            img.scaleToWidth(168 / 2, false);   //缩放图片宽度
+            canvas.add(img);
+        });
+
+    </script>
+</body>
+
+</html>

+ 121 - 0
drawingboard-master/drawingboard/demo/writingpad.html

@@ -0,0 +1,121 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <title>手写板绘制</title>
+    <style>
+        .canvas {
+            border: 1px solid rgb(170, 170, 170);
+            cursor: pointer;
+        }
+
+        .mgTop {
+            margin-top: 30px;
+            text-align: center;
+        }
+    </style>
+    <script src="../js/fabric.min.js"></script>
+</head>
+
+<body style="padding-left: 10px;text-align:center;">
+
+    <h1>手写板测试</h1>
+
+    <div class="mgTop">
+        <canvas width="1880" height="1329" id="freeCanvas" class="canvas"></canvas>
+    </div>
+
+    <button style="display: none;" onclick="toData()"> 转换 </button>
+
+    <button onclick="clearCanvas()"> 清空画板 </button>
+
+    <script>
+        var canvas = new fabric.Canvas("freeCanvas", {
+            isDrawingMode: true,
+            selection: false,
+            width: 1880,
+            height: 1329
+        });
+
+        window.open("http://cmd.com/setpadcanvas?" + canvas.width + "&" + canvas.height);
+
+        function toData() {
+            console.log(canvas.toJSON());
+            console.log(drawingPath.path);
+        }
+
+        var invalidCoord = -1000000; //无效的坐标值
+        var prevX = invalidCoord, prevY = invalidCoord; //绘制中上一个节点的x,y
+        var drawingIndex = 0; //绘制对象的下标
+        var drawingPath = undefined;
+        var drawColor = '#E34F51',
+            strokeWidth = 2,
+            tempCount = 0;
+
+        //手写板绘制 type:M=>开始绘制 Q=>绘制中 L=>结束绘制
+        function writingPad(type, x, y) {
+
+            // window.open("http://cmd.com/WriteLog?writingPad—type:" + type + " x:" + x + " y:" + y);
+
+            if (type) {
+                switch (type.toLowerCase()) {
+                    case 'm':
+                        //开始绘制
+                        drawingPath = new fabric.Path('M ' + x + ' ' + y + ' ', {
+                            stroke: drawColor,
+                            fill: "rgba(255, 255, 255, 0)",
+                            strokeWidth: strokeWidth
+                        });
+                        canvas.add(drawingPath);
+                        break;
+                    case 'q':
+                        //绘制中
+                        if (drawingPath) {
+                            if (prevX == invalidCoord || prevY == invalidCoord) {
+                                prevX = x, prevY = y;
+                            } else {
+                                ++tempCount;
+                                if (tempCount % 2) {
+                                    drawingPath.path.push(["Q", prevX, prevY, x, y]);
+                                    var _path = drawingPath.path;
+                                    canvas.remove(_path); //先移除
+                                    //再添加(变相实现更新)
+                                    drawingPath = new fabric.Path(_path, {
+                                        stroke: drawColor,
+                                        fill: "rgba(255, 255, 255, 0)",
+                                        strokeWidth: strokeWidth
+                                    });
+                                    canvas.add(drawingPath);
+                                    prevX = invalidCoord, prevY = invalidCoord;
+
+                                    // window.open("http://cmd.com/WriteLog?drawingPath—type:" + type + " x:" + x + " y:" + y);
+
+                                }
+                            }
+                        } else {
+                            alert('绘制失败:画板异常,请重新连接画板重试!');
+                        }
+                        break;
+                    case 'l':
+                        //结束绘制
+                        drawingPath.path.push(["L", x, y]);
+                        // canvas.loadFromJSON(canvas.toJSON());
+                        drawingPath = undefined;
+                        prevX = invalidCoord, prevY = invalidCoord;
+                        tempCount = 0;
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+
+        function clearCanvas() {
+            canvas.clear();
+        }
+
+    </script>
+</body>
+
+</html>

+ 70 - 0
drawingboard-master/drawingboard/doc.html

@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <meta http-equiv="X-UA-Compatible" content="ie=edge">
+    <title>画板程序</title>
+    <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css">
+    <style>
+        .canvas {
+            width: 400px;
+            height: 200px;
+            border: 1px solid rgb(170, 170, 170);
+            cursor: pointer;
+        }
+
+        .mgTop {
+            margin-top: 30px;
+        }
+    </style>
+    <script src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js "></script>
+    <script src="https://cdn.bootcss.com/fabric.js/2.0.0-rc.4/fabric.js "></script>
+    <script src="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
+    <script>hljs.initHighlightingOnLoad();</script>
+</head>
+
+<body style="padding-left: 10px;">
+    <div class="mgTop">
+        <h1>1.自由绘</h1>
+        <canvas id="freeCanvas" class="canvas"></canvas>
+        <br /> 代码:
+        <pre><code class="javascipt">
+                var canvas = new fabric.Canvas("freeCanvas", {
+                    isDrawingMode: true,
+                    width: 400,
+                    height: 250
+                });
+        </code></pre>
+    </div>
+    <HR color=#ccc SIZE=1>
+    <div class="mgTop">
+        <h1>2.画直线</h1>
+        <canvas id="lineCanvas" class="canvas"></canvas>
+        <br /> 代码:
+        <pre><code class="javascipt">
+                        
+                </code></pre>
+    </div>
+
+    <script>
+        //自由绘
+        var fCanvas = new fabric.Canvas("freeCanvas", {
+            isDrawingMode: true,
+            width: 400,
+            height: 250
+        });
+
+        //画直线
+        var lCanvas = new fabric.Canvas("lineCanvas");
+
+
+        var line = new fabric.Path(_config);
+        line.set("stroke", "red");
+
+
+    </script>
+</body>
+
+</html>

BIN
drawingboard-master/drawingboard/favicon.ico


BIN
drawingboard-master/drawingboard/image/canvas_bg.jpg


BIN
drawingboard-master/drawingboard/image/check/all-true.png


BIN
drawingboard-master/drawingboard/image/check/all-wrong.png


BIN
drawingboard-master/drawingboard/image/check/app-logo.png


BIN
drawingboard-master/drawingboard/image/check/arrow-left.png


BIN
drawingboard-master/drawingboard/image/check/arrow-right.png


BIN
drawingboard-master/drawingboard/image/check/cancel-icon.png


BIN
drawingboard-master/drawingboard/image/check/change-icon.png


BIN
drawingboard-master/drawingboard/image/check/classroom-not-full.png


BIN
drawingboard-master/drawingboard/image/check/close-icon.png


BIN
drawingboard-master/drawingboard/image/check/confirm-icon.png


BIN
drawingboard-master/drawingboard/image/check/correct-details-bg.png


BIN
drawingboard-master/drawingboard/image/check/default-head-blue.png


BIN
drawingboard-master/drawingboard/image/check/default-head-gray.png


BIN
drawingboard-master/drawingboard/image/check/delete-icon.png


BIN
drawingboard-master/drawingboard/image/check/enlarge-icon.png


BIN
drawingboard-master/drawingboard/image/check/erasure-icon.png


BIN
drawingboard-master/drawingboard/image/check/error-icon.png


BIN
drawingboard-master/drawingboard/image/check/error-tag.png


BIN
drawingboard-master/drawingboard/image/check/help-icon.png


BIN
drawingboard-master/drawingboard/image/check/homework-answer-icon.png


BIN
drawingboard-master/drawingboard/image/check/homework-correct-icon.png


BIN
drawingboard-master/drawingboard/image/check/homework-entry-icon.png


BIN
drawingboard-master/drawingboard/image/check/homework-inspect-icon.png


BIN
drawingboard-master/drawingboard/image/check/homework-review-icon.png


BIN
drawingboard-master/drawingboard/image/check/label-icon.png


BIN
drawingboard-master/drawingboard/image/check/loading_more.gif


BIN
drawingboard-master/drawingboard/image/check/logo.png


BIN
drawingboard-master/drawingboard/image/check/modify-password-icon.png


BIN
drawingboard-master/drawingboard/image/check/pop-icon.png


BIN
drawingboard-master/drawingboard/image/check/pwd0.png


BIN
drawingboard-master/drawingboard/image/check/pwd1.png


BIN
drawingboard-master/drawingboard/image/check/right-tag.png


BIN
drawingboard-master/drawingboard/image/check/select-icon.png


BIN
drawingboard-master/drawingboard/image/check/sign-out-icon.png


BIN
drawingboard-master/drawingboard/image/check/test1.jpg


BIN
drawingboard-master/drawingboard/image/check/test2.jpg


BIN
drawingboard-master/drawingboard/image/check/test3.jpg


BIN
drawingboard-master/drawingboard/image/check/test4.jpg


BIN
drawingboard-master/drawingboard/image/check/test5.jpg


BIN
drawingboard-master/drawingboard/image/check/true-icon.png


BIN
drawingboard-master/drawingboard/image/check/user-info-icon.png


BIN
drawingboard-master/drawingboard/image/check/user0.png


BIN
drawingboard-master/drawingboard/image/check/user1.png


BIN
drawingboard-master/drawingboard/image/check/work-original.jpg


BIN
drawingboard-master/drawingboard/image/check/work-total-icon.png


BIN
drawingboard-master/drawingboard/image/check/work.png


BIN
drawingboard-master/drawingboard/image/check/wrong-icon.png


BIN
drawingboard-master/drawingboard/image/check/开始批改-效果图.png


BIN
drawingboard-master/drawingboard/image/demoPreview.gif


BIN
drawingboard-master/drawingboard/image/right-sel.png


BIN
drawingboard-master/drawingboard/image/right-small-sel.png


BIN
drawingboard-master/drawingboard/image/right-small.png


BIN
drawingboard-master/drawingboard/image/right.png


BIN
drawingboard-master/drawingboard/image/submit-sel.png


BIN
drawingboard-master/drawingboard/image/submit.png


BIN
drawingboard-master/drawingboard/image/tools-28.png


BIN
drawingboard-master/drawingboard/image/wrong-sel.png


BIN
drawingboard-master/drawingboard/image/wrong-small-sel.png


BIN
drawingboard-master/drawingboard/image/wrong-small.png


BIN
drawingboard-master/drawingboard/image/wrong.png


+ 68 - 0
drawingboard-master/drawingboard/index.html

@@ -0,0 +1,68 @@
+<html>
+
+<head>
+    <meta charset="UTF-8">
+    <title>高级画板程序(canvas) - 授课系统</title>
+    <link rel="stylesheet" href="css/index.css">
+</head>
+
+<body style="background-color: #E5E4E5;;overflow-x: hidden;">
+
+    <div style="margin-top:10px;">
+        <div style="width:50px;float:left;">
+            <ul id="toolsul" class="tools">
+                <li id="toolsPencil" data-type="pen" class="active">
+                    <i class="icon-tools icon-pen-select" data-default='icon-tools icon-pen-black'></i>
+                </li>
+                <li data-type="arrow">
+                    <i class="icon-tools icon-arrow-black" data-default='icon-tools icon-arrow-black'></i>
+                </li>
+                <li data-type="line">
+                    <i class="icon-tools icon-line-black" data-default='icon-tools icon-line-black'></i>
+                </li>
+                <li data-type="dottedline">
+                    <i class="icon-tools icon-dottedline-black" data-default='icon-tools icon-dottedline-black'></i>
+                </li>
+                <li data-type="circle">
+                    <i class="icon-tools icon-circle-black" data-default='icon-tools icon-circle-black'></i>
+                </li>
+                <li data-type="ellipse">
+                    <i class="icon-tools icon-ellipse-black" data-default='icon-tools icon-ellipse-black'></i>
+                </li>
+                <li class="hide" data-type="square">
+                    <i class="icon-tools icon-square-black" data-default='icon-tools icon-square-black'></i>
+                </li>
+                <li data-type="rectangle">
+                    <i class="icon-tools icon-rectangle-black" data-default='icon-tools icon-rectangle-black'></i>
+                </li>
+                <li data-type="rightangle">
+                    <i class="icon-tools icon-rightangle-black" data-default='icon-tools icon-rightangle-black'></i>
+                </li>
+                <li data-type="equilateral">
+                    <i class="icon-tools icon-equilateral-black" data-default='icon-tools icon-equilateral-black'></i>
+                </li>
+                <li class="hide" data-type="isosceles">
+                    <i class="icon-tools icon-isosceles-black" data-default='icon-tools icon-isosceles-black'></i>
+                </li>
+                <li data-type="text">
+                    <i class="icon-tools icon-text-black" data-default='icon-tools icon-text-black'></i>
+                </li>
+                <li data-type="remove">
+                    <i class="icon-tools icon-remove-black" data-default='icon-tools icon-remove-black'></i>
+                </li>
+            </ul>
+
+        </div>
+        <div id="canvasDiv" class="canvasDiv" style="width:95%;">
+            <canvas id="c" width="1920" height="1080">请使用支持HTML5的浏览器</canvas>
+        </div>
+    </div>
+
+    <script src="https://cdn.bootcss.com/jquery/1.9.1/jquery.min.js"></script>
+    <script src="https://cdn.bootcss.com/fabric.js/2.1.0/fabric.min.js"></script>
+    <script src="js/demo.js"></script>
+    <script src="js/canvasZoom.js"></script>
+
+</body>
+
+</html>

+ 47 - 0
drawingboard-master/drawingboard/js/canvasZoom.js

@@ -0,0 +1,47 @@
+//配置
+var config = function() {
+  return {
+    height: 1080, //默认画板高、宽
+    width: 1920,
+    canvasParentId: "canvasDiv",
+    canvasId: "c"
+  };
+};
+
+//初次设置画板
+(function() {
+  setZoom(window.canvas);
+})();
+
+//设置缩放
+function setZoom(canvas) {
+  var canvasDiv = jQuery("#" + config().canvasParentId);
+  var zoom = 1;
+  var eleHeight = canvasDiv.height(),
+    eleWidth = canvasDiv.width(),
+    cHeight = canvas.height,
+    cWidth = canvas.width;
+  var height = eleHeight > cHeight ? eleHeight : cHeight;
+  var width = eleWidth > cWidth ? eleWidth : cWidth;
+  if (width > height) {
+    //横版
+    width = eleWidth;
+    height = eleHeight;
+    zoom = width / config().width;
+  } else {
+    //竖版
+    height = height * eleHeight / config().height * 0.8;
+    zoom = height / config().height;
+  }
+  canvas.setZoom(zoom);
+  canvas.setWidth(width);
+  canvas.setHeight(height);
+
+  window.zoom = zoom;
+  canvas.renderAll();
+}
+
+//监听窗体变化
+window.onresize = function() {
+  setZoom(window.canvas);
+};

+ 305 - 0
drawingboard-master/drawingboard/js/check-bak.js

@@ -0,0 +1,305 @@
+(function () {
+  //变量声明
+  var mouseFrom = {},
+    mouseTo = {},
+    drawType = 'right', //画板绘制类型
+    canvasObjectIndex = 0,
+    textbox = null;
+  var drawWidth = 2; //笔触宽度
+  var color = "#E34F51"; //画笔颜色
+  var drawingObject = null; //当前绘制对象
+  var moveCount = 1; //绘制移动计数器
+  var doDrawing = false; // 绘制状态
+  var rightColor = "#006400", wrongColor = "#E34F51";
+
+  //初始化画板
+  var canvas = new fabric.Canvas("c", {
+    isDrawingMode: false,
+    skipTargetFind: true,
+    selectable: false,
+    selection: false
+  });
+
+  fabric.Image.fromURL('http://icdn.apigo.cn/paper.png?1', function (img) {
+    canvas.add(img);
+  }, { crossOrigin: 'anonymous' });
+
+  window.canvas = canvas;
+  window.zoom = window.zoom ? window.zoom : 1;
+  window.drawType = drawType;
+
+  canvas.freeDrawingBrush.color = color; //设置自由绘颜色
+  canvas.freeDrawingBrush.width = drawWidth;
+
+  //绑定画板事件
+  canvas.on("mouse:down", function (options) {
+    var xy = transformMouse(options.e.offsetX, options.e.offsetY);
+    mouseFrom.x = xy.x;
+    mouseFrom.y = xy.y;
+    doDrawing = true;
+  });
+  canvas.on("mouse:up", function (options) {
+    var xy = transformMouse(options.e.offsetX, options.e.offsetY);
+    mouseTo.x = xy.x;
+    mouseTo.y = xy.y;
+    drawing();
+    drawingObject = null;
+    moveCount = 1;
+    doDrawing = false;
+  });
+  canvas.on("mouse:move", function (options) {
+    if (moveCount % 2 && !doDrawing) {
+      //减少绘制频率
+      return;
+    }
+    moveCount++;
+    var xy = transformMouse(options.e.offsetX, options.e.offsetY);
+    mouseTo.x = xy.x;
+    mouseTo.y = xy.y;
+    drawing();
+  });
+
+  canvas.on("selection:created", function (e) {
+    if (e.target._objects) {
+      //多选删除
+      var etCount = e.target._objects.length;
+      for (var etindex = 0; etindex < etCount; etindex++) {
+        if (e.target._objects[etindex].type == "image") {
+          continue;
+        }
+        canvas.remove(e.target._objects[etindex]);
+      }
+    } else {
+      //单选删除
+      if (e.target.type != "image") {
+        canvas.remove(e.target);
+      }
+    }
+    canvas.discardActiveObject(); //清楚选中框
+  });
+
+  //坐标转换
+  function transformMouse(mouseX, mouseY) {
+    return { x: mouseX / window.zoom, y: mouseY / window.zoom };
+  }
+
+  //绑定工具事件
+  jQuery("#toolsul")
+    .find("li")
+    .on("click", function () {
+      //设置样式
+      jQuery("#toolsul")
+        .find("li>i")
+        .each(function () {
+          jQuery(this).attr("class", jQuery(this).attr("data-default"));
+        });
+      jQuery(this)
+        .addClass("active")
+        .siblings()
+        .removeClass("active");
+      jQuery(this)
+        .find("i")
+        .attr(
+          "class",
+          jQuery(this)
+            .find("i")
+            .attr("class")
+            .replace("black", "select")
+        );
+      drawType = jQuery(this).attr("data-type");
+      window.drawType = drawType;
+      canvas.isDrawingMode = false;
+      if (textbox) {
+        //退出文本编辑状态
+        textbox.exitEditing();
+        textbox = null;
+      }
+      if (drawType == "pen") {
+        canvas.isDrawingMode = true;
+      } else if (drawType == "remove") {
+        canvas.selection = true;
+        canvas.skipTargetFind = false;
+        canvas.selectable = true;
+      } else {
+        canvas.skipTargetFind = true; //画板元素不能被选中
+        canvas.selection = false; //画板不显示选中
+      }
+    });
+
+  //绘画方法
+  function drawing() {
+    if (drawingObject) {
+      canvas.remove(drawingObject);
+    }
+    var canvasObject = null;
+    switch (drawType) {
+      case "arrow": //箭头
+        canvasObject = new fabric.Path(drawArrow(mouseFrom.x, mouseFrom.y, mouseTo.x, mouseTo.y, 30, 30), {
+          stroke: color,
+          fill: "rgba(255,255,255,0)",
+          strokeWidth: drawWidth
+        });
+        break;
+      case "line": //直线
+        canvasObject = new fabric.Line([mouseFrom.x, mouseFrom.y, mouseTo.x, mouseTo.y], {
+          stroke: color,
+          strokeWidth: drawWidth
+        });
+        break;
+      case "dottedline": //虚线
+        canvasObject = new fabric.Line([mouseFrom.x, mouseFrom.y, mouseTo.x, mouseTo.y], {
+          strokeDashArray: [3, 1],
+          stroke: color,
+          strokeWidth: drawWidth
+        });
+        break;
+      case "text":
+        textbox = new fabric.Textbox("", {
+          left: mouseFrom.x - 60,
+          top: mouseFrom.y - 20,
+          width: 150,
+          fontSize: 18,
+          borderColor: "#2c2c2c",
+          fill: color,
+          hasControls: false
+        });
+        canvas.add(textbox);
+        textbox.enterEditing();
+        textbox.hiddenTextarea.focus();
+        break;
+      case 'right': //整题正确
+        var step = 30;
+        var path =
+          "M " +
+          (mouseFrom.x - step) +
+          " " +
+          (mouseFrom.y - step) +
+          " L " +
+          mouseFrom.x +
+          " " +
+          mouseFrom.y +
+          " L " +
+          (mouseFrom.x + step * 2) +
+          " " +
+          (mouseFrom.y - step * 2);
+        canvasObject = new fabric.Path(path, {
+          stroke: rightColor,
+          strokeWidth: drawWidth,
+          fill: "rgba(255, 255, 255, 0)"
+        });
+        break;
+      case 'wrong': //整题错误
+        var step = 30;
+        var path =
+          "M " +
+          (mouseFrom.x - step) +
+          " " +
+          (mouseFrom.y - step) +
+          " L " +
+          (mouseFrom.x + step) +
+          " " +
+          (mouseFrom.y + step) +
+          "M " +
+          (mouseFrom.x + step) +
+          " " +
+          (mouseFrom.y - step) +
+          " L " +
+          (mouseFrom.x - step) +
+          " " +
+          (mouseFrom.y + step);
+        canvasObject = new fabric.Path(path, {
+          stroke: wrongColor,
+          strokeWidth: drawWidth,
+          fill: "rgba(255, 255, 255, 0)"
+        });
+        break;
+      case 'smallright': //题目内单个正确
+        var step = 10;
+        var path =
+          "M " +
+          (mouseFrom.x - step) +
+          " " +
+          (mouseFrom.y - step) +
+          " L " +
+          mouseFrom.x +
+          " " +
+          mouseFrom.y +
+          " L " +
+          (mouseFrom.x + step * 2) +
+          " " +
+          (mouseFrom.y - step * 2);
+        canvasObject = new fabric.Path(path, {
+          stroke: rightColor,
+          strokeWidth: drawWidth,
+          fill: "rgba(255, 255, 255, 0)"
+        });
+        break;
+      case 'smallwrong': //题目内单个错误
+        var step = 10;
+        var path =
+          "M " +
+          (mouseFrom.x - step) +
+          " " +
+          (mouseFrom.y - step) +
+          " L " +
+          (mouseFrom.x + step) +
+          " " +
+          (mouseFrom.y + step) +
+          "M " +
+          (mouseFrom.x + step) +
+          " " +
+          (mouseFrom.y - step) +
+          " L " +
+          (mouseFrom.x - step) +
+          " " +
+          (mouseFrom.y + step);
+        canvasObject = new fabric.Path(path, {
+          stroke: wrongColor,
+          strokeWidth: drawWidth,
+          fill: "rgba(255, 255, 255, 0)"
+        });
+        break;
+      case "remove":
+        break;
+      default:
+        break;
+    }
+    if (canvasObject) {
+      // canvasObject.index = getCanvasObjectIndex();
+      canvasObject.type = drawType;
+      canvas.add(canvasObject); //.setActiveObject(canvasObject)
+      drawingObject = canvasObject;
+    }
+  }
+
+  //绘制箭头方法
+  function drawArrow(fromX, fromY, toX, toY, theta, headlen) {
+    theta = typeof theta != "undefined" ? theta : 30;
+    headlen = typeof theta != "undefined" ? headlen : 10;
+    // 计算各角度和对应的P2,P3坐标
+    var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI,
+      angle1 = (angle + theta) * Math.PI / 180,
+      angle2 = (angle - theta) * Math.PI / 180,
+      topX = headlen * Math.cos(angle1),
+      topY = headlen * Math.sin(angle1),
+      botX = headlen * Math.cos(angle2),
+      botY = headlen * Math.sin(angle2);
+    var arrowX = fromX - topX,
+      arrowY = fromY - topY;
+    var path = " M " + fromX + " " + fromY;
+    path += " L " + toX + " " + toY;
+    arrowX = toX + topX;
+    arrowY = toY + topY;
+    path += " M " + arrowX + " " + arrowY;
+    path += " L " + toX + " " + toY;
+    arrowX = toX + botX;
+    arrowY = toY + botY;
+    path += " L " + arrowX + " " + arrowY;
+    return path;
+  }
+
+  //获取画板对象的下标
+  function getCanvasObjectIndex() {
+    return canvasObjectIndex++;
+  }
+})();

+ 269 - 0
drawingboard-master/drawingboard/js/check/canvas.js

@@ -0,0 +1,269 @@
+//变量声明
+var mouseFrom = {},
+  mouseTo = {},
+  drawType = 'right', //画板绘制类型
+  canvasObjectIndex = 0;
+var drawWidth = 2; //笔触宽度
+var modifySize = 20, modifySmallSize = 10; //大/小 | 对/错画笔直径大小
+var color = "#E34F51"; //画笔颜色
+var drawingObject = null; //当前绘制对象
+var moveCount = 1; //绘制移动计数器
+var doDrawing = false; // 绘制状态
+var rightColor = "#008B00", wrongColor = "#E34F51";
+// var modifyImg = null;//当前批改的图片
+var appErrCount = 0;//全局错误个数
+var errTextBoxArray = new Array();
+var canvasArr = [];  //所有(fabric产生)的canvas对象
+
+
+//切换画板
+function switchCanvas(url, index) {
+  var canvasId = "c" + index;
+  jQuery("#canvasDiv").find("div").addClass("fn-hide");
+  jQuery("#canvasDiv").find("div").eq(index).removeClass("fn-hide");
+  if (canvasArr[index]) {
+    //canvas已经存在
+    window.canvas = canvasArr[index];
+    return false;
+  }
+  var canvas = new fabric.Canvas(canvasId, {
+    isDrawingMode: false,
+    skipTargetFind: true,
+    selectable: false,
+    selection: false
+  });
+  fabric.Image.fromURL(url, function (img) {
+    canvas.add(img);
+  }, { crossOrigin: 'anonymous' });
+  canvasArr[index] = canvas;
+  canvas.freeDrawingBrush.color = color; //设置自由绘颜色
+  canvas.freeDrawingBrush.width = drawWidth;
+  window.canvas = canvas;
+
+  //绑定画板事件
+  canvas.on("mouse:down", function (options) {
+    var xy = transformMouse(options.e.offsetX, options.e.offsetY);
+    mouseFrom.x = xy.x;
+    mouseFrom.y = xy.y;
+    doDrawing = true;
+  });
+  canvas.on("mouse:up", function (options) {
+    var xy = transformMouse(options.e.offsetX, options.e.offsetY);
+    mouseTo.x = xy.x;
+    mouseTo.y = xy.y;
+    drawing();
+    drawingObject = null;
+    moveCount = 1;
+    doDrawing = false;
+    if (drawType.indexOf("wrong") != -1) {
+      //有错题
+      jQuery("#errModal").removeClass("fn-hide");
+      jQuery("#errModal").find("div[name=etag]").removeClass("active");
+      ++appErrCount;
+      var addLeft = 10, addTop = 25;
+      if (drawType == "wrong") {
+        addLeft = 25;
+        addTop = 30;
+      }
+      var textbox = new fabric.Textbox(appErrCount.toString(), {
+        left: mouseFrom.x + addLeft,
+        top: mouseFrom.y - addTop,
+        fontSize: 18,
+        borderColor: "#2c2c2c",
+        fill: color,
+        hasControls: false,
+        eindex: (appErrCount - 1),
+        type: "textbox"
+      });
+      canvas.add(textbox);
+      errTextBoxArray[appErrCount] = textbox;
+    }
+  });
+  canvas.on("mouse:move", function (options) {
+    if (moveCount % 2 && !doDrawing) {
+      //减少绘制频率
+      return;
+    }
+    moveCount++;
+    var xy = transformMouse(options.e.offsetX, options.e.offsetY);
+    mouseTo.x = xy.x;
+    mouseTo.y = xy.y;
+    drawing();
+  });
+  canvas.on("selection:created", function (e) {
+    if (e.target._objects) {
+      //多选删除
+      var etCount = e.target._objects.length;
+      for (var etindex = 0; etindex < etCount; etindex++) {
+        if (e.target._objects[etindex].type == "image" || e.target._objects[etindex].type == "textbox") {
+          continue;
+        }
+        var eindex = e.target._objects[etindex].eindex;
+        canvas.remove(errTextBoxArray[(1 + eindex)]); //移除对应右上角的数字
+        delete errTextBoxArray[(1 + eindex)];
+
+        canvas.remove(e.target._objects[etindex]);
+
+        //移除作业批注
+        var errMsgChildren = jQuery("#errMsg").children();
+        errMsgChildren.eq(errMsgChildren.length - 1 - eindex).addClass("fn-hide");
+      }
+    } else {
+      //单选删除
+      if (e.target.type != "image" && e.target.type != "textbox") {
+        var eindex = e.target.eindex;
+        canvas.remove(errTextBoxArray[(1 + eindex)]); //移除对应右上角的数字
+        delete errTextBoxArray[(1 + eindex)];
+        canvas.remove(e.target);
+
+        //移除作业批注
+        var errMsgChildren = jQuery("#errMsg").children();
+        errMsgChildren.eq(errMsgChildren.length - 1 - eindex).addClass("fn-hide");
+
+      }
+    }
+    canvas.discardActiveObject(); //清楚选中框
+  });
+
+
+}
+
+window.zoom = window.zoom ? window.zoom : 1;
+// window.drawType = drawType;
+
+//坐标转换
+function transformMouse(mouseX, mouseY) {
+  return { x: mouseX / window.zoom, y: mouseY / window.zoom };
+}
+
+//绘画方法
+function drawing() {
+  if (drawingObject) {
+    canvas.remove(drawingObject);
+  }
+  var canvasObject = null;
+  switch (drawType) {
+    case 'right': //整题正确
+      var path =
+        "M " +
+        (mouseFrom.x - modifySize) +
+        " " +
+        (mouseFrom.y - modifySize) +
+        " L " +
+        mouseFrom.x +
+        " " +
+        mouseFrom.y +
+        " L " +
+        (mouseFrom.x + modifySize * 2) +
+        " " +
+        (mouseFrom.y - modifySize * 2);
+      canvasObject = new fabric.Path(path, {
+        stroke: rightColor,
+        strokeWidth: drawWidth,
+        fill: "rgba(255, 255, 255, 0)"
+      });
+      break;
+    case 'wrong': //整题错误
+      var path =
+        "M " +
+        (mouseFrom.x - modifySize) +
+        " " +
+        (mouseFrom.y - modifySize) +
+        " L " +
+        (mouseFrom.x + modifySize) +
+        " " +
+        (mouseFrom.y + modifySize) +
+        "M " +
+        (mouseFrom.x + modifySize) +
+        " " +
+        (mouseFrom.y - modifySize) +
+        " L " +
+        (mouseFrom.x - modifySize) +
+        " " +
+        (mouseFrom.y + modifySize);
+      canvasObject = new fabric.Path(path, {
+        stroke: wrongColor,
+        strokeWidth: drawWidth,
+        eindex: appErrCount,
+        fill: "rgba(255, 255, 255, 0)"
+      });
+
+      // canvas.add();
+      break;
+    case 'smallright': //题目内单个正确
+      var path =
+        "M " +
+        (mouseFrom.x - modifySmallSize) +
+        " " +
+        (mouseFrom.y - modifySmallSize) +
+        " L " +
+        mouseFrom.x +
+        " " +
+        mouseFrom.y +
+        " L " +
+        (mouseFrom.x + modifySmallSize * 2) +
+        " " +
+        (mouseFrom.y - modifySmallSize * 2);
+      canvasObject = new fabric.Path(path, {
+        stroke: rightColor,
+        strokeWidth: drawWidth,
+        fill: "rgba(255, 255, 255, 0)"
+      });
+      break;
+    case 'smallwrong': //题目内单个错误
+      var path =
+        "M " +
+        (mouseFrom.x - modifySmallSize) +
+        " " +
+        (mouseFrom.y - modifySmallSize) +
+        " L " +
+        (mouseFrom.x + modifySmallSize) +
+        " " +
+        (mouseFrom.y + modifySmallSize) +
+        "M " +
+        (mouseFrom.x + modifySmallSize) +
+        " " +
+        (mouseFrom.y - modifySmallSize) +
+        " L " +
+        (mouseFrom.x - modifySmallSize) +
+        " " +
+        (mouseFrom.y + modifySmallSize);
+      canvasObject = new fabric.Path(path, {
+        stroke: wrongColor,
+        strokeWidth: drawWidth,
+        eindex: appErrCount,
+        fill: "rgba(255, 255, 255, 0)"
+      });
+      break;
+    case "rectangle": //圈题
+      canvasObject = new fabric.Rect({
+        top: mouseFrom.y,
+        left: mouseFrom.x,
+        width: (mouseTo.x - mouseFrom.x),
+        height: (mouseTo.y - mouseFrom.y),
+        stroke: color,
+        strokeWidth: drawWidth,
+        fill: "rgba(255, 255, 255, 0)"
+      });
+      break;
+    case "remove":
+      break;
+    case "help":
+
+      break;
+    default:
+
+      break;
+  }
+  if (canvasObject) {
+    // canvasObject.index = getCanvasObjectIndex();
+    canvasObject.type = drawType;
+    canvas.add(canvasObject); //.setActiveObject(canvasObject)
+    drawingObject = canvasObject;
+  }
+}
+
+//获取画板对象的下标
+function getCanvasObjectIndex() {
+  return canvasObjectIndex++;
+}

+ 9 - 0
drawingboard-master/drawingboard/js/check/config.js

@@ -0,0 +1,9 @@
+/**
+ * 服务器地址
+ */
+var config = {
+    tokenURL: 'http://172.16.10.79:8360/qiniu/gettoken',
+    checkURL: 'http://third.172.16.11.49.xip.io/wq.php/record/correct',
+    imgDomain: 'http://img.yousi.com/',  //图片域名
+    callbackURL: 'http://172.16.10.78:7777/index/content/homework_main.html'
+};

+ 17 - 0
drawingboard-master/drawingboard/js/check/fontsize.js

@@ -0,0 +1,17 @@
+(function (doc, win) {
+    var docEl = doc.documentElement,
+        resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
+        recalc = function () {
+            var clientWidth = docEl.clientWidth;
+            if (!clientWidth) return;
+            if(clientWidth>=3200){
+                docEl.style.fontSize = '100px';
+            }else{
+                docEl.style.fontSize = 100 * (clientWidth / 3200) + 'px';
+            }
+        };
+
+    if (!doc.addEventListener) return;
+    win.addEventListener(resizeEvt, recalc, false);
+    doc.addEventListener('DOMContentLoaded', recalc, false);
+})(document, window);

Файловите разлики са ограничени, защото са твърде много
+ 0 - 0
drawingboard-master/drawingboard/js/check/qiniu.min.js


+ 287 - 0
drawingboard-master/drawingboard/js/demo.js

@@ -0,0 +1,287 @@
+(function () {
+  //变量声明
+  var mouseFrom = {},
+    mouseTo = {},
+    drawType = null,
+    canvasObjectIndex = 0,
+    textbox = null;
+  var drawWidth = 2; //笔触宽度
+  var color = "#E34F51"; //画笔颜色
+  var drawingObject = null; //当前绘制对象
+  var moveCount = 1; //绘制移动计数器
+  var doDrawing = false; // 绘制状态
+
+  //初始化画板
+  var canvas = new fabric.Canvas("c", {
+    isDrawingMode: true,
+    skipTargetFind: true,
+    selectable: false,
+    selection: false
+  });
+
+  window.canvas = canvas;
+  window.zoom = window.zoom ? window.zoom : 1;
+
+  canvas.freeDrawingBrush.color = color; //设置自由绘颜色
+  canvas.freeDrawingBrush.width = drawWidth;
+
+  //绑定画板事件
+  canvas.on("mouse:down", function (options) {
+    var xy = transformMouse(options.e.offsetX, options.e.offsetY);
+    mouseFrom.x = xy.x;
+    mouseFrom.y = xy.y;
+    doDrawing = true;
+  });
+  canvas.on("mouse:up", function (options) {
+    var xy = transformMouse(options.e.offsetX, options.e.offsetY);
+    mouseTo.x = xy.x;
+    mouseTo.y = xy.y;
+    // drawing();
+    drawingObject = null;
+    moveCount = 1;
+    doDrawing = false;
+  });
+  canvas.on("mouse:move", function (options) {
+    if (moveCount % 2 && !doDrawing) {
+      //减少绘制频率
+      return;
+    }
+    moveCount++;
+    var xy = transformMouse(options.e.offsetX, options.e.offsetY);
+    mouseTo.x = xy.x;
+    mouseTo.y = xy.y;
+    drawing();
+  });
+
+  canvas.on("selection:created", function (e) {
+    if (e.target._objects) {
+      //多选删除
+      var etCount = e.target._objects.length;
+      for (var etindex = 0; etindex < etCount; etindex++) {
+        canvas.remove(e.target._objects[etindex]);
+      }
+    } else {
+      //单选删除
+      canvas.remove(e.target);
+    }
+    canvas.discardActiveObject(); //清楚选中框
+  });
+
+  //坐标转换
+  function transformMouse(mouseX, mouseY) {
+    return { x: mouseX / window.zoom, y: mouseY / window.zoom };
+  }
+
+  //绑定工具事件
+  jQuery("#toolsul")
+    .find("li")
+    .on("click", function () {
+      //设置样式
+      jQuery("#toolsul")
+        .find("li>i")
+        .each(function () {
+          jQuery(this).attr("class", jQuery(this).attr("data-default"));
+        });
+      jQuery(this)
+        .addClass("active")
+        .siblings()
+        .removeClass("active");
+      jQuery(this)
+        .find("i")
+        .attr(
+          "class",
+          jQuery(this)
+            .find("i")
+            .attr("class")
+            .replace("black", "select")
+        );
+      drawType = jQuery(this).attr("data-type");
+      canvas.isDrawingMode = false;
+      if (textbox) {
+        //退出文本编辑状态
+        textbox.exitEditing();
+        textbox = null;
+      }
+      if (drawType == "pen") {
+        canvas.isDrawingMode = true;
+      } else if (drawType == "remove") {
+        canvas.selection = true;
+        canvas.skipTargetFind = false;
+        canvas.selectable = true;
+      } else {
+        canvas.skipTargetFind = true; //画板元素不能被选中
+        canvas.selection = false; //画板不显示选中
+      }
+    });
+
+  //绘画方法
+  function drawing() {
+    if (drawingObject) {
+      canvas.remove(drawingObject);
+    }
+    var canvasObject = null;
+    switch (drawType) {
+      case "arrow": //箭头
+        canvasObject = new fabric.Path(drawArrow(mouseFrom.x, mouseFrom.y, mouseTo.x, mouseTo.y, 30, 30), {
+          stroke: color,
+          fill: "rgba(255,255,255,0)",
+          strokeWidth: drawWidth
+        });
+        break;
+      case "line": //直线
+        canvasObject = new fabric.Line([mouseFrom.x, mouseFrom.y, mouseTo.x, mouseTo.y], {
+          stroke: color,
+          strokeWidth: drawWidth
+        });
+        break;
+      case "dottedline": //虚线
+        canvasObject = new fabric.Line([mouseFrom.x, mouseFrom.y, mouseTo.x, mouseTo.y], {
+          strokeDashArray: [3, 1],
+          stroke: color,
+          strokeWidth: drawWidth
+        });
+        break;
+      case "circle": //正圆
+        var left = mouseFrom.x,
+          top = mouseFrom.y;
+        var radius = Math.sqrt((mouseTo.x - left) * (mouseTo.x - left) + (mouseTo.y - top) * (mouseTo.y - top)) / 2;
+        canvasObject = new fabric.Circle({
+          left: left,
+          top: top,
+          stroke: color,
+          fill: "rgba(255, 255, 255, 0)",
+          radius: radius,
+          strokeWidth: drawWidth
+        });
+        break;
+      case "ellipse": //椭圆
+        var left = mouseFrom.x,
+          top = mouseFrom.y;
+        var radius = Math.sqrt((mouseTo.x - left) * (mouseTo.x - left) + (mouseTo.y - top) * (mouseTo.y - top)) / 2;
+        canvasObject = new fabric.Ellipse({
+          left: left,
+          top: top,
+          stroke: color,
+          fill: "rgba(255, 255, 255, 0)",
+          originX: "center",
+          originY: "center",
+          rx: Math.abs(left - mouseTo.x),
+          ry: Math.abs(top - mouseTo.y),
+          strokeWidth: drawWidth
+        });
+        break;
+      case "square": //TODO:正方形(后期完善)
+        break;
+      case "rectangle": //长方形
+        var path =
+          "M " +
+          mouseFrom.x +
+          " " +
+          mouseFrom.y +
+          " L " +
+          mouseTo.x +
+          " " +
+          mouseFrom.y +
+          " L " +
+          mouseTo.x +
+          " " +
+          mouseTo.y +
+          " L " +
+          mouseFrom.x +
+          " " +
+          mouseTo.y +
+          " L " +
+          mouseFrom.x +
+          " " +
+          mouseFrom.y +
+          " z";
+        canvasObject = new fabric.Path(path, {
+          left: left,
+          top: top,
+          stroke: color,
+          strokeWidth: drawWidth,
+          fill: "rgba(255, 255, 255, 0)"
+        });
+        //也可以使用fabric.Rect
+        break;
+      case "rightangle": //直角三角形
+        var path = "M " + mouseFrom.x + " " + mouseFrom.y + " L " + mouseFrom.x + " " + mouseTo.y + " L " + mouseTo.x + " " + mouseTo.y + " z";
+        canvasObject = new fabric.Path(path, {
+          left: left,
+          top: top,
+          stroke: color,
+          strokeWidth: drawWidth,
+          fill: "rgba(255, 255, 255, 0)"
+        });
+        break;
+      case "equilateral": //等边三角形
+        var height = mouseTo.y - mouseFrom.y;
+        canvasObject = new fabric.Triangle({
+          top: mouseFrom.y,
+          left: mouseFrom.x,
+          width: Math.sqrt(Math.pow(height, 2) + Math.pow(height / 2.0, 2)),
+          height: height,
+          stroke: color,
+          strokeWidth: drawWidth,
+          fill: "rgba(255,255,255,0)"
+        });
+        break;
+      case "isosceles":
+        break;
+      case "text":
+        textbox = new fabric.Textbox("", {
+          left: mouseFrom.x - 60,
+          top: mouseFrom.y - 20,
+          width: 150,
+          fontSize: 18,
+          borderColor: "#2c2c2c",
+          fill: color,
+          hasControls: false
+        });
+        canvas.add(textbox);
+        textbox.enterEditing();
+        textbox.hiddenTextarea.focus();
+        break;
+      case "remove":
+        break;
+      default:
+        break;
+    }
+    if (canvasObject) {
+      // canvasObject.index = getCanvasObjectIndex();
+      canvas.add(canvasObject); //.setActiveObject(canvasObject)
+      drawingObject = canvasObject;
+    }
+  }
+
+  //绘制箭头方法
+  function drawArrow(fromX, fromY, toX, toY, theta, headlen) {
+    theta = typeof theta != "undefined" ? theta : 30;
+    headlen = typeof theta != "undefined" ? headlen : 10;
+    // 计算各角度和对应的P2,P3坐标
+    var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI,
+      angle1 = (angle + theta) * Math.PI / 180,
+      angle2 = (angle - theta) * Math.PI / 180,
+      topX = headlen * Math.cos(angle1),
+      topY = headlen * Math.sin(angle1),
+      botX = headlen * Math.cos(angle2),
+      botY = headlen * Math.sin(angle2);
+    var arrowX = fromX - topX,
+      arrowY = fromY - topY;
+    var path = " M " + fromX + " " + fromY;
+    path += " L " + toX + " " + toY;
+    arrowX = toX + topX;
+    arrowY = toY + topY;
+    path += " M " + arrowX + " " + arrowY;
+    path += " L " + toX + " " + toY;
+    arrowX = toX + botX;
+    arrowY = toY + botY;
+    path += " L " + arrowX + " " + arrowY;
+    return path;
+  }
+
+  //获取画板对象的下标
+  function getCanvasObjectIndex() {
+    return canvasObjectIndex++;
+  }
+})();

Файловите разлики са ограничени, защото са твърде много
+ 0 - 0
drawingboard-master/drawingboard/js/fabric.min.js


Файловите разлики са ограничени, защото са твърде много
+ 1 - 0
drawingboard-master/drawingboard/js/jquery.min.js


Файловите разлики са ограничени, защото са твърде много
+ 0 - 0
drawingboard-master/drawingboard/js/tools/md5.min.js


+ 109 - 0
drawingboard-master/drawingboard/js/tools/upload.js

@@ -0,0 +1,109 @@
+//图片上传 (uploadImageArray = [{"name":"xxx","base64":"xxx"}])
+function uploadImg(uploadImageArray, qiniuToken) {
+    if (uploadImageArray && uploadImageArray.length > 0 && qiniuToken) {
+        //上传,返回地址
+        var putExtra = {
+            fname: "",
+            params: {},
+            mimeType: [] || null
+        };
+        var config = {
+            useCdnDomain: true
+        };
+        window.WinSuccCount = 0;
+        window.WinUploadImgCount = uploadImageArray.length;
+        for (var i = 0; i < uploadImageArray.length; i++) {
+            doUpload(uploadImageArray[i].name, uploadImageArray[i].base64.replace('data:image/png;base64,', ''), qiniuToken);
+        }
+    }
+}
+
+//图片上传七牛云
+function doUpload(name, base64, qiniuToken) {
+    //图片上传(base64模式直传)
+    var urlkey = toBase64(name); //自定义文件名必须是base64格式的
+    var url = "http://upload.qiniup.com/putb64/-1/key/" + urlkey; //非华东空间需要根据注意事项-修改上传域名(upload.qiniup.com)
+    var xhr = new XMLHttpRequest();
+    xhr.onreadystatechange = function () {
+        if (xhr.readyState == 4) {
+            //返回信息
+            console.log(xhr.responseText);
+
+            //检测是否上传完毕,提交请求给服务器
+            ++window.WinSuccCount;
+            if (window.WinUploadImgCount == window.WinSuccCount) {
+                reqCheckServer();
+                window.WinSuccCount = 0;
+                window.WinUploadImgCount = 0;
+            }
+        }
+    }
+    xhr.open("POST", url, true);
+    xhr.setRequestHeader("Content-Type", "application/octet-stream");
+    xhr.setRequestHeader("Authorization", "UpToken " + qiniuToken);
+    xhr.send(base64);
+}
+
+//提交作业批改(php)
+function reqCheckServer() {
+    if (window.checkJson) {
+        // prompt("最终结果", window.checkJson);
+        jQuery.ajax({
+            type: "POST",
+            url: config.checkURL,
+            data: { "param": window.checkJson },
+            success: function (res) {
+                location.href = config.callbackURL;
+                console.log(res);
+            }
+        });
+        jQuery("#maskDiv").hide();
+    }
+}
+
+function toBase64(data) {
+    var toBase64Table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+    var base64Pad = '=';
+    var result = '';
+    var length = data.length;
+    var i;
+    for (i = 0; i < (length - 2); i += 3) {
+        result += toBase64Table[data.charCodeAt(i) >> 2];
+        result += toBase64Table[((data.charCodeAt(i) & 0x03) << 4) + (data.charCodeAt(i + 1) >> 4)];
+        result += toBase64Table[((data.charCodeAt(i + 1) & 0x0f) << 2) + (data.charCodeAt(i + 2) >> 6)];
+        result += toBase64Table[data.charCodeAt(i + 2) & 0x3f];
+    }
+    if (length % 3) {
+        i = length - (length % 3);
+        result += toBase64Table[data.charCodeAt(i) >> 2];
+        if ((length % 3) == 2) {
+            result += toBase64Table[((data.charCodeAt(i) & 0x03) << 4) + (data.charCodeAt(i + 1) >> 4)];
+            result += toBase64Table[(data.charCodeAt(i + 1) & 0x0f) << 2];
+            result += base64Pad;
+        } else {
+            result += toBase64Table[(data.charCodeAt(i) & 0x03) << 4];
+            result += base64Pad + base64Pad;
+        }
+    }
+    return result;
+}
+
+//base64转blob
+function base64ToBlob(base64, contentType, sliceSize) {
+    contentType = contentType || '';
+    sliceSize = sliceSize || 512;
+    var byteCharacters = atob(base64);
+    var byteArrays = [];
+
+    for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
+        var slice = byteCharacters.slice(offset, offset + sliceSize);
+        var byteNumbers = new Array(slice.length);
+        for (var i = 0; i < slice.length; i++) {
+            byteNumbers[i] = slice.charCodeAt(i);
+        }
+        var byteArray = new Uint8Array(byteNumbers);
+        byteArrays.push(byteArray);
+    }
+    var blob = new Blob(byteArrays, { type: contentType });
+    return blob;
+}

+ 5 - 0
drawingboard-master/drawingboard/js/tools/uuid.js

@@ -0,0 +1,5 @@
+/**
+ * 注意:这不是真正的GUID,无法在Javascript中生成真正的GUID,因为它们依赖于浏览器不公开的本地计算机的属性。
+ * 可以配合时间戳:md5(uuid.uuid() + new Date().getTime())重复性更小
+ */
+(function(){var _uuid={uuid:function(){var s=[];var hexDigits="0123456789abcdef";for(var i=0;i<36;i++){s[i]=hexDigits.substr(Math.floor(Math.random()*16),1)}s[14]="4";s[19]=hexDigits.substr((s[19]&3)|8,1);s[8]=s[13]=s[18]=s[23]="-";var uuid=s.join("");return uuid}};this.uuid=_uuid})();

+ 29 - 0
drawingboard-master/drawingboard/test.html

@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+    <meta charset="UTF-8">
+    <title>test页面</title>
+</head>
+
+<body>
+
+    <script type="text/javascript" src="../js/jquery.min.js"></script>
+    <script type="text/javascript" src="../js/check/qiniu.min.js"></script>
+
+    <button>提交</button>
+
+    <script>
+        jQuery.ajax({
+            type: "POST",
+            url: "http://third.172.16.11.49.xip.io/wq.php/Record/wrongQuestion",
+            data: { "roomid": "111" },
+            success: function (res) {
+                console.log(res);
+            }
+        });
+
+    </script>
+</body>
+
+</html>

+ 134 - 0
drawingboard-master/fabricjs使用笔记.md

@@ -0,0 +1,134 @@
+## 使用笔记 ##
+
+### 常用属性 ###
+canvas.isDrawingMode = true; 可以自由绘制<br>
+canvas.selectable = false; 控件不能被选择,不会被操作<br>
+canvas.selection = true; 画板显示选中<br>
+canvas.skipTargetFind = true; 整个画板元素不能被选中<br>
+canvas.freeDrawingBrush.color = "#E34F51" 设置自由绘画笔的颜色<br>
+freeDrawingBrush.width  自由绘笔触宽度<br>
+canvas.setZoom(2); 设置画板缩放比例
+
+----------
+
+### 方法 ###
+add(object) 添加<br>
+insertAt(object,index) 添加<br>
+remove(object) 移除<br>
+forEachObject 循环遍历 <br>
+getObjects() 获取所有对象<br>
+item(int) 获取子项<br>
+isEmpty() 判断是否空画板<br>
+size() 画板元素个数<br>
+contains(object) 查询是否包含某个元素<br>
+fabric.util.cos<br>
+fabric.util.sin<br>
+fabric.util.drawDashedLine  绘制虚线<br>
+getWidth() setWidth()<br>
+getHeight()?<br>
+clear() 清空<br>
+renderAll() 重绘<br>
+requestRenderAll() 请求重新渲染<br>
+rendercanvas() 重绘画板?<br>
+getCenter().top/left 获取中心坐标<br>
+toDatalessJSON() 画板信息序列化成最小的json<br>
+toJSON() 画板信息序列化成json<br>
+moveTo(object,index) 移动?<br>
+dispose() 释放?<br>
+setCursor() 设置手势图标<br>
+getSelectionContext()获取选中的context<br>
+getSelectionElement()获取选中的元素<br>
+getActiveObject() 获取选中的对象<br>
+getActiveObjects() 获取选中的多个对象<br>
+discardActiveObject()取消当前选中对象 <br>
+isType() 图片的类型?<br>
+setColor(color) = canvas.set("full","");<br>
+rotate() 设置旋转角度<br>
+setCoords() 设置坐标<br>
+
+----------
+
+### 事件 ###
+object:added<br>
+object:removed<br>
+object:modified<br>
+object:rotating<br>
+object:scaling<br>
+object:moving<br>
+object:selected 这个方法v2已经废弃,使用selection:created替代,多选不会触发<br>
+before:selection:cleared<br>
+selection:cleared<br>
+selection:updated<br>
+selection:created<br>
+path:created<br>
+mouse:down<br>
+mouse:move<br>
+mouse:up<br>
+mouse:over<br>
+mouse:out<br>
+mouse:dblclick<br>
+
+----------
+
+### IText的方法 ###
+selectAll() 选择全部<br>
+getSelectedText() 获取选中的文本<br>
+exitEditing() 退出编辑模式?<br>
+
+
+----------
+
+### 绘制直线 ###
+var line = new fabric.Line([10, 10, 100, 100], {<br>
+  fill: 'green',<br>
+  stroke: 'green',	//笔触颜色<br>
+  strokeWidth: 2,//笔触宽度<br>
+});<br>
+canvas.add(line);<br>
+
+----------
+
+### 绘制虚线 ###
+在绘制直线的基础上添加属性strokeDashArray:Array<br>
+example:<br>
+var line = new fabric.Line([10, 10, 100, 100], {<br>
+  fill: 'green',<br>
+  stroke: 'green',<br>
+  strokeDashArray:[3,1] <br>
+});<br>
+canvas.add(line);<br>
+
+strokeDashArray[a,b] =》 每隔a个像素空b个像素。<br>
+
+
+
+----------
+
+### 可绘制对象 ###
+fabric.Circle	圆<br>
+fabric.Ellipse	椭圆<br>
+fabric.Line 直线<br>
+fabric.Polygon<br>
+fabric.Polyline<br>
+fabric.Rect 矩形<br>
+fabric.Triangle 三角形<br>
+
+----------
+
+### 图片去掉选中边框和旋转,且只能移动,不可操作 ###
+oImg.hasControls = false; 只能移动不能(编辑)操作<br>
+oImg.hasBorders = false; 去掉边框,可以正常操作<br>
+hasRotatingPoint = false; 不能被旋转<br>
+hasRotatingPoint 控制旋转点不可见<br>
+scaleToHeight(value, absolute) 缩放图片高度到value
+scaleToWidth(value, absolute) 缩放图片宽度到value
+
+示例代码如下:
+
+    fabric.Image.fromURL("img.jpg", function (oImg) {
+    	img.scaleToHeight(400, false);  //缩放图片的高度到400
+    	img.scaleToWidth(400, false);   //缩放图片的宽度到400
+    	canvas.add(oImg);
+    	oImg.hasControls = oImg.hasBorders = false;
+    });
+

BIN
drawingboard-master/res/check.png


+ 11 - 0
drawingboard-master/res/作业批改传入参数.txt

@@ -0,0 +1,11 @@
+http://xxx/check.html?img=[{"i":"http://icdn.apigo.cn/paper.png","s":"http://icdn.apigo.cn/paper.png"},{"i":"http://photo.yousi.com/2018-06-12_5b1f6999d205c.png","s":"http://photo.yousi.com/2018-06-12_5b1f6999d205c.png"}]&subject=语文
+
+
+注意:img、subject的值需要encodeURIComponent编码。
+
+最终地址:
+http://172.16.10.79:4001/check.html?img=%5B%7B%22i%22%3A%22http%3A%2F%2Ficdn.apigo.cn%2Fpaper.png%22%2C%22s%22%3A%22http%3A%2F%2Ficdn.apigo.cn%2Fpaper.png%22%7D%2C%7B%22i%22%3A%22http%3A%2F%2Fphoto.yousi.com%2F2018-06-12_5b1f6999d205c.png%22%2C%22s%22%3A%22http%3A%2F%2Fphoto.yousi.com%2F2018-06-12_5b1f6999d205c.png%22%7D%5D&subject=%E8%AF%AD%E6%96%87
+
+
+
+

BIN
drawingboard-master/res/作业批改数据传输-参数说明.docx


+ 32 - 0
drawingboard-master/res/作业批改数据传输.json

@@ -0,0 +1,32 @@
+{
+    "pages": [
+        {
+            "question": [
+                {
+                    "r": 0,
+                    "w": 0,
+                    "sr": 2,
+                    "sw": 3,
+                    "eimg": "http://www.baidu.com/log.png",
+                    "err": [
+                        {
+                            "id": 1,
+                            "desc": "审题不清,技巧不清",
+                            "x": 12,
+                            "y": 12
+                        }
+                    ]
+                }
+            ],
+            "page": {
+                "img": "http://www.baidu.com/log.png",
+                "imgorg": "http://www.baidu.com/log.png",
+                "w": 166,
+                "h": 188,
+                "index": 0
+            }
+        }
+    ],
+    "font": 10,
+    "callback": {}
+}

Някои файлове не бяха показани, защото твърде много файлове са промени