热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用CSS和javascript制作拼图验证码

源码代码下载gitgitee.com:mryangjianxinpuzzle-verification-code.git首先,我们要了解一个拼图验证码所时怎么组成

源码代码下载

git@gitee.com:mryangjianxin/puzzle-verification-code.git

首先,我们要了解一个拼图验证码所时怎么组成的

  • 一个完整的图片
  • 一个在图片上的遮罩层,来区别我们需要填充的位置,和我们要移动的”块“
  • 一个可以操作”块“的滑动条

  1. 得到一个居中的图片

DOCTYPE html>
<html lang&#61;"en"><head><meta charset&#61;"UTF-8"><meta http-equiv&#61;"X-UA-Compatible" content&#61;"IE&#61;edge"><meta name&#61;"viewport" content&#61;"width&#61;device-width, initial-scale&#61;1.0"><title>拼图验证码实现title><link rel&#61;"stylesheet" href&#61;"css/VerificationCode.css" type&#61;"text/css">
head><body><div id&#61;"captcha">div>
body><script type&#61;"text/Javascript" src&#61;"js/VerificationCode.js">script>html>

body {display: flex;justify-content: center;align-items: center;min-height: 100vh;
}#captcha {--width: 400px;--height: 260px;display: block;width: var(--width);height: var(--height);border-radius: 4px;background-image: url(https://images.unsplash.com/photo-1606787366850-de6330128bfc?ixlib&#61;rb-1.2.1&ixid&#61;MnwxMjA3fDB8MHxwzaG90by1wYWdlfHx8fGVufDB8fHx8&auto&#61;format&fit&#61;crop&w&#61;2700&q&#61;80);background-size: cover;background-position: center;position: relative;box-shadow: 0px 2px 4px rgba(0, 0, 0, .3);
}

结果如下&#xff1a;
显示结果

  1. 利用 Pseudo Element 伪元素创造一个缺口

inset()      函数是一个图形函数&#xff0c;用于指定某种基本图形类型。inset()函数用于定义矩形。


calc()       此 CSS 函数允许在声明 CSS 属性值时执行一些计算。


-webkit     这种就叫做浏览器私有前缀&#xff0c;是浏览器对于新CSS属性的一个提前支持


ackground-blend-mode 属性定义每个背景层&#xff08;颜色和/或图像&#xff09;的混合模式。

#captcha {--puzzle-width: 80px;--puzzle-height: 80px;
}#captcha::before,
#captcha::after
{position: absolute;content: &#39;拼图&#39;;display: block;width: inherit;height: inherit;background-image: inherit;/* background-color: red; */background-size: inherit;background-position: inherit;clip-path: inset(calc((var(--height) - var(--puzzle-height)) / 2)/* 90px */var(--puzzle-width)/* 90px */calc((var(--height) - var(--puzzle-height)) / 2)/* 90px */calc(var(--width) - var(--puzzle-width) * 2)/* 230px */);/* -webkit 私有前缀 */-webkit-clip-path: inset(/* 由上向内方向缩小 */calc((var(--height) - var(--puzzle-height)) / 2)/* 90px *//* 右向内方向缩小 */var(--puzzle-width)/* 90px *//* 由下向内方向缩小 */calc((var(--height) - var(--puzzle-height)) / 2)/* 90px *//* 左向内方向缩小 */calc(var(--width) - var(--puzzle-width) * 2)/* 230px */);
}#captcha::after {transform: translatex(calc((var(--width)*-1)))
}#captcha::before {background-color: rgba(0, 0, 0, .6);background-blend-mode: multiply;
}

在这里插入图片描述

  1. 实现滚动条
    在实现滚动条时我们使用的是在原来的基础上在下面添块级元素&#xff0c;注意&#xff1a;我们这里不使用伪元素来实现原因是在Javascript中不能直接监听伪类元素的事件&#xff0c;是为了后面我们使用Javascript操作做准备

clamp() 函数的作用是把一个值限制在一个上限和下限之间&#xff0c;当这个值超过最小值和最大值的范围时&#xff0c;在最小值和最大值之间选择一个值使用。它接收三个参数&#xff1a;最小值、首选值、最大值。

<div id&#61;"captcha"><div id&#61;"handle"><span>span>div>div>

注意&#xff1a;由于我们使用了clamp()函数&#xff0c;限制了按钮的最大值和最小值&#xff0c;我们发现我们移动的块也是随着移动的&#xff0c;我们就可以使用同一个值来修改&#xff0c;这样就可以达到按钮和拼图的同步

#captcha {--moved: 0px;
}

#captcha::after {transform: translatex(calc((var(--width)*-1)))
}

修改为

#captcha::after {transform: translatex(clamp(calc(var(--width) * -1),calc((var(--width) * -1) &#43; var(--moved)),calc(var(--puzzle-width))));
}

/* 滚动条 */
#handle {width: calc(var(--width) &#43; var(--puzzle-width) * 2);height: 30px;border-radius: 18px;background-color: #eee;position: absolute;bottom: -50px;left: calc(var(--puzzle-width) * 2 * -1);box-shadow: inset 0px 0px 12px rgba(0, 0, 0, .2);border: 3px solid #ccc;
}/* 拖动的按钮 */
#handle span {display: block;width: var(--puzzle-width);height: inherit;border-radius: inherit;background-color: #fff;box-shadow: inset 0px 0px 6px rgba(0, 0, 0, .25), 0px 2px 4px rgba(0, 0, 0, .3);position: absolute;cursor: move;transform: translatex(clamp(0px,var(--moved),calc(var(--width) &#43; var(--puzzle-width))));
}

