scanButton.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. <template>
  2. <div class="canvas_button">
  3. <canvas id="canvasProcess" height="180" width="180"></canvas>
  4. <div class="canvas_cr"></div>
  5. <img src="../../../assets/icon/scan_button_bg.png" v-if="showButton">
  6. </div>
  7. </template>
  8. <script>
  9. export default {
  10. name: 'scanButton',
  11. props: {
  12. process: {
  13. type: Number,
  14. default: 10
  15. },
  16. quekao: {
  17. type: Number,
  18. default: 20
  19. },
  20. yichang: {
  21. type: Number,
  22. default: 40
  23. }
  24. },
  25. watch: {
  26. yichang(){
  27. // console.log("异常数值变化了",this.yichang);
  28. // console.log("打印进度值",this.process,this.quekao,this.yichang);
  29. },
  30. },
  31. data () {
  32. return {
  33. canvas: null,
  34. scale: 1,
  35. circle:0,
  36. id: '',
  37. animationSpeed:1,
  38. showButton:true
  39. }
  40. },
  41. mounted() {
  42. // this.canvas = document.getElementById('canvasScanButton')
  43. this.DrawCanvas();//画布开始
  44. // this.animations()
  45. },
  46. beforeDestroy () {
  47. cancelAnimationFrame(this.id);//取消注册请求动画id 通过取消动画帧请求,可以停止正在进行的动画,防止不必要的计算和渲染,从而节省资源和提高性能。
  48. },
  49. methods: {
  50. handleAnimation: function(anim) {
  51. this.anim = anim;
  52. this.anim.setSpeed(this.animationSpeed);
  53. // 可以在这里添加更多的动画控制逻辑
  54. },
  55. //画一个环行进度条圆圈
  56. DrawCanvas()
  57. {
  58. this.canvas=document.getElementById('canvasProcess');
  59. if(this.canvas==null)
  60. {
  61. return;
  62. }
  63. let ctx=this.canvas.getContext('2d');
  64. //创建一个圆锥渐变对象
  65. let g = ctx.createConicGradient(0, 55, 55);
  66. //添加颜色停止点
  67. g.addColorStop(0,'blue')
  68. g.addColorStop(1,'white')
  69. ctx.clearRect(0,0,this.canvas.width,this.canvas.height);//清除指定矩形区域内的所有像素
  70. ctx.save();//保存当前绘图状态
  71. ctx.translate(this.canvas.width / 2, this.canvas.height / 2);//将原点移动到画布的中心
  72. //抖动
  73. // this.scale = this.scale + 0.002
  74. // ctx.scale(this.scale, this.scale)
  75. // if (this.scale >= 1.05) {
  76. // this.scale = 0.9998
  77. // }
  78. // // 圆底
  79. ctx.translate(-this.canvas.width / 2, -this.canvas.height / 2)//将原点移动到画布的中心
  80. ctx.beginPath();//开始路径
  81. ctx.save();//保存当前绘图状态
  82. ctx.arc(90,90,75,0,2 * Math.PI);//绘制一个圆形,圆心在90,90原点上 半径为80像素
  83. ctx.shadowColor = "#4D2EFA";//描边颜色
  84. ctx.shadowBlur = 10;//描边粗细
  85. ctx.fillStyle = '#ffffff';//底部背景色
  86. ctx.fill();//填充
  87. ctx.restore();//恢复之前保存的绘图状态
  88. ctx.closePath();//闭合路径
  89. // 绘制进度环轨道
  90. ctx.beginPath();//开始路径
  91. ctx.lineWidth = 10;//进度环宽度
  92. ctx.strokeStyle = '#EAF0FF';//进度环轨道颜色值
  93. ctx.arc(90,90,75,0,2*Math.PI);//绘制进度环圆形 圆心在90 90上半径为75像素
  94. ctx.stroke();//描边
  95. ctx.closePath();//闭合路径
  96. // 进度环
  97. //绿色进度环
  98. ctx.beginPath()
  99. ctx.lineWidth = 10;//进度条宽度
  100. ctx.strokeStyle = '#2BC644';//进度条颜色值
  101. ctx.arc(90,90,75, -90 * Math.PI / 180,((this.process.toFixed(0) / 100)*360 - 90)*Math.PI/180);//绘制进度条弧度 圆心在90 90 半径为75像素
  102. ctx.stroke()
  103. ctx.closePath();//闭合路径
  104. //异常进度环
  105. ctx.beginPath()
  106. ctx.strokeStyle = '#F56C6C';//异常进度条颜色值
  107. ctx.arc(90,90,75,((this.process.toFixed(0) / 100)*360 - 90)*Math.PI/180,((this.yichang.toFixed(0) / 100)*360 + ((this.process.toFixed(0) / 100)*360 - 90))*Math.PI/180)
  108. ctx.stroke()
  109. ctx.closePath()
  110. //缺考进度环
  111. ctx.beginPath()
  112. ctx.strokeStyle = '#FB9F34'//缺考颜色值
  113. ctx.arc(90,90,75,
  114. ((this.yichang.toFixed(0) / 100)*360 + ((this.process.toFixed(0) / 100)*360 - 90))*Math.PI/180,
  115. ((this.quekao.toFixed(0) / 100)*360 + (this.yichang.toFixed(0) / 100)*360 + ((this.process.toFixed(0) / 100)*360 - 90))*Math.PI/180)
  116. ctx.stroke();
  117. ctx.closePath();
  118. // 扫描文字
  119. ctx.beginPath()
  120. ctx.font = "20px bold"
  121. ctx.textAlign = 'center'
  122. ctx.fillStyle = '#333333';//文字颜色值
  123. ctx.fillText('开始扫描',90,120);//扫描的位置
  124. ctx.closePath()
  125. // 扫描百分比
  126. ctx.beginPath()
  127. ctx.font = "32px bold";
  128. ctx.textAlign = 'center'
  129. ctx.fillStyle = '#2E64FA';//扫描百分比颜色值
  130. ctx.fillText(this.FormatProcess(this.process) + '%',90,90)
  131. ctx.closePath()
  132. ctx.restore()
  133. // console.log("打印进度值",this.process,this.quekao,this.yichang);
  134. // 请求下一帧
  135. this.id = requestAnimationFrame(this.DrawCanvas);
  136. },
  137. // 格式化进度显示:如果小数部分为0则不显示,否则显示一位小数
  138. FormatProcess(process) {
  139. if (process % 1 === 0) {
  140. // 如果是整数,直接返回整数部分
  141. return Math.floor(process);
  142. } else {
  143. // 如果有小数部分,保留一位小数
  144. return process.toFixed(2);
  145. }
  146. },
  147. animations () {
  148. this.canvas=document.getElementById('canvasProcess');
  149. let ctx = this.canvas.getContext('2d')
  150. //创建一个圆锥渐变对象
  151. let g = ctx.createConicGradient(0, 90, 90);
  152. //添加颜色停止点
  153. g.addColorStop(0,'blue')
  154. g.addColorStop(1,'white')
  155. ctx.clearRect(0,0,this.canvas.width,this.canvas.height);//清除指定矩形区域内的所有像素
  156. ctx.save();//保存当前绘图状态
  157. ctx.translate(this.canvas.width / 2, this.canvas.height / 2);//将原点移动到画布的中心
  158. //抖动
  159. // this.scale = this.scale + 0.002
  160. // ctx.scale(this.scale, this.scale)
  161. // if (this.scale >= 1.05) {
  162. // this.scale = 0.9998
  163. // }
  164. // 圆底
  165. ctx.translate(-this.canvas.width / 2, -this.canvas.height / 2)
  166. ctx.beginPath()
  167. ctx.save()
  168. ctx.arc(125,125,100,0,360 * Math.PI / 180)
  169. ctx.shadowColor = "#4D2EFA";
  170. ctx.shadowBlur = 15;
  171. ctx.fillStyle = '#ffffff';//底部背景色
  172. ctx.fill()
  173. ctx.restore()
  174. ctx.closePath()
  175. // 进度环底边
  176. ctx.beginPath()
  177. ctx.lineWidth = 20
  178. ctx.strokeStyle = '#D1E0FF';//进度环轨道颜色值
  179. ctx.arc(125,125,85,0,360*Math.PI/180)
  180. ctx.stroke()
  181. ctx.closePath()
  182. // 进度环
  183. ctx.beginPath()
  184. ctx.lineWidth = 20
  185. ctx.strokeStyle = '#2BC644';//进度条颜色值
  186. ctx.arc(125,125,85,-90 * Math.PI / 180,((this.process.toFixed(0) / 100)*360 - 90)*Math.PI/180)
  187. ctx.stroke()
  188. ctx.closePath()
  189. ctx.beginPath()
  190. ctx.strokeStyle = 'red'
  191. ctx.arc(125,125,85,((this.process.toFixed(0) / 100)*360 - 90)*Math.PI/180,((this.yichang.toFixed(0) / 100)*360 + ((this.process.toFixed(0) / 100)*360 - 90))*Math.PI/180)
  192. ctx.stroke()
  193. ctx.beginPath()
  194. ctx.strokeStyle = '#FB9334'//缺考颜色值
  195. ctx.arc(125,125,85,
  196. ((this.yichang.toFixed(0) / 100)*360 + ((this.process.toFixed(0) / 100)*360 - 90))*Math.PI/180,
  197. ((this.quekao.toFixed(0) / 100)*360 + (this.yichang.toFixed(0) / 100)*360 + ((this.process.toFixed(0) / 100)*360 - 90))*Math.PI/180)
  198. ctx.stroke()
  199. ctx.closePath()
  200. // 扫描文字
  201. ctx.beginPath()
  202. ctx.font = "20px bold"
  203. ctx.textAlign = 'center'
  204. ctx.fillStyle = '#333333';//文字颜色值
  205. ctx.fillText('开始扫描',125,155);//扫描的位置
  206. ctx.closePath()
  207. // 扫描百分比
  208. ctx.beginPath()
  209. ctx.font = "32px bold";
  210. ctx.textAlign = 'center'
  211. ctx.fillStyle = '#2E64FA';//扫描百分比颜色值
  212. ctx.fillText(this.process.toFixed(0) + '%',125,125)
  213. ctx.closePath()
  214. ctx.restore()
  215. this.id = requestAnimationFrame(this.animations)
  216. }
  217. }
  218. }
  219. </script>
  220. <style lang="scss" scoped>
  221. .canvas_button{
  222. width: 250px;
  223. height: 250px;
  224. background-color: transparent;
  225. position: relative;
  226. text-align: center;
  227. justify-content:center;
  228. align-items: center;
  229. img
  230. {
  231. width: 100%;
  232. height: 100%;
  233. }
  234. #canvasProcess
  235. {
  236. position: absolute;
  237. left: 35px;
  238. top:35px;
  239. z-index: 999;
  240. }
  241. .canvas_cr
  242. {
  243. width: 138px;
  244. height: 138px;
  245. // box-shadow: 4px 4px 16px 0px rgba(46,100,250,0.4);
  246. // border-image: radial-gradient(circle, rgba(83, 46, 250, 0), rgba(77, 46, 250, 0.53), rgba(46, 100, 250, 1)) 1;;
  247. // border: 2px solid red;
  248. border-radius: 50%;
  249. border:1px dashed #4D2EFA;
  250. position: absolute;
  251. left: 55px;
  252. top: 55px;
  253. z-index: 1000;
  254. animation:identifier 10s linear infinite;
  255. }
  256. @keyframes identifier {
  257. from {
  258. transform: rotate(0deg);
  259. }
  260. to {
  261. transform: rotate(360deg);
  262. }
  263. }
  264. }
  265. </style>