Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

SlidingBlockVerifyTwo.vue 8.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <template>
  2. <div class="as-gravity-center as-radius-5px" @mouseup="onmouseup" style="background-color:#FFFFFF;
  3. padding: 15px 10px 15px 10px;width:340px;box-shadow: 0px 0px 5px #999999;">
  4. <div :style="`width: ${totalWidth}px;`">
  5. <!-- 文字提示 -->
  6. <div class="as-gravity-center-start" style="display:flex;margin-bottom: 10px;">
  7. <div class="as-weight" style="display:flex;align-items: flex-end;">
  8. <span style="color: #666666;font: size 24px;margin-right: 5px; ">请完成拼图验证</span>
  9. <!-- 刷新按钮 -->
  10. <div @click="refresh">
  11. <el-icon color="#36B7FB">
  12. <refresh />
  13. </el-icon>
  14. </div>
  15. </div>
  16. <!-- 关闭按钮 -->
  17. <div @click="close">
  18. <el-icon :size="24" color="#CDCDCD">
  19. <close />
  20. </el-icon>
  21. </div>
  22. </div>
  23. <!-- 图片层 -->
  24. <div style="max-height: 200px;margin-bottom: 10px;">
  25. <!-- 图片 -->
  26. <img :src="SlideImgThreePng" class="as-radius-5px" style="height: 200px;width: 300px;">
  27. <!-- 裁剪部分 background-color: #3FC0FC; -->
  28. <canvas class="as-radius-5px" id="canvas-cut" :width="canWidth * 2" :height="canHeight * 2"
  29. style="position: relative;z-index: 10;top: 0px;box-shadow: 1px 1px 2.5px #333;"
  30. :style="`left:${canLeft}px;top:${initTop}px;width: ${canWidth}px;height: ${canHeight}px;`">
  31. </canvas>
  32. <!-- 阴影部分 -->
  33. <canvas class="as-radius-5px" id="canvas-shadow" :width="canWidth * 2" :height="canHeight * 2" style="
  34. position: relative;background-color: #333;" :style="`left:${initLeft}px;top:${initTop}px;
  35. width: ${canWidth}px;height: ${canHeight}px;`">
  36. </canvas>
  37. </div>
  38. <!-- 滑动层 -->
  39. <div>
  40. <!-- 背景层 -->
  41. <div v-show="!succeed" ref="slidingBg" class="as-radius-30px slide-bg">
  42. <!-- 拖动圆圈 -->
  43. <div @mousemove="onmousemove" @mousedown="onmousedown" class="circle-bg"
  44. :style="`left:${slidingX}px;width:${dragWidth}px`" style="z-index: 20;">
  45. <span class="as-gravity-center as-bold circle-bg-text">→</span>
  46. </div>
  47. <!-- 拖动层 -->
  48. <div class="slide-bg-tier" :style="`width:${dragBgWidth}px;background-color: ${bgColor};`">
  49. </div>
  50. <span class="as-gravity-center slide-reight">向右滑动完成拼图</span>
  51. </div>
  52. <!-- 成功层 -->
  53. <div v-show="succeed" class="as-gravity-center as-radius-30px" style="height: 45px;
  54. background-color:#36B7FB;color: #ffffff">
  55. 拼接成功
  56. </div>
  57. </div>
  58. </div>
  59. </div>
  60. </template>
  61. <script>
  62. import SlideImgThreePng from '@/assets/image/slide_img_three.png';
  63. //md开撸第二版
  64. export default {
  65. props: {
  66. marginTop: { //高度
  67. default: 40,
  68. type: Number
  69. },
  70. marginLeft: { //宽度
  71. default: 80,
  72. type: Number
  73. },
  74. figure: { //灵敏度
  75. default: 10,
  76. type: Number
  77. }
  78. },
  79. data() {
  80. return {
  81. totalWidth: 300, //设置总宽
  82. dragWidth: 45, //拖动圆大小
  83. dragBgWidth: 0, //拖动背景
  84. slidingX: 0, //圆位置
  85. slidingBg: undefined,
  86. clickStart: false, //点击状态
  87. bgColor: '#3FC0FC', //#FF5B57
  88. succeed: false, //展示状态
  89. canWidth: 60, //60
  90. canHeight: 40, //40
  91. initTop: -205,
  92. initLeft: -60,
  93. canLeft: 0,
  94. SlideImgThreePng
  95. }
  96. },
  97. mounted() {
  98. const {
  99. marginTop,
  100. marginLeft,
  101. canWidth,
  102. canHeight
  103. } = this
  104. //设置阴影位置
  105. this.initTop = this.initTop + this.marginTop
  106. this.initLeft = this.initLeft + this.marginLeft
  107. // 获取滑块背景位置
  108. this.slidingBg = this.$refs['slidingBg'].getBoundingClientRect()
  109. //裁剪视图
  110. let canvas = document.getElementById('canvas-cut');
  111. let cut = canvas.getContext('2d');
  112. let img = new Image();
  113. img.src = this.SlideImgThreePng;
  114. //处理toDataURL遇跨域资源导致的报错
  115. img.crossOrigin = 'Anonymous';
  116. img.onload = function () {
  117. /*
  118. drawImage方法说明 https://www.runoob.com/jsref/met-canvas-drawimage.html
  119. sx 可选。开始剪切的 x 坐标位置。
  120. sy 可选。开始剪切的 y 坐标位置。
  121. swidth 可选。被剪切图像的宽度。
  122. sheight 可选。被剪切图像的高度。
  123. x 在画布上放置图像的 x 坐标位置。
  124. y 在画布上放置图像的 y 坐标位置。
  125. width 可选。要使用的图像的宽度(伸展或缩小图像)。
  126. height 可选。要使用的图像的高度(伸展或缩小图像)。
  127. //在画布上定位图像:
  128. drawImage(image, dx, dy)
  129. //在画布上定位图像,并规定图像的宽度和高度:
  130. drawImage(image, dx, dy, dw, dh)
  131. //剪切图像,并在画布上定位被剪切的部分:
  132. context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
  133. */
  134. console.log(canWidth * 4, canHeight * 4);
  135. cut.drawImage(img, marginLeft * 5.4, marginTop * 5.4, 600, 400, 0, 0, canWidth * 4, canHeight *
  136. 4); //通过缩放增加截取图片的清晰度
  137. };
  138. },
  139. width: {},
  140. methods: {
  141. close() { //关闭监听
  142. this.$emit('close');
  143. },
  144. onmousedown(event) { //鼠标按下事件
  145. this.init(0)
  146. this.clickStart = true
  147. },
  148. onmouseup(event) { //鼠标抬起
  149. this.clickStart = false
  150. if (this.marginLeft + this.figure > this.canLeft && this.canLeft > this.marginLeft - 5) {
  151. this.succeed = true
  152. setTimeout(() => {
  153. this.init(0)
  154. this.succeed = false
  155. this.$emit('succeed');
  156. }, 2000)
  157. } else {
  158. this.bgColor = '#FF5B57'
  159. setTimeout(() => {
  160. this.init(0)
  161. this.bgColor = '#3FC0FC'
  162. this.$emit('fail')
  163. }, 1000)
  164. }
  165. },
  166. onmousemove(event) { //鼠标移动事件
  167. if (this.clickStart) {
  168. const {
  169. slidingBg,
  170. dragWidth,
  171. totalWidth
  172. } = this
  173. const value = event.x - (slidingBg.x + dragWidth / 2) //移动的值
  174. //限制移动范围
  175. if (value > 0 && value < totalWidth - dragWidth) {
  176. this.init(value)
  177. }
  178. }
  179. },
  180. init(value) {
  181. this.slidingX = value
  182. this.dragBgWidth = value + this.dragWidth / 2
  183. //处理滑块超出问题
  184. if (value > (this.totalWidth - this.dragWidth) / 2) {
  185. this.canLeft = value - 15
  186. } else {
  187. this.canLeft = value
  188. }
  189. }
  190. }
  191. }
  192. </script>
  193. <style lang="scss" scoped>
  194. .slide-bg {
  195. color: #3FC0FC;
  196. height: 45px;
  197. background-color: #DBF1FF;
  198. }
  199. .slide-bg-tier {
  200. height: 45px;
  201. position: relative;
  202. z-index: 10;
  203. border-radius: 30px 0 0 30px;
  204. top: -45px
  205. }
  206. .slide-reight {
  207. position: relative;
  208. height: 45px;
  209. width: 100%;
  210. top: -90px;
  211. }
  212. .circle-bg {
  213. height: 45px;
  214. background-color: #fff;
  215. position: relative;
  216. border-radius: 100px;
  217. z-index: 10;
  218. }
  219. .circle-bg-text {
  220. height: 100%;
  221. font-size: 24px;
  222. color: #3FC0FC;
  223. user-select: none
  224. }
  225. </style>