<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
純前端,通過canvas來自定義開發滑動圖片驗證,反過來也能完成純滑動驗證。
<template> <div class="verification" ref="verification"> <!-- 畫布部分 --> <canvas ref="slideVerify" class="slide-img"></canvas> <div style="display:none"> <img ref="imgs" :src="imgList[imgIndex]"/> </div> <!-- 下面滾軸部分 --> <div class="slide-wrapper bg-start"> <!-- 滾軸 --> <div class="btn" ref="btn" @mousedown="mouseDown" @mouseup="mouseUp"></div> <p class="text" ref="text">{{content}}</p> <div class="bg" ref="bg"></div> </div> <!-- 重新整理按鈕 --> <button class="refresh" @click="refresh"></button> </div> </template> <script> export default { data () { return { imgIndex: 0, blockCanvas: null, imgList: [require('../assets/1.png'), require('../assets/3.png'), require('../assets/4.png'), require('../assets/5.png') ], content: '滑動滾軸', isDown: false, // 滑鼠是否按下 btnX: 0, imgX: 0 } }, mounted () { this.imgIndex = this.randomNumber(0, 4) document.addEventListener('mousemove', this.mouseMove) this.imageCanvas() }, methods: { // 生成亂數字 randomNumber (min, max) { return Math.floor(Math.random() * (max - min) + min) }, // 滑鼠按下時 mouseDown (e) { this.isDown = true this.btnX = e.clientX - this.$refs.btn.offsetLeft }, // 滑鼠滑動時 mouseMove (e) { // 滾軸左端向右邊移動的距離 let moveX = e.clientX - this.btnX if (this.isDown) { // 滾軸滑動時不能超過的距離 if (this.$refs.btn.offsetLeft <= 259 && this.$refs.btn.offsetLeft >= 0) { this.$refs.btn.style.left = `${moveX}px` this.blockCanvas.style.left = `${moveX - this.imgX}px` this.$refs.bg.style.width = `${moveX}px` } } }, // 滑動中鬆開 mouseUp () { let leftX = this.$refs.btn.offsetLeft // 方塊的位置和缺失的位置重合允許左右2px的誤差 if (this.imgX >= leftX - 1 && this.imgX <= leftX + 1) { // 滑動成功時的邏輯 this.$refs.btn.classList.add('btnsuccess') this.isDown = false } // 如果滑動失敗,滾軸自動回到左邊 if (this.isDown) { this.$refs.btn.style.left = 0 this.blockCanvas.style.left = `-${this.imgX}px` this.$refs.bg.style.width = 0 } // 開關原則 this.isDown = false }, // 畫圖 imageCanvas () { this.blockCanvas = this.blockCanvas ? this.blockCanvas.remove() : null this.blockCanvas = this.createCanvas(300, 150) this.$refs.verification.insertBefore(this.blockCanvas, this.$refs.slideVerify) let x = this.randomNumber(60, 200) let y = 40 this.imgX = x let c = this.$refs.slideVerify let bg = c.getContext('2d') let img = this.$refs.imgs let bk = this.blockCanvas.getContext('2d') // 在兩塊畫布上都放上相同的圖片 img.onload = () => { bg.drawImage(img, 0, 0) bk.drawImage(img, 0, 0) } this.drawBlock(bg, x, y, 'fill') this.drawBlock(bk, x, y, 'clip') }, // 畫摳出來的方塊 drawBlock (ctx, x, y, type) { ctx.beginPath() ctx.moveTo(x, y) ctx.arc(x + 42 / 2, y - 9 + 2, 9, 0.72 * Math.PI, 2.26 * Math.PI) ctx.lineTo(x + 42, y) ctx.arc(x + 42 + 9 - 2, y + 42 / 2, 9, 1.21 * Math.PI, 2.78 * Math.PI) ctx.lineTo(x + 42, y + 42) ctx.lineTo(x, y + 42) ctx.arc(x + 9 - 2, y + 42 / 2, 9 + 0.4, 2.76 * Math.PI, 1.24 * Math.PI, true) ctx.lineTo(x, y) ctx.lineWidth = 2 ctx.fillStyle = 'rgba(255, 255, 255, 0.7)' ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)' ctx.stroke() ctx[type]() ctx.globalCompositeOperation = 'destination-over' // 解決進入頁面時不自動扣拼圖樣式的麻煩(有時需要滑鼠點選後才會出現裁剪後的拼圖) this.blockCanvas.style.left = `-${x}px` }, // 重新整理 refresh () { // 有時會出現點選重新整理,randomNumber返回的數位和上次儲存的一樣,畫布清空後但是填充時沒有改變;所以當一樣時,不會執行重新整理操作 if (this.imgIndex == this.randomNumber(0, 4)) { return false } this.clean() this.$refs.btn.style.left = 0 this.$refs.bg.style.width = 0 this.$refs.btn.classList.remove('btnsuccess') this.isDown = false // 滑鼠是否按下 this.btnX = 0 // 滑鼠點選的水平位置與滾軸移動水平位置的差 this.imgX = 0 this.imageCanvas('restore') this.imgIndex = this.randomNumber(0, 4) }, // 清空canvas clean () { let cxt2 = this.$refs.slideVerify.getContext('2d') cxt2.clearRect(0, 0, 300, 150) }, // 新建canvas createCanvas (width, height) { const canvas = document.createElement('canvas') canvas.width = width canvas.height = height canvas.style.position = 'absolute' return canvas } } } </script> <style scoped> .verification { position: relative; width: 300px; margin: 0 auto; } .slide-wrapper { position: relative; width: 300px; height: 40px; } .bg-start { background: cadetblue; } .bg { position: absolute; height: 40px; background: #ccc; } .text { position: absolute; width: 100%; height: 40px; text-align: center; line-height: 40px; margin: 0; /* z-index: 1; */ } .text-success { color: white; z-index: 2; } .btn { position: absolute; width: 40px; height: 40px; z-index: 1; border-radius: 5px; background: rgb(143, 145, 148); text-align: center; font-size: 24px; color: white; box-shadow: 0 0 1px 1px #fff; background: #fff no-repeat center url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTEyNTVEMURGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTEyNTVEMUNGMkVFMTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2MTc5NzNmZS02OTQxLTQyOTYtYTIwNi02NDI2YTNkOWU5YmUiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+YiRG4AAAALFJREFUeNpi/P//PwMlgImBQkA9A+bOnfsIiBOxKcInh+yCaCDuByoswaIOpxwjciACFegBqZ1AvBSIS5OTk/8TkmNEjwWgQiUgtQuIjwAxUF3yX3xyGIEIFLwHpKyAWB+I1xGSwxULIGf9A7mQkBwTlhBXAFLHgPgqEAcTkmNCU6AL9d8WII4HOvk3ITkWJAXWUMlOoGQHmsE45ViQ2KuBuASoYC4Wf+OUYxz6mQkgwAAN9mIrUReCXgAAAABJRU5ErkJggg=="); } .btnsuccess { background: #fff no-repeat center url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0ZDhlNWY5My05NmI0LTRlNWQtOGFjYi03ZTY4OGYyMTU2ZTYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDlBRDI3NjVGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDlBRDI3NjRGMkQ2MTFFNEI5NDBCMjQ2M0ExMDQ1OUYiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDphNWEzMWNhMC1hYmViLTQxNWEtYTEwZS04Y2U5NzRlN2Q4YTEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NGQ4ZTVmOTMtOTZiNC00ZTVkLThhY2ItN2U2ODhmMjE1NmU2Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+k+sHwwAAASZJREFUeNpi/P//PwMyKD8uZw+kUoDYEYgloMIvgHg/EM/ptHx0EFk9I8wAoEZ+IDUPiIMY8IN1QJwENOgj3ACo5gNAbMBAHLgAxA4gQ5igAnNJ0MwAVTsX7IKyY7L2UNuJAf+AmAmJ78AEDTBiwGYg5gbifCSxFCZoaBMCy4A4GOjnH0D6DpK4IxNSVIHAfSDOAeLraJrjgJp/AwPbHMhejiQnwYRmUzNQ4VQgDQqXK0ia/0I17wJiPmQNTNBEAgMlQIWiQA2vgWw7QppBekGxsAjIiEUSBNnsBDWEAY9mEFgMMgBk00E0iZtA7AHEctDQ58MRuA6wlLgGFMoMpIG1QFeGwAIxGZo8GUhIysmwQGSAZgwHaEZhICIzOaBkJkqyM0CAAQDGx279Jf50AAAAAABJRU5ErkJggg=="); } .refresh { cursor: pointer; width: 20px; height: 20px; position: absolute; z-index: 1; top: 0; right: 10px; opacity: .6; background: url('../assets/ref.jpg') no-repeat; background-size: cover; } </style>
完成效果圖
滑動完成時
因為允許1px的差距,可以自己改
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45