🐯 uses div to write authentication

Friends let me write a pure front-end verification method, subtractive write a simple addition, subtraction, multiplication and division operation, total feeling little what

I looked at the missing background, so I added the background

Post this effect – code

The content of the 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>
Copy the code

The content of the 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;">The correct answer</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();
       })

        // Change to 16 bits
      function randomto16Sting (){
        return The '#'+parseInt(randomNumber(0xFFFFFF)).toString(16);
      }
      / / random number
      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; // Use interactively
        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="The present"
           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>
Copy the code

explain

General process:

  1. First get the node
  2. Use randomOption: this function to generate random numbers, and generate the symbols of addition, subtraction, multiplication and division we learned in primary school, but also to generate the answer to this algorithm. The division in this function, what I’m doing is, after two numbers, I’m multiplying to get the answer, which is the one that’s being divided, using data interchange, and then output the data. (This effect is to eliminate, blindly random, in addition to the problem).
  3. Click on the call to randomOption function once and it will refresh.

defects

Suddenly, I found that the single interface had no interference graph (just those colorful balls and lines), so I boldly wanted to use div to draw, of course, such an idea is indeed 🐯.

So I decided to use canvas to paint. ,

🐯 Use canvas canvas authentication

Gorgeous (flowery) whistles, inside the ball and line, but also let the text happened to rotate

Using canvas technology

  • A circle
  • Painting line
  • Draw the text

First, the use of canvas

The page needs to have a canvas node

<! Set the width and height of the canvas -->
 <canvas id="canvas" width="100" height="50"></canvas>
Copy the code

Js to get and use canvas

  let canvas = document.querySelector('#canvas'); // Get the canvas
  let ctx =canvas.getContext('2d'); // Open the 2D canvas
Copy the code

A circle

Here is the design code

       / / random number
      function randomNumber(number){
        return Math.random()*number
      }
      //randomRange Specifies the radius of the drawing circle
      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; // To ensure that the color is not affected by the strokeStyle below
        ctx.lineWidth = 1; // To ensure that its length is not affected by the lineWidth below
        ctx.stroke();
        ctx.closePath();
      }
Copy the code

Renderings (canvas enlarged 10 times to see the effect)

Painting line

Here is the design code

   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();
      }
Copy the code

Renderings (canvas enlarged 10 times to see the effect)

Draw the text

Here is the design code

The text is rotated

   // Change to 16 bits
      function randomto16Sting (){
        return The '#'+parseInt(randomNumber(0xFFFFFF)).toString(16);
      }
    / / font
     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();
     }
Copy the code

Renderings (canvas enlarged 10 times to see the effect)

My friend asked me again, why the font will not rotate that, I see others’ verification code, are crooked.

Since the friend mentioned, that will do ah! Put on enough of your own face

Rotate Angle design code

  function randomRotate(){
    let arr = [];
    let arr1 =[];
    let count = 0;
    // I am afraid that the random Angle is too different, so I write a little adjustment
      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 ++ ;
      }
      // This is to store the previous data, to eliminate the next rotation of Translate starting at the current position Angle.
      preRotateDeg.unshift(arr1);
      return arr1
  }
Copy the code

Font usage code

 function drawText(dataArray){
      / / CTX. Translate (0, 0);
      ctx.font = "26px Gaoel";
      ctx.textAlign ='center';
      ctx.textBaseline ='middle';
      let rotateNumber = randomRotate()
      // the canvas (0,0) has been rotated and needs to be fixed, i.e. pre takes a step back
      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();


 }
Copy the code

Renderings (canvas enlarged 10 times to see the effect)

🐯 General code

<! DOCTYPEhtml>
<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;">The correct answer</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()
           } 
       })
       // // Automatically refreshes every 30 seconds
      // setInterval(()=>{
      // randomOption(inputNode);
      / /}, 30000)
        // Change to 16-bit color specific
      function randomto16Sting (){
        return The '#'+parseInt(randomNumber(0xFFFFFF)).toString(16);
      }
      / / random number
      function randomNumber(number){
        return Math.random()*number
      }
      function randomRotate(){
        let arr = [];
        let arr1 =[];
        let count = 0;
        // I am afraid that the random Angle is too different, so I write a little adjustment
          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 ++ ;
          }
            // This is to store the previous data, to eliminate the next rotation of Translate starting at the current position Angle.
          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()
          // The data itself as the rotation point, need to be corrected, i.e. pre back a step
          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; // Use interactively
        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="The present"
           let answerFirst = firstNumber*secodeNumber;
           mul = firstNumber ;
           firstNumber = answerFirst;
           answer  = mul;
            break;
          default:
            break;
        }
        
        let dataArray = [firstNumber,operation,secodeNumber,answer];
          inputNode.value =  dataArray[3];
          // Clear the canvas
          ctx.clearRect(0.0,canvas.width,canvas.height)
          for (let index = 0; index < 60; index++) {
            // Draw the ball, pass the ball radius (range)
            drawArc(15);
          } 
          
          for (let index = 0; index < 6; index++) {
             // Draw a line, pass the line width (range)
            drawLine(4);
          } 

           // Draw to display text
          drawText(dataArray);
      }
    </script>
</body>
</html>
Copy the code

Effect:

🐯 epilogue

Good luck to you and me 🐮🐯