記錄--使用Canvas繪製一個驗證碼組件

来源:https://www.cnblogs.com/smileZAZ/archive/2023/09/22/17723036.html
-Advertisement-
Play Games

這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 使用Canvas繪製一個驗證碼組件 前言 驗證碼,這一日常伴隨我們的要素,是我們線上交互的重要安全保障。你的手機簡訊里是否被它占據半壁江山,今天我們就來聊聊如何在網頁上實現一個簡單的驗證碼組件。大家在登錄網站時為了防止被惡意攻擊或者多次點 ...


這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

使用Canvas繪製一個驗證碼組件

前言

驗證碼,這一日常伴隨我們的要素,是我們線上交互的重要安全保障。你的手機簡訊里是否被它占據半壁江山,今天我們就來聊聊如何在網頁上實現一個簡單的驗證碼組件。大家在登錄網站時為了防止被惡意攻擊或者多次點擊操作,使用驗證碼是最常用的實現方式。在學習完Canvas後,通過Canvas實現簡單的驗證碼就比較簡單了,該組件已開源上傳npm,可以直接安裝使用,源碼已上傳Git,地址在文尾。

聊聊Canvas

1、在開始繪製Canvas時,我們需要先創建一個html節點,併為其設置寬高

<canvas id="canvas" width="200" height="150""></canvas>

2、可以使用 cnv.width 和 cnv.height 分別獲取 Canvas 的寬度和高度,可以使用 cnv.getContext("2d")來獲取 canvas 2D 上下文環境對象。

如何繪製一條直線

使用canvas的 moveTo()和 lineTo()方法,比如將畫筆moveTo(0,0),移動畫筆到極點坐標,使用lineTo(100,100),這樣執行完兩個步驟將能夠繪製一條從坐標(0,0)到坐標(100,100)的一條直線,不過此時canvas上並不會展示出一條直線,我們還需要調用stroke()方法結束繪畫,這樣就能在頁面上看到一條直線。

隨機畫一條直線:

    context.moveTo(Math.random() * Canvas_DOM.width, Math.random() * Canvas_DOM.height);
    context.lineTo(Math.random() * Canvas_DOM.width, Math.random() * Canvas_DOM.height);

如何繪製一個點

從上面我們知道瞭如何繪製一條直線,那麼繪製一個點其實就是繪製一個長度為1的直線。

繪製一個隨機點:

    var x = Math.random() * Canvas_DOM.width;
    var y = Math.random() * Canvas_DOM.height;
    context.moveTo(x, y);
    context.lineTo(x + 1, y + 1);

怎麼繪製文字

通過fillText(txt, 0, 0)就能在canvas里添加一個文字,其中txt為需要繪製的內容,後面兩個參數為文字在canvas中的位置,當然也可以通過rotate()和translate()來改變文字的方向和位置。

    context.fillText(txt, 0, 0);
    context.rotate(-deg);
    context.translate(-x, -y);

使用fillStyle可以修改文字、線條的顏色

繪製驗證碼組件

從上面我們知道瞭如何繪製直線、點、以及文字,那麼一個驗證碼也就由這些組成,我們只需要把他們結合起來,在點擊驗證碼時,重新繪製一個隨機的canvas,就能得到一個完整的驗證碼組件:

<template>
    <canvas class="canvas" ref="cav" @click="Refresh"></canvas>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
const show_num = ref<any>([])
const cav = ref<any>(null)
onMounted(() => {
    draw();
});
const draw = () => {
    var Canvas_DOM = cav.value;
    var cav_width = Canvas_DOM.clientWidth;
    var cav_height = Canvas_DOM.clientHeight;
    var context = Canvas_DOM.getContext('2d');
    Canvas_DOM.width = cav_width;
    Canvas_DOM.height = cav_height;
    var sCode = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,1,2,3,4,5,6,7,8,9,0";
    var aCode = sCode.split(',');
    var aLength = aCode.length; //獲取到數組的長度

    for (var i = 0; i <= 3; i++) {
        var j = Math.floor(Math.random() * aLength); //獲取到隨機的索引值
        var deg = (Math.random() * 30 * Math.PI) / 180; //產生0~30之間的隨機弧度
        var txt = aCode[j]; //得到隨機的一個內容
        show_num.value[i] = txt.toLowerCase();
        var x = 50 + i * 20; //文字在canvas上的x坐標
        var y = 20 + Math.random() * 8; //文字在canvas上的y坐標
        context.font = 'bold 23px 微軟雅黑';

        context.translate(x, y);
        context.rotate(deg);

        context.fillStyle = _randomColor();
        context.fillText(txt, 0, 0);
        context.rotate(-deg);
        context.translate(-x, -y);
    }
    for (var i = 0; i <= 5; i++) {
        //驗證碼上顯示隨機線條
        context.strokeStyle = _randomColor();
        context.beginPath();
        context.moveTo(Math.random() * Canvas_DOM.width, Math.random() * Canvas_DOM.height);
        context.lineTo(Math.random() * Canvas_DOM.width, Math.random() * Canvas_DOM.height);
        context.stroke();
    }
    for (var i = 0; i <= 30; i++) {
        //驗證碼上顯示隨機小點
        context.strokeStyle = _randomColor();
        context.beginPath();
        var x = Math.random() * Canvas_DOM.width;
        var y = Math.random() * Canvas_DOM.height;
        context.moveTo(x, y);
        context.lineTo(x + 1, y + 1);
        context.stroke();
    }
}
const _randomColor = () => {
    //得到隨機的顏色值
    var r = Math.floor(Math.random() * 256);
    var g = Math.floor(Math.random() * 256);
    var b = Math.floor(Math.random() * 256);
    return 'rgb(' + r + ',' + g + ',' + b + ')';
}
const Refresh = () => {
    draw();
}
</script>
<style  scoped>
.canvas {
    width: 200px;
    height: 40px;
    display: inline-block;
    margin-left: 12px;
    cursor: pointer;
}
</style>

