Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(captcha): add hollow-shape prop (#458)
* feat: add path process prop * feat: update
- Loading branch information
Showing
8 changed files
with
417 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
export interface CaptchaHollowOptions { | ||
ctx: CanvasRenderingContext2D, | ||
/** | ||
* The x coordinate of slide target center | ||
*/ | ||
x: number, | ||
/** | ||
* The y coordinate of slide target center | ||
*/ | ||
y: number, | ||
/** | ||
* Current canvas width | ||
*/ | ||
width: number, | ||
/** | ||
* Current canvas height | ||
*/ | ||
height: number | ||
} | ||
|
||
/** | ||
* Specify the react of the hollow's shape | ||
*/ | ||
export type CaptchaHollowResult = [x: number, y: number, width: number, height: number] | ||
export type CaptchaHollowProcess = (options: CaptchaHollowOptions) => CaptchaHollowResult | ||
|
||
export type CaptchaHollowType = 'square' | 'puzzle' | 'shield' | 'heart' | ||
|
||
export const squarePath: CaptchaHollowProcess = ({ ctx, x, y, width, height }) => { | ||
const side = Math.min(width, height) * 0.25 | ||
const halfSide = side * 0.5 | ||
|
||
ctx.moveTo(x - halfSide, y - halfSide) | ||
ctx.lineTo(x + halfSide, y - halfSide) | ||
ctx.lineTo(x + halfSide, y + halfSide) | ||
ctx.lineTo(x - halfSide, y + halfSide) | ||
ctx.closePath() | ||
|
||
return [x - halfSide - 2, y - halfSide - 2, side + 4, side + 4] | ||
} | ||
|
||
export const puzzlePath: CaptchaHollowProcess = ({ ctx, x, y, width, height }) => { | ||
const side = Math.min(width, height) * 0.2 | ||
const halfSide = side * 0.5 | ||
const left = x - halfSide | ||
const top = y - halfSide | ||
const radius = side * 0.2 | ||
|
||
ctx.moveTo(left, top) | ||
ctx.arc(left + halfSide, top - radius + 2, radius, 0.72 * Math.PI, 2.26 * Math.PI) | ||
ctx.lineTo(left + side, top) | ||
ctx.arc(left + side + radius - 2, top + halfSide, radius, 1.21 * Math.PI, 2.78 * Math.PI) | ||
ctx.lineTo(left + side, top + side) | ||
ctx.lineTo(left, top + side) | ||
ctx.arc(left + radius - 2, top + halfSide, radius + 0.4, 2.76 * Math.PI, 1.24 * Math.PI, true) | ||
ctx.lineTo(left, top) | ||
|
||
return [x - halfSide - 2, y - side * 0.9 - 2, side * 1.4 + 4, side * 1.4 + 4] | ||
} | ||
|
||
export const shieldPath: CaptchaHollowProcess = ({ ctx, x, y, width, height }) => { | ||
const side = Math.min(width, height) * 0.25 | ||
const halfSide = side * 0.5 | ||
|
||
ctx.moveTo(x, y - halfSide) | ||
ctx.bezierCurveTo( | ||
x, | ||
y - halfSide + side * 0.05, | ||
x - halfSide + side * 0.3, | ||
y - halfSide * 0.5 + side * 0.1, | ||
x - halfSide, | ||
y - halfSide * 0.7 | ||
) | ||
ctx.bezierCurveTo(x - halfSide, y + side * 0.3, x - side * 0.1, y + halfSide, x, y + halfSide) | ||
ctx.bezierCurveTo( | ||
x + side * 0.1, | ||
y + halfSide, | ||
x + halfSide, | ||
y + side * 0.3, | ||
x + halfSide, | ||
y - halfSide * 0.7 | ||
) | ||
ctx.bezierCurveTo( | ||
x + halfSide - side * 0.3, | ||
y - halfSide * 0.5 + side * 0.1, | ||
x, | ||
y - halfSide + side * 0.05, | ||
x, | ||
y - halfSide | ||
) | ||
|
||
return [x - halfSide - 2, y - halfSide - 2, side + 4, side + 4] | ||
} | ||
|
||
export const heartPath: CaptchaHollowProcess = ({ ctx, x, y, width, height }) => { | ||
const side = Math.min(width, height) * 0.25 | ||
const halfSide = side * 0.5 | ||
|
||
ctx.moveTo(x, y - side * 0.25) | ||
ctx.bezierCurveTo( | ||
x, | ||
y - side * 0.4, | ||
x - side * 0.1, | ||
y - halfSide, | ||
x - halfSide * 0.5, | ||
y - halfSide | ||
) | ||
ctx.bezierCurveTo( | ||
x - halfSide * 0.5 - side * 0.1, | ||
y - halfSide, | ||
x - halfSide, | ||
y - side * 0.4, | ||
x - halfSide, | ||
y - side * 0.2 | ||
) | ||
ctx.bezierCurveTo( | ||
x - halfSide, | ||
y + side * 0.2, | ||
x - side * 0.05, | ||
y + halfSide * 0.8, | ||
x, | ||
y + halfSide * 0.8 | ||
) | ||
ctx.bezierCurveTo( | ||
x + side * 0.05, | ||
y + halfSide * 0.8, | ||
x + halfSide, | ||
y + side * 0.2, | ||
x + halfSide, | ||
y - side * 0.2 | ||
) | ||
ctx.bezierCurveTo( | ||
x + halfSide, | ||
y - side * 0.4, | ||
x + halfSide * 0.5 + side * 0.1, | ||
y - halfSide, | ||
x + halfSide * 0.5, | ||
y - halfSide | ||
) | ||
ctx.bezierCurveTo(x + side * 0.1, y - halfSide, x, y - side * 0.4, x, y - side * 0.25) | ||
|
||
return [x - halfSide - 2, y - halfSide - 2, side + 4, side * 0.9 + 4] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
export { default as Captcha } from './captcha' | ||
|
||
export type { CaptchaProps, CaptchaCProps } from './props' | ||
export type * from './hollow-paths' | ||
export type { CaptchaType, CaptchaBeforeTest, CaptchaExposed } from './symbol' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<template> | ||
<Space vertical> | ||
<RadioGroup v-model:value="currentShape" button :options="shapes"></RadioGroup> | ||
<Captcha | ||
ref="captcha" | ||
image="/picture-3.jpg" | ||
:hollow-shape="currentShape === 'circle' ? circlePath : currentShape" | ||
></Captcha> | ||
<Button type="primary" @click="captcha?.reset()"> | ||
Reset Captcha | ||
</Button> | ||
</Space> | ||
</template> | ||
<script setup lang="ts"> | ||
import { ref, watch } from 'vue' | ||
import type { CaptchaExposed, CaptchaHollowProcess } from 'vexip-ui' | ||
const shapes = ['square', 'puzzle', 'shield', 'heart', 'circle'] as const | ||
const currentShape = ref(shapes[0]) | ||
const captcha = ref<CaptchaExposed>() | ||
watch(currentShape, () => captcha.value?.reset()) | ||
const circlePath: CaptchaHollowProcess = ({ ctx, x, y, width, height }) => { | ||
const side = Math.min(width, height) * 0.25 | ||
const halfSide = side * 0.5 | ||
ctx.arc(x, y, halfSide, 0, 2 * Math.PI) | ||
// Must return a rect array specifying the range of hollow | ||
return [x - halfSide, y - halfSide, side, side] | ||
} | ||
</script> |
Oops, something went wrong.