index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. <template>
  2. <div id="outerDiv" class="development_stage">
  3. <head-component :headinfo=headinfo></head-component>
  4. <div class="page-content">
  5. <canvas width="1700" height="900" style="border: 1px solid blue; background-color: #000000;"
  6. id="can"></canvas>
  7. </div>
  8. </div>
  9. </template>
  10. <script setup>
  11. import headComponent from '@/views/xjc-integratedmachine/components/head_component.vue'
  12. const headinfo = ref({})
  13. import {onMounted} from 'vue'
  14. import * as echarts from "echarts";
  15. import html2canvas from 'html2canvas';
  16. import {ElMessage} from 'element-plus'
  17. const backgroundImage = new Image();
  18. // backgroundImage.src = 'http://192.168.3.100/screenshot.png'; // 替换为你的背景图片路径
  19. let CENTER_X = 910;
  20. let CENTER_Y = 900;
  21. let startMouse = {x: 0, y: 0};
  22. let moveMouse = {x: 0, y: 0};
  23. // 画笔橡皮擦状态,true画笔,false橡皮
  24. let paintStateFlag = true;
  25. let paintStateFlagText = ref('画笔');
  26. // 第一个职业
  27. let startAngle11 = 0;
  28. let startAngle12 = 0;
  29. let startAngle13 = 0;
  30. // 第二个职业
  31. let startAngle21 = 0;
  32. let startAngle22 = 0;
  33. let startAngle23 = 0;
  34. // 第三个职业
  35. let startAngle31 = 0;
  36. let startAngle32 = 0;
  37. let startAngle33 = 0;
  38. // 第四个职业
  39. let startAngle41 = 0;
  40. let startAngle42 = 0;
  41. let startAngle43 = 0;
  42. // 第五个职业
  43. let startAngle51 = 0;
  44. let startAngle52 = 0;
  45. let startAngle53 = 0;
  46. // 第六个职业
  47. let startAngle61 = 0;
  48. let startAngle62 = 0;
  49. let startAngle63 = 0;
  50. // 第七个职业
  51. let startAngle71 = 0;
  52. let startAngle72 = 0;
  53. let startAngle73 = 0;
  54. // 所有轨道绘画限制
  55. let paintFlagList = [
  56. false, false, false,
  57. false, false, false,
  58. false, false, false,
  59. false, false, false,
  60. false, false, false,
  61. false, false, false]
  62. let undoList = []; // 用于保存所有操作,用于撤销和重做
  63. let redoList = []; // 用于保存所有撤销的操作,用于重做
  64. function changes() {
  65. can.addEventListener('touchstart', function (el) {
  66. let rect = el.target.getBoundingClientRect();
  67. startMouse.x = el.touches[0].pageX - rect.left;
  68. startMouse.y = el.touches[0].pageY - rect.top;
  69. calcStartRadius();
  70. can.addEventListener('touchmove', function (e) {
  71. moveMouse.x = startMouse.x;
  72. moveMouse.y = startMouse.y;
  73. startMouse.x = e.targetTouches[0].pageX - this.offsetLeft;
  74. startMouse.y = e.targetTouches[0].pageY - this.offsetTop;
  75. if (startMouse.x !== moveMouse.x && startMouse.y !== moveMouse.y) {
  76. return;
  77. }
  78. calcEndRadius();
  79. })
  80. })
  81. can.addEventListener('touchend', function () {
  82. can.onmousemove = null;
  83. })
  84. }
  85. /*计算起始点*/
  86. function calcStartRadius() {
  87. let sum = Math.pow(startMouse.x - CENTER_X, 2) + Math.pow(CENTER_Y - startMouse.y, 2);
  88. // 第一个职业
  89. if (sum < Math.pow(50, 2) && sum > Math.pow(10, 2)) {
  90. startAngle11 = calcAngle();
  91. calcPaintCircleFlag(0)
  92. } else if (sum < Math.pow(90, 2) && sum > Math.pow(50, 2)) {
  93. startAngle12 = calcAngle();
  94. calcPaintCircleFlag(1)
  95. } else if (sum < Math.pow(130, 2) && sum > Math.pow(90, 2)) {
  96. startAngle13 = calcAngle();
  97. calcPaintCircleFlag(2)
  98. }
  99. // 第二个职业
  100. else if (sum < Math.pow(185, 2) && sum > Math.pow(145, 2)) {
  101. startAngle21 = calcAngle();
  102. calcPaintCircleFlag(3)
  103. } else if (sum < Math.pow(225, 2) && sum > Math.pow(185, 2)) {
  104. startAngle22 = calcAngle();
  105. calcPaintCircleFlag(4)
  106. } else if (sum < Math.pow(265, 2) && sum > Math.pow(225, 2)) {
  107. startAngle23 = calcAngle();
  108. calcPaintCircleFlag(5)
  109. }
  110. // 第三个职业
  111. else if (sum < Math.pow(320, 2) && sum > Math.pow(280, 2)) {
  112. startAngle31 = calcAngle();
  113. calcPaintCircleFlag(6)
  114. } else if (sum < Math.pow(360, 2) && sum > Math.pow(320, 2)) {
  115. startAngle32 = calcAngle();
  116. calcPaintCircleFlag(7)
  117. } else if (sum < Math.pow(400, 2) && sum > Math.pow(360, 2)) {
  118. startAngle33 = calcAngle();
  119. calcPaintCircleFlag(8)
  120. }
  121. // 第四个职业
  122. else if (sum < Math.pow(455, 2) && sum > Math.pow(415, 2)) {
  123. startAngle41 = calcAngle();
  124. calcPaintCircleFlag(9)
  125. } else if (sum < Math.pow(495, 2) && sum > Math.pow(455, 2)) {
  126. startAngle42 = calcAngle();
  127. calcPaintCircleFlag(10)
  128. } else if (sum < Math.pow(535, 2) && sum > Math.pow(495, 2)) {
  129. startAngle43 = calcAngle();
  130. calcPaintCircleFlag(11)
  131. }
  132. // 第五个职业
  133. else if (sum < Math.pow(590, 2) && sum > Math.pow(550, 2)) {
  134. startAngle51 = calcAngle();
  135. calcPaintCircleFlag(12)
  136. } else if (sum < Math.pow(630, 2) && sum > Math.pow(590, 2)) {
  137. startAngle52 = calcAngle();
  138. calcPaintCircleFlag(13)
  139. } else if (sum < Math.pow(670, 2) && sum > Math.pow(630, 2)) {
  140. startAngle53 = calcAngle();
  141. calcPaintCircleFlag(14)
  142. }
  143. // 第六个职业
  144. else if (sum < Math.pow(725, 2) && sum > Math.pow(685, 2)) {
  145. startAngle61 = calcAngle();
  146. calcPaintCircleFlag(15)
  147. } else if (sum < Math.pow(765, 2) && sum > Math.pow(725, 2)) {
  148. startAngle62 = calcAngle();
  149. calcPaintCircleFlag(16)
  150. } else if (sum < Math.pow(805, 2) && sum > Math.pow(765, 2)) {
  151. startAngle63 = calcAngle();
  152. calcPaintCircleFlag(17)
  153. }
  154. }
  155. /**
  156. * 只有起始点所在轨道可以绘制
  157. **/
  158. function calcPaintCircleFlag(index) {
  159. paintFlagList = [
  160. false, false, false,
  161. false, false, false,
  162. false, false, false,
  163. false, false, false,
  164. false, false, false,
  165. false, false, false]
  166. paintFlagList[index] = true
  167. console.log(paintFlagList)
  168. }
  169. /*计算终点*/
  170. function calcEndRadius() {
  171. let sum = Math.pow(moveMouse.x - CENTER_X, 2) + Math.pow(CENTER_Y - moveMouse.y, 2);
  172. let ret = calcAngle();
  173. // 第一个职业
  174. if (sum < Math.pow(50, 2) && sum > Math.pow(10, 2)) {
  175. if (paintFlagList[0]) {
  176. if (paintStateFlag) {
  177. paint("#ffc300", 30, startAngle11, ret);
  178. } else {
  179. paint("#000000", 30, startAngle11, ret);
  180. paint("#000000", 70, startAngle11, ret);
  181. paint("#000000", 110, startAngle11, ret);
  182. }
  183. }
  184. } else if (sum < Math.pow(90, 2) && sum > Math.pow(50, 2)) {
  185. if (paintFlagList[1]) {
  186. if (paintStateFlag) {
  187. paint("#ffc300", 30, startAngle12, ret);
  188. paint("#ffc300", 70, startAngle12, ret);
  189. } else {
  190. paint("#000000", 70, startAngle12, ret);
  191. paint("#000000", 110, startAngle12, ret);
  192. }
  193. }
  194. } else if (sum < Math.pow(130, 2) && sum > Math.pow(90, 2)) {
  195. if (paintFlagList[2]) {
  196. if (paintStateFlag) {
  197. paint("#ffc300", 30, startAngle13, ret);
  198. paint("#ffc300", 70, startAngle13, ret);
  199. paint("#ffc300", 110, startAngle13, ret);
  200. } else {
  201. paint("#000000", 110, startAngle13, ret);
  202. }
  203. }
  204. }
  205. // 第二个职业
  206. else if (sum < Math.pow(185, 2) && sum > Math.pow(145, 2)) {
  207. if (paintFlagList[3]) {
  208. if (paintStateFlag) {
  209. paint("#f72585", 165, startAngle21, ret);
  210. } else {
  211. paint("#000000", 165, startAngle21, ret);
  212. paint("#000000", 205, startAngle21, ret);
  213. paint("#000000", 245, startAngle21, ret);
  214. }
  215. }
  216. } else if (sum < Math.pow(225, 2) && sum > Math.pow(185, 2)) {
  217. if (paintFlagList[4]) {
  218. if (paintStateFlag) {
  219. paint("#f72585", 165, startAngle22, ret);
  220. paint("#f72585", 205, startAngle22, ret);
  221. } else {
  222. paint("#000000", 205, startAngle22, ret);
  223. paint("#000000", 245, startAngle22, ret);
  224. }
  225. }
  226. } else if (sum < Math.pow(265, 2) && sum > Math.pow(225, 2)) {
  227. if (paintFlagList[5]) {
  228. if (paintStateFlag) {
  229. paint("#f72585", 165, startAngle23, ret);
  230. paint("#f72585", 205, startAngle23, ret);
  231. paint("#f72585", 245, startAngle23, ret);
  232. } else {
  233. paint("#000000", 245, startAngle23, ret);
  234. }
  235. }
  236. }
  237. //第三个职业
  238. else if (sum < Math.pow(320, 2) && sum > Math.pow(280, 2)) {
  239. if (paintFlagList[6]) {
  240. if (paintStateFlag) {
  241. paint("#4cc9f0", 300, startAngle31, ret);
  242. } else {
  243. paint("#000000", 300, startAngle31, ret);
  244. paint("#000000", 340, startAngle31, ret);
  245. paint("#000000", 380, startAngle31, ret);
  246. }
  247. }
  248. } else if (sum < Math.pow(360, 2) && sum > Math.pow(320, 2)) {
  249. if (paintFlagList[7]) {
  250. if (paintStateFlag) {
  251. paint("#4cc9f0", 300, startAngle31, ret);
  252. paint("#4cc9f0", 340, startAngle31, ret);
  253. } else {
  254. paint("#000000", 340, startAngle32, ret);
  255. paint("#000000", 380, startAngle32, ret);
  256. }
  257. }
  258. } else if (sum < Math.pow(400, 2) && sum > Math.pow(360, 2)) {
  259. if (paintFlagList[8]) {
  260. if (paintStateFlag) {
  261. paint("#4cc9f0", 300, startAngle33, ret);
  262. paint("#4cc9f0", 340, startAngle33, ret);
  263. paint("#4cc9f0", 380, startAngle33, ret);
  264. } else {
  265. paint("#000000", 380, startAngle33, ret);
  266. }
  267. }
  268. }
  269. //第四个职业
  270. else if (sum < Math.pow(455, 2) && sum > Math.pow(415, 2)) {
  271. if (paintFlagList[9]) {
  272. if (paintStateFlag) {
  273. paint("#a000ff", 435, startAngle41, ret);
  274. } else {
  275. paint("#000000", 435, startAngle41, ret);
  276. paint("#000000", 475, startAngle41, ret);
  277. paint("#000000", 515, startAngle41, ret);
  278. }
  279. }
  280. } else if (sum < Math.pow(495, 2) && sum > Math.pow(455, 2)) {
  281. if (paintFlagList[10]) {
  282. if (paintStateFlag) {
  283. paint("#a000ff", 435, startAngle42, ret);
  284. paint("#a000ff", 475, startAngle42, ret);
  285. } else {
  286. paint("#000000", 475, startAngle42, ret);
  287. paint("#000000", 515, startAngle42, ret);
  288. }
  289. }
  290. } else if (sum < Math.pow(535, 2) && sum > Math.pow(495, 2)) {
  291. if (paintFlagList[11]) {
  292. if (paintStateFlag) {
  293. paint("#a000ff", 435, startAngle43, ret);
  294. paint("#a000ff", 475, startAngle43, ret);
  295. paint("#a000ff", 515, startAngle43, ret);
  296. } else {
  297. paint("#000000", 515, startAngle43, ret);
  298. }
  299. }
  300. }
  301. //第五个职业
  302. else if (sum < Math.pow(590, 2) && sum > Math.pow(550, 2)) {
  303. if (paintFlagList[12]) {
  304. if (paintStateFlag) {
  305. paint("#ffc9f6", 570, startAngle51, ret);
  306. } else {
  307. paint("#000000", 570, startAngle51, ret);
  308. paint("#000000", 610, startAngle51, ret);
  309. paint("#000000", 650, startAngle51, ret);
  310. }
  311. }
  312. } else if (sum < Math.pow(630, 2) && sum > Math.pow(590, 2)) {
  313. if (paintFlagList[13]) {
  314. if (paintStateFlag) {
  315. paint("#ffc9f6", 570, startAngle52, ret);
  316. paint("#ffc9f6", 610, startAngle52, ret);
  317. } else {
  318. paint("#000000", 610, startAngle52, ret);
  319. paint("#000000", 650, startAngle52, ret);
  320. }
  321. }
  322. } else if (sum < Math.pow(670, 2) && sum > Math.pow(630, 2)) {
  323. if (paintFlagList[14]) {
  324. if (paintStateFlag) {
  325. paint("#ffc9f6", 570, startAngle53, ret);
  326. paint("#ffc9f6", 610, startAngle53, ret);
  327. paint("#ffc9f6", 650, startAngle53, ret);
  328. } else {
  329. paint("#000000", 650, startAngle53, ret);
  330. }
  331. }
  332. }
  333. //第六个职业
  334. else if (sum < Math.pow(725, 2) && sum > Math.pow(685, 2)) {
  335. if (paintFlagList[15]) {
  336. if (paintStateFlag) {
  337. paint("#9de617", 705, startAngle61, ret);
  338. } else {
  339. paint("#000000", 705, startAngle61, ret);
  340. paint("#000000", 745, startAngle61, ret);
  341. paint("#000000", 785, startAngle61, ret);
  342. }
  343. }
  344. } else if (sum < Math.pow(765, 2) && sum > Math.pow(725, 2)) {
  345. if (paintFlagList[16]) {
  346. if (paintStateFlag) {
  347. paint("#9de617", 705, startAngle62, ret);
  348. paint("#9de617", 745, startAngle62, ret);
  349. } else {
  350. paint("#000000", 745, startAngle62, ret);
  351. paint("#000000", 785, startAngle62, ret);
  352. }
  353. }
  354. } else if (sum < Math.pow(805, 2) && sum > Math.pow(765, 2)) {
  355. if (paintFlagList[17]) {
  356. if (paintStateFlag) {
  357. paint("#9de617", 705, startAngle63, ret);
  358. paint("#9de617", 745, startAngle63, ret);
  359. paint("#9de617", 785, startAngle63, ret);
  360. } else {
  361. paint("#000000", 785, startAngle63, ret);
  362. }
  363. }
  364. }
  365. }
  366. /*计算角度0-180度*/
  367. function calcAngle() {
  368. let number = Math.atan2(Math.abs(CENTER_Y - startMouse.y), CENTER_X - startMouse.x);
  369. let ret = number * 180 / Math.PI; //弧度转角度,方便调试
  370. if (ret > 360) {
  371. ret -= 360;
  372. }
  373. if (ret < 0) {
  374. ret += 450;
  375. }
  376. let num = ret * Math.PI / 180 + Math.PI;
  377. console.log('角度:' + num);
  378. return num;
  379. }
  380. let can = "";
  381. let context = "";
  382. function init() {
  383. can = document.getElementById('can');
  384. context = can.getContext('2d');
  385. }
  386. function arc(num) {
  387. context.lineWidth = 1;
  388. context.strokeStyle = '#ffffff'
  389. context.beginPath();
  390. context.arc(CENTER_X, CENTER_Y, num, Math.PI, 2 * Math.PI, false);
  391. context.stroke();
  392. }
  393. function paint(color, radius, startAngle, endAngle) {
  394. // 结束角度不能小于起始角度
  395. if (endAngle <= startAngle) {
  396. // ElMessage.error("只能顺时针画")
  397. return;
  398. }
  399. context.lineWidth = 37;
  400. context.strokeStyle = color;
  401. context.beginPath();
  402. context.arc(CENTER_X, CENTER_Y, radius, startAngle, endAngle, false);
  403. context.stroke();
  404. }
  405. function changePaintState() {
  406. if (paintStateFlag) {
  407. paintStateFlag = false;
  408. paintStateFlagText.value = '橡皮擦'
  409. } else {
  410. paintStateFlag = true;
  411. paintStateFlagText.value = '画笔'
  412. }
  413. }
  414. function eraserState() {
  415. paintStateFlag = false;
  416. }
  417. function clear() {
  418. context.clearRect(0, 0, can.width, can.height);
  419. drawBackground();
  420. }
  421. function drawBackground() {
  422. let radius = 10;
  423. arc(radius);
  424. for (let i = 1; i < 24; i++) {
  425. radius = drawBackgroundOne(radius, i);
  426. arc(radius);
  427. }
  428. }
  429. function drawBackgroundOne(innerRadius, i) {
  430. if (i % 4 == 0) {
  431. return innerRadius + 15;
  432. } else {
  433. return innerRadius + 40;
  434. }
  435. }
  436. function save() {
  437. html2canvas(can).then(canvas => {
  438. const link = document.createElement('a');
  439. link.download = 'screenshot.png';
  440. link.href = canvas.toDataURL();
  441. link.click();
  442. document.body.removeChild(link); // 清理创建的链接
  443. });
  444. // capturePage()
  445. }
  446. const content = ref(null);
  447. const canvas = ref(null);
  448. function capturePage() {
  449. const ctx = canvas.value.getContext('2d');
  450. const contentElement = content.value;
  451. html2canvas(contentElement).then(canvas => {
  452. // 将生成的 canvas 转换为图片并下载
  453. const imgData = canvas.toDataURL('image/png');
  454. const link = document.createElement('a');
  455. link.download = 'page-screenshot.png';
  456. link.href = imgData;
  457. link.click();
  458. });
  459. }
  460. onMounted(() => {
  461. init();
  462. changes();
  463. console.log("mmmmm")
  464. drawBackground();
  465. });
  466. </script>
  467. <style scoped lang="scss">
  468. //body,html{
  469. // overflow: hidden;
  470. //}
  471. p {
  472. margin: 0;
  473. padding: 0;
  474. }
  475. .development_stage {
  476. background: url('@/assets/images/login/login-home-background.png') no-repeat;
  477. background-size: 1920px 1080px;
  478. z-index: 10;
  479. width: 100%;
  480. height: 1080px;
  481. }
  482. .page-content {
  483. display:flex;
  484. justify-content: center;
  485. padding-top: 113px;
  486. }
  487. .bg-color-style1 {
  488. background: #FFFFFF;
  489. }
  490. </style>