|
@@ -8,6 +8,7 @@ import { ref, onMounted } from "vue";
|
|
|
export const useImageVerify = (width = 120, height = 40) => {
|
|
|
const domRef = ref<HTMLCanvasElement>();
|
|
|
const imgCode = ref("");
|
|
|
+ const password = ref(0)
|
|
|
|
|
|
function setImgCode(code: string) {
|
|
|
imgCode.value = code;
|
|
@@ -15,9 +16,12 @@ export const useImageVerify = (width = 120, height = 40) => {
|
|
|
|
|
|
function getImgCode() {
|
|
|
if (!domRef.value) return;
|
|
|
- imgCode.value = draw(domRef.value, width, height);
|
|
|
+ const code = draw(domRef.value, width, height);
|
|
|
+ password.value = code.password
|
|
|
+ imgCode.value = code.imgCode
|
|
|
}
|
|
|
|
|
|
+
|
|
|
onMounted(() => {
|
|
|
getImgCode();
|
|
|
});
|
|
@@ -25,6 +29,7 @@ export const useImageVerify = (width = 120, height = 40) => {
|
|
|
return {
|
|
|
domRef,
|
|
|
imgCode,
|
|
|
+ password,
|
|
|
setImgCode,
|
|
|
getImgCode
|
|
|
};
|
|
@@ -35,6 +40,34 @@ function randomNum(min: number, max: number) {
|
|
|
return num;
|
|
|
}
|
|
|
|
|
|
+function generateArithmeticCaptcha() {
|
|
|
+ var firstNumber = Math.floor(Math.random() * 10)
|
|
|
+ var secondNumber = Math.floor(Math.random() * 10)
|
|
|
+ var operator = Math.random() < 0.5 ? '+' : (Math.random() < 0.5 ? '-' : '*')
|
|
|
+ var result
|
|
|
+
|
|
|
+ switch (operator) {
|
|
|
+ case '+':
|
|
|
+ result = firstNumber + secondNumber
|
|
|
+ break
|
|
|
+ case '-':
|
|
|
+ result = firstNumber - secondNumber
|
|
|
+ break
|
|
|
+ case '*':
|
|
|
+ result = firstNumber * secondNumber
|
|
|
+ break
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Number(result) < 0) {
|
|
|
+ return generateArithmeticCaptcha()
|
|
|
+ }
|
|
|
+
|
|
|
+ return {
|
|
|
+ subject: (`${firstNumber}${operator === '*' ? '×' : operator}${secondNumber}`).trim(),
|
|
|
+ answer: result
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
function randomColor(min: number, max: number) {
|
|
|
const r = randomNum(min, max);
|
|
|
const g = randomNum(min, max);
|
|
@@ -42,18 +75,27 @@ function randomColor(min: number, max: number) {
|
|
|
return `rgb(${r},${g},${b})`;
|
|
|
}
|
|
|
|
|
|
+const map = {
|
|
|
+ '+': '加',
|
|
|
+ '-': '减',
|
|
|
+ '×': '乘'
|
|
|
+}
|
|
|
+
|
|
|
function draw(dom: HTMLCanvasElement, width: number, height: number) {
|
|
|
let imgCode = "";
|
|
|
-
|
|
|
+ let password = 0
|
|
|
const NUMBER_STRING = "0123456789";
|
|
|
-
|
|
|
const ctx = dom.getContext("2d");
|
|
|
- if (!ctx) return imgCode;
|
|
|
-
|
|
|
+ if (!ctx) return {
|
|
|
+ imgCode,
|
|
|
+ password: 0
|
|
|
+ };
|
|
|
ctx.fillStyle = randomColor(180, 230);
|
|
|
ctx.fillRect(0, 0, width, height);
|
|
|
- for (let i = 0; i < 4; i += 1) {
|
|
|
- const text = NUMBER_STRING[randomNum(0, NUMBER_STRING.length)];
|
|
|
+ const code = generateArithmeticCaptcha();
|
|
|
+ password = code.answer
|
|
|
+ for (let i = 0; i < code.subject.length; i += 1) {
|
|
|
+ const text = map[code.subject[i]] || code.subject[i];
|
|
|
imgCode += text;
|
|
|
const fontSize = randomNum(18, 41);
|
|
|
const deg = randomNum(-30, 30);
|
|
@@ -66,20 +108,23 @@ function draw(dom: HTMLCanvasElement, width: number, height: number) {
|
|
|
ctx.fillText(text, -15 + 5, -15);
|
|
|
ctx.restore();
|
|
|
}
|
|
|
- for (let i = 0; i < 5; i += 1) {
|
|
|
- ctx.beginPath();
|
|
|
- ctx.moveTo(randomNum(0, width), randomNum(0, height));
|
|
|
- ctx.lineTo(randomNum(0, width), randomNum(0, height));
|
|
|
- ctx.strokeStyle = randomColor(180, 230);
|
|
|
- ctx.closePath();
|
|
|
- ctx.stroke();
|
|
|
- }
|
|
|
- for (let i = 0; i < 41; i += 1) {
|
|
|
- ctx.beginPath();
|
|
|
- ctx.arc(randomNum(0, width), randomNum(0, height), 1, 0, 2 * Math.PI);
|
|
|
- ctx.closePath();
|
|
|
- ctx.fillStyle = randomColor(150, 200);
|
|
|
- ctx.fill();
|
|
|
- }
|
|
|
- return imgCode;
|
|
|
+ // for (let i = 0; i < 5; i += 1) {
|
|
|
+ // ctx.beginPath();
|
|
|
+ // ctx.moveTo(randomNum(0, width), randomNum(0, height));
|
|
|
+ // ctx.lineTo(randomNum(0, width), randomNum(0, height));
|
|
|
+ // ctx.strokeStyle = randomColor(180, 230);
|
|
|
+ // ctx.closePath();
|
|
|
+ // ctx.stroke();
|
|
|
+ // }
|
|
|
+ // for (let i = 0; i < 41; i += 1) {
|
|
|
+ // ctx.beginPath();
|
|
|
+ // ctx.arc(randomNum(0, width), randomNum(0, height), 1, 0, 2 * Math.PI);
|
|
|
+ // ctx.closePath();
|
|
|
+ // ctx.fillStyle = randomColor(150, 200);
|
|
|
+ // ctx.fill();
|
|
|
+ // }
|
|
|
+ return {
|
|
|
+ imgCode,
|
|
|
+ password
|
|
|
+ };
|
|
|
}
|