使用示例

npm install @fcli/vue-vercode --save-dev 來安裝

在項目中使用
import VerCode from '@fcli/vue-vercode';
const app=createApp(App)
app.use(VerCode);
示例:
<div class="content">
    <ver-code ref=verCode></ver-code>
</div>

獲取驗證碼組件的數據

let code = verCode.value.show_num.join('');

本文轉載於:

https://juejin.cn/post/7280786332712173626

如果對您有所幫助,歡迎您點個關註,我會定時更新技術文檔,大家一起討論學習,一起進步。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、首先你需要提前準備好jar包或者war包,並想辦法放入Linux環境(或虛擬機)中; 2、java項目的部署需要用到Tomcat或者Jetty,docker可以直接拉取他倆的鏡像,這裡以Tomcat為例: # : 後面需要加上war或者jar對應的Tomcat版本,最好加上, # 否則預設最新的 ...
  • 一、文檔的查看指令 1、tail指令 作用:查看一個文件的末n行 語法:#tail -n 文件的路徑 說明:-n可以不寫,不寫,預設表示10行。 案例:新建一個1.txt文檔,使用tail指令查看root/1.txt文件的末5行和末10行 tail -5 /root/1.txt tail /root ...
  • 1. 線上備份 2. 離線備份 2.1. 關閉MySQL做備份是最簡單、最安全的 2.2. 所有獲取一致性副本的方法中最好的 2.3. 損壞或不一致的風險最小 2.4. 根本不用關心InnoDB緩衝池中的臟頁或其他緩存 2.5. 不需要擔心數據在嘗試備份的過程中被修改 2.5.1. 伺服器不對應用提 ...
  • MySQL 主從複製與讀寫分離 1、什麼是讀寫分離? 讀寫分離,基本的原理是讓主資料庫處理事務性增、改、刪操作(INSERT、UPDATE、DELETE),而從資料庫處理SELECT查詢操作。資料庫複製被用來把事務性操作導致的變更同步到集群中的從資料庫。 2、為什麼要讀寫分離呢? 因為資料庫的“寫” ...
  • 最近,某白酒品牌頻頻吸引大眾眼球,白酒與咖啡、巧克力等聯名衍生品一經推出便掀起熱潮。某商品由於太過火爆,甚至一度售罄下架。 不得不說,我國擁有超大規模內需市場,消費潛力巨大。 當前,創新消費場景加上數字化融合轉型,成為酒企品牌開疆擴土、逆勢增長的重要途徑。 如今越來越多的酒企開始擁抱數字化,建立涵蓋 ...
  • 1. 每個人都知道需要備份,但並不是每個人都能意識到需要的是可恢復的備份 1.1. 如果你沒有提前做好備份規劃,也許以後會發現已經錯失了一些最佳的選擇 1.2. 在伺服器已經配置好以後,才想起應該使用LVM,以便獲取文件系統的快照——但這時已經太遲了 1.3. 如果你沒有計劃做定期的恢復演練,當真的 ...
  • 在日常開發中,很多時候需要對數組進行分組,每次都要手寫一個分組函數,或者使用lodash的groupBy函數。好消息是,JavaScript 現在正在引入全新的分組方法:Object.groupBy和Map.groupBy,以後再也不需要手寫分組函數了,目前最新版本的 Chrome(117)已經支持 ...
  • 前言 Vue 3是一個功能強大的前端框架,它引入了一些令人興奮的新特性,其中最引人註目的是ref和reactive。這兩個API是Vue 3中響應式編程的核心,本文將深入探討它們的用法和差異。 什麼是響應式編程? 在Vue中,響應式編程是一種使數據與UI保持同步的方式。當數據變化時,UI會自動更新, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...