当我们修改 --moved 值时&#xff0c;就会出现以下及结果
在这里插入图片描述

  1. 加入Javascript逻辑&#xff0c;更改–moved 的值

const captcha &#61; document.querySelector(&#39;#captcha&#39;)
const handle &#61; document.querySelector(&#39;#handle&#39;)
const button &#61; document.querySelector(&#39;#handle span&#39;)//点击时
button.addEventListener(&#39;mousedown&#39;, (e) &#61;> {
}
//移动时window.addEventListener(&#39;mousemove&#39;, (e) &#61;> {}
//放手时window.addEventListener(&#39;mouseup&#39;, (e) &#61;> {}

在这里我们需要定义一个flag (shouldMove)&#xff0c;来判断他是否在点击状态

Element.getBoundingClientRect() 方法返回元素的大小及其相对于视口的位置。


setProperty() 方法用于设置一个新的 CSS 属性&#xff0c;同时也可以修改 CSS 声明块中已存在的属性。

let shouldMove &#61; falsebutton.addEventListener(&#39;mousedown&#39;, (e) &#61;> {shouldMove &#61; true
})window.addEventListener(&#39;mouseup&#39;, (e) &#61;> {if (shouldMove) {}
}

我们最终的Javascript代码

let shouldMove &#61; false
const captcha &#61; document.querySelector(&#39;#captcha&#39;)
const handle &#61; document.querySelector(&#39;#handle&#39;)
const button &#61; document.querySelector(&#39;#handle span&#39;)
//点击时
button.addEventListener(&#39;mousedown&#39;, (e) &#61;> {shouldMove &#61; true
})
//移动时
window.addEventListener(&#39;mousemove&#39;, (e) &#61;> {if (shouldMove) {const offsetLeft &#61; handle.getBoundingClientRect().leftconst buttonWidth &#61; button.getBoundingClientRect().width// 游标的X位置&#xff0c;减滚动条与左边的位置&#xff0c;在减去按钮宽度除2&#xff08;除2的原因的是中心点设定到按钮的中间位置&#xff09;captcha.style.setProperty(&#39;--moved&#39;, &#96;${e.clientX - offsetLeft - buttonWidth / 2}px&#96;)}
})
// 放手时
window.addEventListener(&#39;mouseup&#39;, (e) &#61;> {if (shouldMove) {//获取我们鼠标离开时我们拖动的个距离const finalOffset &#61; e.clientX - handle.getBoundingClientRect().left// console.log(finalOffset);if (finalOffset >&#61; 430 && finalOffset <&#61; 450) {// passcaptcha.classList.add(&#39;passed&#39;)} else {// failedcaptcha.style.setProperty(&#39;--moved&#39;, &#39;0px&#39;)}shouldMove &#61; false}
})

到我们拼图满足条件时&#xff0c;我们就要将拼图 “拼接” 在图片上&#xff0c;也就是让遮罩层的透明度改为0

#captcha.passed::before,
#captcha.passed::after,
#captcha.passed #handle {opacity: 0;
}

  1. 优化&#xff0c;加入回弹效果
    但是我们发现&#xff0c;按钮和拼图在移动和拼接时都是非产地个生硬
    我们在为 #handle span 设置 transition 时&#xff0c;发现不会套用在拖到过程中

#handle span {transition: .25s all ease-in-out;
}

所以我们可以通过active &#xff0c;即在点下去时设定状态为transition为none

#captcha:active #handle span {transition: none;
}

同时也设定到#captcha::after中

#captcha::after{transition: .25s all ease-in-out;
}
#captcha:active::after {transition: none;
}

参考文献

快速访问视频
快速访问文章


推荐阅读
  • 导航栏样式练习:项目实例解析
    本文详细介绍了如何创建一个具有动态效果的导航栏,包括HTML、CSS和JavaScript代码的实现,并附有详细的说明和效果图。 ... [详细]
  • 前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ... [详细]
  • 本文详细介绍了Java中org.neo4j.helpers.collection.Iterators.single()方法的功能、使用场景及代码示例,帮助开发者更好地理解和应用该方法。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • golang常用库:配置文件解析库/管理工具viper使用
    golang常用库:配置文件解析库管理工具-viper使用-一、viper简介viper配置管理解析库,是由大神SteveFrancia开发,他在google领导着golang的 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 本文介绍了如何使用JQuery实现省市二级联动和表单验证。首先,通过change事件监听用户选择的省份,并动态加载对应的城市列表。其次,详细讲解了使用Validation插件进行表单验证的方法,包括内置规则、自定义规则及实时验证功能。 ... [详细]
  • 本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • JavaScript中属性节点的类型及应用
    本文深入探讨了JavaScript中属性节点的不同类型及其在实际开发中的应用,帮助开发者更好地理解和处理HTML元素的属性。通过具体的案例和代码示例,我们将详细解析如何操作这些属性节点。 ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • 本文详细介绍了 Apache Jena 库中的 Txn.executeWrite 方法,通过多个实际代码示例展示了其在不同场景下的应用,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 使用Vultr云服务器和Namesilo域名搭建个人网站
    本文详细介绍了如何通过Vultr云服务器和Namesilo域名搭建一个功能齐全的个人网站,包括购买、配置服务器以及绑定域名的具体步骤。文章还提供了详细的命令行操作指南,帮助读者顺利完成建站过程。 ... [详细]
author-avatar
陈奇江娇谦
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有