index.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  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" style="background:#fff">
  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. times: 2
  70. }
  71. // window.onload = function(){
  72. new Vue({
  73. el: '#app',
  74. data: exampleData,
  75. created() {
  76. // if(this.domain == 'localhost:9800'){
  77. this.domain = 'https://front.mingxuejinbang.com'
  78. // }
  79. // this.getData()
  80. },
  81. methods: {
  82. convertImgToBase64(img) {
  83. return new Promise((resolve, reject) => {
  84. let canvas = document.createElement('canvas');
  85. const ctx = canvas.getContext('2d');
  86. canvas.height = img.height;
  87. canvas.width = img.width;
  88. ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
  89. let ext = img.src.substring(img.src.lastIndexOf(".") + 1).toLowerCase();
  90. const base64 = canvas.toDataURL("image/" + ext);
  91. canvas = null;
  92. const holder = new Image();
  93. holder.setAttribute('crossOrigin', 'anonymous')
  94. holder.onload = (e) => {
  95. resolve(holder)
  96. }
  97. holder.src = base64;
  98. // return base64;
  99. });
  100. },
  101. hasImg(dom) {
  102. for (let i of dom?.children || []) {
  103. if (i.nodeName === 'IMG') {
  104. return true;
  105. }
  106. }
  107. return false;
  108. },
  109. getCanvasWrap(width, height) {
  110. const canvasWrap = document.createElement('canvas')
  111. canvasWrap.width = this.times * width
  112. canvasWrap.height = this.times * height
  113. canvasWrap.getContext('2d').scale(this.times, this.times)
  114. return canvasWrap;
  115. },
  116. waitingLoaingImg(cb) {
  117. let doms;
  118. const qs = document.querySelector('#qs');
  119. // 每次重置容器高度
  120. qs.style.height = 'auto';
  121. if (this.hasImg(qs)) {
  122. doms = qs?.children ?? [];
  123. } else {
  124. doms = qs.firstChild?.children ?? [];
  125. }
  126. const promiseArr = [];
  127. for (let i of doms) {
  128. if (i.nodeName === 'IMG') {
  129. const promise = new Promise((resolve, reject) => {
  130. i.onload = async (e) => {
  131. // 如果图片存在浮动,需要手动设置容器的高度
  132. if (i.style.float) {
  133. qs.style.height = Math.max(qs.getBoundingClientRect().height, i.height) + 'px'
  134. }
  135. const { width, height } = qs.getBoundingClientRect();
  136. html2canvas(qs, {
  137. canvas: this.getCanvasWrap(width, height),
  138. useCORS: true,
  139. }).then((canvas) => {
  140. resolve(canvas)
  141. })
  142. }
  143. });
  144. promiseArr.push(promise);
  145. }
  146. }
  147. Promise.all(promiseArr).then(res => {
  148. // 虽然用了Promise.all,但实际假设只有一张图片
  149. if (cb) {
  150. cb(res[0])
  151. }
  152. });
  153. },
  154. search() {
  155. if (this.questionId) {
  156. this.getData(this.questionId)
  157. } else {
  158. this.$message({
  159. message: '请输入题目编号',
  160. type: 'warning'
  161. });
  162. }
  163. },
  164. auto() {
  165. this.isAuto = !this.isAuto;
  166. if (this.isAuto) {
  167. this.getData()
  168. }
  169. },
  170. upLoad() {
  171. if (this.questionId && this.imgUri) {
  172. this.uploadQuestionImage(this.imgUri, 1)
  173. } else {
  174. this.$message({
  175. message: '请先搜索题目',
  176. type: 'warning'
  177. });
  178. }
  179. },
  180. getData(questionId) {
  181. axios.defaults.withCredentials = true;
  182. let str = ''
  183. if (questionId) {
  184. str = '?questionId=' + questionId
  185. }
  186. axios.get(this.domain + '/prod-api/front/questionCollection/getNextQuestionForImageGenerate' + str).then(response => {
  187. if (response.data.code == 200) {
  188. this.data = response.data.data
  189. this.$nextTick(() => {
  190. this.MathQueueTitle(str)
  191. })
  192. } else {
  193. this.isAuto = false
  194. this.$message({
  195. message: '获取题目信息失败',
  196. type: 'warning'
  197. });
  198. }
  199. }).catch(function (error) { // 请求失败处理
  200. this.isAuto = false
  201. this.$message.error('网络请求异常!');
  202. });
  203. },
  204. uploadQuestionImage(src, type) {
  205. axios.defaults.withCredentials = true;
  206. var formData = new FormData()
  207. formData.append('questionId', this.data.questionId)
  208. formData.append('imageBase64', src)
  209. if (this.isAuto == false) {
  210. formData.append('manual', true)
  211. }
  212. axios.post(this.domain + '/prod-api/front/questionCollection/uploadQuestionImage', formData).then(response => {
  213. console.log(response)
  214. if (response.data.code == 200) {
  215. if (this.isAuto) {
  216. this.getData()
  217. }
  218. if (type) {
  219. this.$message({
  220. message: '上传题目信息成功!',
  221. type: 'success'
  222. });
  223. }
  224. } else {
  225. this.isAuto = false
  226. this.$message({
  227. message: '上传题目信息失败!',
  228. type: 'warning'
  229. });
  230. }
  231. }).catch(function (error) { // 请求失败处理
  232. this.isAuto = false
  233. this.$message.error('网络请求异常!');
  234. });
  235. },
  236. getCookie(str) {//获取cookie
  237. let cookie = document.cookie.split('; ');
  238. let cookies = {}
  239. cookie.forEach(item => {
  240. cookies[item.split('=')[0]] = item.split('=')[1]
  241. })
  242. return cookies[str]
  243. },
  244. MathQueueTitle(str) {//初始化公式
  245. if (MathQueue) {
  246. clearInterval(this.time)
  247. MathQueue('title')
  248. // setTimeout(() => {
  249. // this.$nextTick(() => {
  250. // this.downLoad(str)
  251. this.waitingLoaingImg((canvas) => { this.downLoad(str, canvas) });
  252. // })
  253. // }, 1000)
  254. } else {
  255. this.time = setInterval(() => {
  256. this.MathQueueTitle()
  257. }, 5)
  258. }
  259. },
  260. downLoad(type, canvas1) {
  261. if (!this.data.questionId) {
  262. this.$message({
  263. message: '请先搜索题目!',
  264. type: 'warning'
  265. });
  266. return
  267. }
  268. let _this = this
  269. _this.imgUri = ''
  270. document.getElementById('qs').style.display = 'none'
  271. let _canvas = document.getElementById('ans')
  272. const { width, height } = _canvas.getBoundingClientRect();
  273. html2canvas(_canvas, {
  274. canvas: this.getCanvasWrap(width, height),
  275. useCORS: true,
  276. }).then((canvas2) => {
  277. document.getElementById('qs').style.display = 'block'
  278. console.log(canvas2)
  279. var canvas3 = document.createElement("canvas");
  280. canvas3.width = Math.max(canvas1.width, canvas2.width)
  281. canvas3.height = canvas1.height + (canvas2.width && canvas2.height ? canvas2.height : 0)
  282. var ctx = canvas3.getContext("2d");
  283. // 绘制题目
  284. ctx.drawImage(canvas1, 0, 0, canvas1.width, canvas1.height);
  285. if (canvas2.width && canvas2.height) {
  286. console.log(123)
  287. // 绘制答案
  288. ctx.drawImage(canvas2, 0, canvas1.height, canvas2.width, canvas2.height);
  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>