?使用div去写验证方式
朋友让我写一个纯前端的验证方法,唯唯诺诺的写了一个简单的加减乘除运算,总感觉少了点什么
我看了一下可能是少了一个背景,于是我加上了背景
贴出此效果–代码
style的内容
<style>
.verificationCode{
width: 100px;
height: 50px;
display: flex;
border: 1px black solid;
align-items: center;
justify-content: center;
user-select: none;
cursor: pointer;
}
.firstNumber{
font-size: 26px;
margin-right: 5px;
}
.operationNumber{
font-size: 26px;
margin-right: 5px;
}
.secodeNumber{
font-size: 26px;
}
.inputNumber{
padding: 9px;
width: 70px;
margin-left: 15px;
font-size: 24px;
}
.inputNumber::-webkit-inner-spin-button{
appearance: none;
}
.baibai{
display: flex;
margin: 0 auto;
}
</style>
复制代码
body的内容
<body>
<div class="baibai">
<div class="verificationCode">
<div class="firstNumber"></div>
<div class="operationNumber"></div>
<div class="secodeNumber"></div>
</div>
<label style="line-height: 50px;height: 50px;margin: 0 15px;"> 正确答案</label>
<input class="inputNumber" type="number">
</div>
<script>
let firstNumberNode = document.querySelector('.firstNumber');
let operationNumberNode = document.querySelector('.operationNumber');
let secodeNumberNode = document.querySelector('.secodeNumber');
let verificationCodeNode = document.querySelector('.verificationCode');
let inputNode = document.querySelector('.inputNumber');
randomOption(firstNumberNode,operationNumberNode,secodeNumberNode,inputNode);
verificationCodeNode.style.backgroundColor = randomto16Sting();
verificationCodeNode.addEventListener('click',()=>{
randomOption(firstNumberNode,operationNumberNode,secodeNumberNode,inputNode);
verificationCodeNode.style.backgroundColor = randomto16Sting();
})
//变成16位的
function randomto16Sting (){
return '#'+parseInt(randomNumber(0xFFFFFF)).toString(16);
}
//随机数
function randomNumber(number){
return Math.random()*number
}
function randomOption(firstNumberNode,operationNumberNode,secodeNumberNode,inputNode){
let firstNumber = Math.ceil(Math.random(1)*10);
let operationNumber = Math.ceil(Math.random()*4);
let secodeNumber = Math.ceil(Math.random(1)*10);
let answer = 0;
let mul = 0; //交互使用
switch (operationNumber) {
case 1:
operation="+";
answer = firstNumber+secodeNumber;
break;
case 2:
operation="-"
if(firstNumber < secodeNumber){
mul = firstNumber ;
firstNumber = secodeNumber;
secodeNumber = mul;
}
answer = firstNumber - secodeNumber;
break;
case 3:
operation="×"
answer = firstNumber*secodeNumber;
break;
case 4:
operation="÷"
let answerFirst = firstNumber*secodeNumber;
mul = firstNumber ;
firstNumber = answerFirst;
answer = mul;
break;
default:
break;
}
let dataArray = [firstNumber,operation,secodeNumber,answer];
firstNumberNode.innerHTML = dataArray[0];
operationNumberNode.innerHTML = dataArray[1];
secodeNumberNode.innerHTML = dataArray[2];
inputNode.value = dataArray[3];
firstNumberNode.style.color = randomto16Sting();
operationNumberNode.style.color = randomto16Sting();
secodeNumberNode.style.color = randomto16Sting();
}
</script>
</body>
复制代码
说明一下
大致流程:
- 首先获取结点
- 利用randomOption:这个函数生成随机数,和生成我们小学学过的加减乘除的符号,同时也是为了生成这个算法的答案。该函数中的除法,我采用的是,等到两个数之后,利用乘法获取答案,该答案就是被除者,使用数据交换,在输出数据。(这个效果是为了排除,一味的随机,除不尽问题)。
- 点击在调用一次randomOption函数,就会刷新。
缺陷
突然发现,单一的界面没有了干扰图(就那些花花绿绿的圆球与线条),我大胆的想使用div去画,当然这样的想法确实是?了。
于是我打算采用了canvas去画画。、
?使用canvas画验证方式
华丽(花里)胡哨,里面画了球与线段,还让文字发生了旋转
采取的canvas技术使用
- 画圆
- 画线段
- 画文字
先说canvas的使用
页面中需要有canvas的节点
<!-- 对canvas画布的宽高进行设定-->
<canvas id="canvas" width="100" height="50"></canvas>
复制代码
js中去获取与使用canvas
let canvas = document.querySelector('#canvas'); //获取画布
let ctx =canvas.getContext('2d'); //开启的2d的画布
复制代码
画圆
以下是设计代码
//随机数
function randomNumber(number){
return Math.random()*number
}
//randomRange 画圆的半径大小取值
function drawArc(randomRange){
let x = randomNumber(canvas.width);
let y = randomNumber(canvas.height);
let r = randomNumber(randomRange)+2;
let to16Sting = randomto16Sting();
ctx.beginPath();
ctx.arc(x,y,r,0,Math.PI*2);
ctx.fillStyle = to16Sting;
ctx.fill();
ctx.strokeStyle= to16Sting; //为了确保自身的颜色,不被下面的strokeStyle影响
ctx.lineWidth = 1; //为了确保自身的长度,不被下面的lineWidth影响
ctx.stroke();
ctx.closePath();
}
复制代码
效果图(为看见效果canvas扩大了10倍)
画线段
以下是设计代码
function drawLine(randomRange){
ctx.beginPath();
let x1 = randomNumber(canvas.width - 10)+10;
let y1 = randomNumber(canvas.height - 10)+10;
let x2 = randomNumber(canvas.width - 10)+10;
let y2 = randomNumber(canvas.height - 10)+10;
ctx.moveTo(x1,y1);
ctx.lineTo(x2,y2);
ctx.strokeStyle= randomto16Sting();
ctx.lineWidth=randomNumber(randomRange)+1;
ctx.stroke();
ctx.closePath();
}
复制代码
效果图(为看见效果canvas扩大了10倍)
画文字
以下是设计代码
文字是带有旋转的
//变成16位的
function randomto16Sting (){
return '#'+parseInt(randomNumber(0xFFFFFF)).toString(16);
}
//画字体
function drawText(dataArray){
// ctx.translate(0,0);
ctx.font = "26px Gaoel";
ctx.textAlign ='center';
ctx.textBaseline ='middle';
ctx.fillText(dataArray[0],20,25);
ctx.fillStyle = randomto16Sting();
ctx.fillText(dataArray[1],50,25);
ctx.fillStyle = randomto16Sting();
ctx.fillText(dataArray[2],80,25);
ctx.fillStyle = randomto16Sting();
}
复制代码
效果图(为看见效果canvas扩大了10倍)
朋友又又给我提问了,为什么字体不会旋转那,我看别人的验证码,都是歪歪扭扭的。
朋友既然提了,那就要搞啊!,自身的面子要装足
旋转角度设计代码
function randomRotate(){
let arr = [];
let arr1 =[];
let count = 0;
//担心随机出的角度太差距,所以写出的一点调整
while(count < 3 ){
switch (count) {
case 0:
arr.push(randomNumber(10))
break;
case 1:
arr.push(randomNumber(10))
break;
case 2:
arr.push(randomNumber(10))
let sum = arr.reduce((a,b) =>{
return a+b;
},0)
if(Math.max(...arr)/sum > 0.6){
arr[arr.indexOf(Math.max(...arr))] = - sum/(sum*0.6);
}else{
arr[arr.indexOf(Math.max(...arr))] = - Math.max(...arr);
}
arr1 = arr.map(element=>{
return element*Math.PI/180;
})
break;
default:
break;
}
count ++ ;
}
//这个是为了存储上一次的数据,为了消除translate的下次旋转以当前位置角度开始。
preRotateDeg.unshift(arr1);
return arr1
}
复制代码
字体使用代码
function drawText(dataArray){
// ctx.translate(0,0);
ctx.font = "26px Gaoel";
ctx.textAlign ='center';
ctx.textBaseline ='middle';
let rotateNumber = randomRotate()
// 以画布(0,0)作为了旋转点了,需要修正,也就是pre后退一步
ctx.rotate(-preRotateDeg[1][0])
ctx.rotate(rotateNumber[0]);
ctx.fillText(dataArray[0],20,25);
ctx.fillStyle = randomto16Sting();
ctx.rotate(-preRotateDeg[1][1])
ctx.rotate(rotateNumber[1]);
ctx.fillText(dataArray[1],50,25);
ctx.fillStyle = randomto16Sting();
ctx.rotate(-preRotateDeg[1][2])
ctx.rotate(rotateNumber[2]);
ctx.fillText(dataArray[2],80,25);
ctx.fillStyle = randomto16Sting();
}
复制代码
效果图(为看见效果canvas扩大了10倍)
?总体代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.verificationCode{
width: 100px;
height: 50px;
display: flex;
align-items: center;
justify-content: center;
user-select: none;
cursor: pointer;
}
.inputNumber{
padding: 9px;
width: 70px;
margin-left: 15px;
font-size: 24px;
}
.inputNumber::-webkit-inner-spin-button{
appearance: none;
}
.baibai{
display: flex;
margin: 0 auto;
}
</style>
</head>
<body>
<div class="baibai">
<div class="verificationCode">
<canvas id="canvas" width="100" height="50"></canvas>
</div>
<label style="line-height: 50px;height: 50px;margin: 0 15px;"> 正确答案</label>
<input class="inputNumber" type="number">
</div>
<script>
let canvas = document.querySelector('#canvas');
let ctx =canvas.getContext('2d');
let verificationCodeNode = document.querySelector('.verificationCode');
let inputNode = document.querySelector('.inputNumber');
let preRotateDeg =[[0,0,0]];
randomOption(inputNode);
verificationCodeNode.addEventListener('click',()=>{
randomOption(inputNode);
if(preRotateDeg.length == 3){
preRotateDeg.pop()
}
})
// //定时30秒自动刷新一次
// setInterval(()=>{
// randomOption(inputNode);
// } ,30000)
//变成16位的颜色专用
function randomto16Sting (){
return '#'+parseInt(randomNumber(0xFFFFFF)).toString(16);
}
//随机数
function randomNumber(number){
return Math.random()*number
}
function randomRotate(){
let arr = [];
let arr1 =[];
let count = 0;
//担心随机出的角度太差距,所以写出的一点调整
while(count < 3 ){
switch (count) {
case 0:
arr.push(randomNumber(10))
break;
case 1:
arr.push(randomNumber(10))
break;
case 2:
arr.push(randomNumber(10))
let sum = arr.reduce((a,b) =>{
return a+b;
},0)
if(Math.max(...arr)/sum > 0.6){
arr[arr.indexOf(Math.max(...arr))] = - sum/(sum*0.6);
}else{
arr[arr.indexOf(Math.max(...arr))] = - Math.max(...arr);
}
arr1 = arr.map(element=>{
return element*Math.PI/180;
})
break;
default:
break;
}
count ++ ;
}
//这个是为了存储上一次的数据,为了消除translate的下次旋转以当前位置角度开始。
preRotateDeg.unshift(arr1);
return arr1
}
function drawArc(randomRange){
let x = randomNumber(canvas.width);
let y = randomNumber(canvas.height);
let r = randomNumber(randomRange)+2;
let to16Sting = randomto16Sting();
ctx.beginPath();
ctx.arc(x,y,r,0,Math.PI*2);
ctx.fillStyle = to16Sting;
ctx.fill();
ctx.strokeStyle= to16Sting;
ctx.lineWidth = 1;
ctx.stroke();
ctx.closePath();
}
function drawLine(randomRange){
ctx.beginPath();
let x1 = randomNumber(canvas.width - 10)+10;
let y1 = randomNumber(canvas.height - 10)+10;
let x2 = randomNumber(canvas.width - 10)+10;
let y2 = randomNumber(canvas.height - 10)+10;
ctx.moveTo(x1,y1);
ctx.lineTo(x2,y2);
ctx.strokeStyle= randomto16Sting();
ctx.lineWidth=randomNumber(randomRange)+1;
ctx.stroke();
ctx.closePath();
}
function drawText(dataArray){
// ctx.translate(0,0);
ctx.font = "26px Gaoel";
ctx.textAlign ='center';
ctx.textBaseline ='middle';
let rotateNumber = randomRotate()
// 以数据的本身作为了旋转点了,需要修正,也就是pre后退一步
ctx.rotate(-preRotateDeg[1][0])
ctx.rotate(rotateNumber[0]);
ctx.fillText(dataArray[0],20,25);
ctx.fillStyle = randomto16Sting();
ctx.rotate(-preRotateDeg[1][1])
ctx.rotate(rotateNumber[1]);
ctx.fillText(dataArray[1],50,25);
ctx.fillStyle = randomto16Sting();
ctx.rotate(-preRotateDeg[1][2])
ctx.rotate(rotateNumber[2]);
ctx.fillText(dataArray[2],80,25);
ctx.fillStyle = randomto16Sting();
}
function randomOption(inputNode){
let firstNumber = Math.ceil(Math.random(1)*10);
let operationNumber = Math.ceil(Math.random()*4);
let secodeNumber = Math.ceil(Math.random(1)*10);
let answer = 0;
let mul = 0; //交互使用
switch (operationNumber) {
case 1:
operation="+";
answer = firstNumber+secodeNumber;
break;
case 2:
operation="-"
if(firstNumber < secodeNumber){
mul = firstNumber ;
firstNumber = secodeNumber;
secodeNumber = mul;
}
answer = firstNumber - secodeNumber;
break;
case 3:
operation="×"
answer = firstNumber*secodeNumber;
break;
case 4:
operation="÷"
let answerFirst = firstNumber*secodeNumber;
mul = firstNumber ;
firstNumber = answerFirst;
answer = mul;
break;
default:
break;
}
let dataArray = [firstNumber,operation,secodeNumber,answer];
inputNode.value = dataArray[3];
//清除画布
ctx.clearRect(0,0,canvas.width,canvas.height)
for (let index = 0; index < 60; index++) {
//画球,传画球的半径(范围)
drawArc(15);
}
for (let index = 0; index < 6; index++) {
//画线,传画线的线宽(范围)
drawLine(4);
}
//画显示文字
drawText(dataArray);
}
</script>
</body>
</html>
复制代码
效果图:
?结语
祝你我好运??
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END