index.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. <!DOCTYPE html>
  2. <html lang="zh">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7. <script src="https://unpkg.com/vue@2.6.14/dist/vue.js"></script>
  8. <script type="text/javascript" async
  9. src="https://mingxuejingbang.oss-cn-beijing.aliyuncs.com/MathJaxFiles/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML"></script>
  10. <script type="text/javascript" async src="js/globalVariable.js"></script>
  11. <script type="text/javascript" async src="js/html2canvas.min.js"></script>
  12. <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
  13. <script src="https://unpkg.com/element-ui/lib/index.js"></script>
  14. <script src="https://cdn.staticfile.org/axios/0.18.0/axios.min.js"></script>
  15. <title></title>
  16. <style>
  17. html,
  18. body {
  19. margin: 0;
  20. padding: 0
  21. }
  22. .el-radio--medium.is-bordered {
  23. height: auto;
  24. padding-bottom: 8px;
  25. }
  26. #title::after {
  27. display: table;
  28. content: "";
  29. clear: both;
  30. }
  31. </style>
  32. </head>
  33. <body>
  34. <div id="app">
  35. <div style="min-height:300px;">
  36. <div id="title" style="background:#fff;max-width:1024px">
  37. <div id="qs" style="padding-bottom: 15px" v-html="data.title"></div>
  38. <div id="ans">
  39. <template v-for="(itemOpt, idx) in data.options">
  40. <div :key="idx">
  41. <el-radio style="margin-bottom: 15px" :label="selectOpt[idx]" border size="medium">
  42. {{ selectOpt[idx] + ' 、 ' }}<span style="white-space: normal" v-html="itemOpt"></span>
  43. </el-radio>
  44. </div>
  45. </template>
  46. </div>
  47. </div>
  48. </div>
  49. <div style="margin-bottom:20px;padding: 15px;background: rgb(255, 255, 255); max-width: 1024px;">
  50. <el-input v-model="questionId" style="width: 150px;" placeholder="请输入题目编号"></el-input>
  51. <el-button type="primary" :disabled="isAuto" @click="search">搜索</el-button>
  52. <el-button type="primary" :disabled="isAuto" @click="upLoad">手动上传</el-button>
  53. <el-button type="primary" @click="auto">{{isAuto?'暂停':'自动运行'}}</el-button>
  54. </div>
  55. <div v-if="imgUri" style="margin-top:30px;padding: 15px;background: rgb(255, 255, 255); max-width: 1024px;">
  56. 图片展示:
  57. <img :src="imgUri" alt="" crossorigin="anonymous">
  58. </div>
  59. </div>
  60. <script>
  61. var exampleData = {
  62. selectOpt: ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
  63. data: {},
  64. time: null,
  65. domain: '',
  66. isAuto: false,
  67. questionId: '20061713',
  68. imgUri: ''
  69. }
  70. // window.onload = function(){
  71. new Vue({
  72. el: '#app',
  73. data: exampleData,
  74. created() {
  75. // if(this.domain == 'localhost:9800'){
  76. this.domain = 'https://front.mingxuejinbang.com'
  77. // }
  78. // this.getData()
  79. },
  80. methods: {
  81. convertImgToBase64(img) {
  82. return new Promise((resolve, reject) => {
  83. let canvas = document.createElement('canvas');
  84. const ctx = canvas.getContext('2d');
  85. canvas.height = img.height;
  86. canvas.width = img.width;
  87. ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
  88. let ext = img.src.substring(img.src.lastIndexOf(".") + 1).toLowerCase();
  89. const base64 = canvas.toDataURL("image/" + ext);
  90. canvas = null;
  91. const holder = new Image();
  92. holder.setAttribute('crossOrigin', 'anonymous')
  93. holder.onload = (e) => {
  94. resolve(holder)
  95. }
  96. holder.src = base64;
  97. // return base64;
  98. });
  99. },
  100. hasImg(dom) {
  101. for (let i of dom?.children || []) {
  102. if (i.nodeName === 'IMG') {
  103. return true;
  104. }
  105. }
  106. return false;
  107. },
  108. waitingLoaingImg(cb) {
  109. let doms;
  110. const qs = document.querySelector('#qs');
  111. // 每次重置容器高度
  112. qs.style.height = 'auto';
  113. if (this.hasImg(qs)) {
  114. doms = qs?.children ?? [];
  115. } else {
  116. doms = qs.firstChild?.children ?? [];
  117. }
  118. const promiseArr = [];
  119. for (let i of doms) {
  120. if (i.nodeName === 'IMG') {
  121. const promise = new Promise((resolve, reject) => {
  122. i.onload = async (e) => {
  123. // 如果图片存在浮动,需要手动设置容器的高度
  124. if (i.style.float) {
  125. qs.style.height = Math.max(qs.getBoundingClientRect().height, i.height) + 'px'
  126. }
  127. html2canvas(document.getElementById('qs'), {
  128. useCORS: true,
  129. }).then((canvas) => {
  130. resolve(canvas)
  131. })
  132. }
  133. });
  134. promiseArr.push(promise);
  135. }
  136. }
  137. Promise.all(promiseArr).then(res => {
  138. // 虽然用了Promise.all,但实际假设只有一张图片
  139. if (cb) {
  140. cb(res[0])
  141. }
  142. });
  143. },
  144. search() {
  145. if (this.questionId) {
  146. this.getData(this.questionId)
  147. } else {
  148. this.$message({
  149. message: '请输入题目编号',
  150. type: 'warning'
  151. });
  152. }
  153. },
  154. auto() {
  155. this.isAuto = !this.isAuto;
  156. if (this.isAuto) {
  157. this.getData()
  158. }
  159. },
  160. upLoad() {
  161. if (this.questionId && this.imgUri) {
  162. this.uploadQuestionImage(this.imgUri, 1)
  163. } else {
  164. this.$message({
  165. message: '请先搜索题目',
  166. type: 'warning'
  167. });
  168. }
  169. },
  170. getData(questionId) {
  171. axios.defaults.withCredentials = true;
  172. let str = ''
  173. if (questionId) {
  174. str = '?questionId=' + questionId
  175. }
  176. axios.get(this.domain + '/prod-api/front/questionCollection/getNextQuestionForImageGenerate' + str).then(response => {
  177. if (response.data.code == 200) {
  178. this.data = response.data.data
  179. this.$nextTick(() => {
  180. this.MathQueueTitle(str)
  181. })
  182. } else {
  183. this.isAuto = false
  184. this.$message({
  185. message: '获取题目信息失败',
  186. type: 'warning'
  187. });
  188. }
  189. }).catch(function (error) { // 请求失败处理
  190. this.isAuto = false
  191. this.$message.error('网络请求异常!');
  192. });
  193. },
  194. uploadQuestionImage(src, type) {
  195. axios.defaults.withCredentials = true;
  196. var formData = new FormData()
  197. formData.append('questionId', this.data.questionId)
  198. formData.append('imageBase64', src)
  199. if (this.isAuto == false) {
  200. formData.append('manual', true)
  201. }
  202. axios.post(this.domain + '/prod-api/front/questionCollection/uploadQuestionImage', formData).then(response => {
  203. console.log(response)
  204. if (response.data.code == 200) {
  205. if (this.isAuto) {
  206. this.getData()
  207. }
  208. if (type) {
  209. this.$message({
  210. message: '上传题目信息成功!',
  211. type: 'success'
  212. });
  213. }
  214. } else {
  215. this.isAuto = false
  216. this.$message({
  217. message: '上传题目信息失败!',
  218. type: 'warning'
  219. });
  220. }
  221. }).catch(function (error) { // 请求失败处理
  222. this.isAuto = false
  223. this.$message.error('网络请求异常!');
  224. });
  225. },
  226. getCookie(str) {//获取cookie
  227. let cookie = document.cookie.split('; ');
  228. let cookies = {}
  229. cookie.forEach(item => {
  230. cookies[item.split('=')[0]] = item.split('=')[1]
  231. })
  232. return cookies[str]
  233. },
  234. MathQueueTitle(str) {//初始化公式
  235. if (MathQueue) {
  236. clearInterval(this.time)
  237. MathQueue('title')
  238. // setTimeout(() => {
  239. // this.$nextTick(() => {
  240. // this.downLoad(str)
  241. this.waitingLoaingImg((canvas) => { this.downLoad(str, canvas) });
  242. // })
  243. // }, 1000)
  244. } else {
  245. this.time = setInterval(() => {
  246. this.MathQueueTitle()
  247. }, 5)
  248. }
  249. },
  250. downLoad(type, canvas1) {
  251. if (!this.data.questionId) {
  252. this.$message({
  253. message: '请先搜索题目!',
  254. type: 'warning'
  255. });
  256. return
  257. }
  258. this.questionId=this.data.questionId
  259. const times = 2 // 图片放大倍数,能提升清晰度
  260. let _this = this
  261. _this.imgUri = ''
  262. // let canvas2 = document.createElement('canvas')
  263. let _canvas = document.getElementById('ans')
  264. // console.log(_canvas)
  265. // let w = parseInt(window.getComputedStyle(_canvas).width)
  266. // let h = parseInt(window.getComputedStyle(_canvas).height)
  267. // canvas2.width = w
  268. // canvas2.height = h
  269. // canvas2.style.width = w + 'px'
  270. // canvas2.style.height = h + 'px'
  271. // let context = canvas2.getContext('2d')
  272. // context.scale(1, 1) ///缩放等级
  273. html2canvas(document.getElementById('ans'), {
  274. // canvas: canvas2,
  275. useCORS: true,
  276. allowTaint: false
  277. }).then(function (canvas2) {
  278. var canvas3 = document.createElement("canvas");
  279. canvas3.width = canvas1.width*times + (canvas2.width*times && canvas2.height*times ? canvas2.width*times : 0)
  280. canvas3.height = canvas1.height*times + (canvas2.width*times && canvas2.height*times ? canvas2.height*times : 0)
  281. var ctx = canvas3.getContext("2d");
  282. ctx.scale(times, times) ///缩放等级
  283. // 绘制题目
  284. ctx.drawImage(canvas1, 0, 0, canvas1.width*times, canvas1.height*times);
  285. console.log(canvas2.width*times, canvas2.height*times)
  286. if (canvas2.width*times && canvas2.height*times) {
  287. // 绘制答案
  288. ctx.drawImage(canvas2, 0, canvas1.height*times, canvas2.width*times, canvas2.height*times);
  289. }
  290. _this.imgUri = canvas3.toDataURL('image/png')
  291. canvas1 = null
  292. canvas2 = null
  293. canvas3 = null
  294. if (!type) {
  295. _this.uploadQuestionImage(imgUri)
  296. }
  297. })
  298. },
  299. }
  300. });
  301. // }
  302. </script>
  303. </body>
  304. </html>