Building a Slider Captcha Component with Vue 3, Vite, and Canvas
This article guides developers through creating a customizable slider captcha component using Vue 3 and Vite, covering component design principles, Canvas drawing techniques, event handling, API configuration, and publishing the component to npm, with complete code examples.
The article introduces a new graphics practice: implementing a sliding verification (captcha) component using Vue 3 and Vite. It begins with a brief overview of the component's purpose and the design principles such as readability, usability, reusability, maintainability, and performance.
Component Design and API
Key configurable props include visibility, size (width, height), slider dimensions (l, r), text tip, image source, and several callbacks (onSuccess, onFail, onCustomVertify, onDraw, onRefresh, etc.). These enable flexible integration into various projects.
Canvas Drawing Basics
The implementation relies on Canvas APIs like beginPath(), moveTo(), arc(), lineTo(), stroke(), fill(), and clip(). The globalCompositeOperation property is used to control how the cut‑out shape is composited over the background image.
const drawPath = (ctx, x, y, operation) => {
ctx.beginPath();
ctx.moveTo(x, y);
ctx.arc(x + l / 2, y - r + 2, r, 0.72 * PI, 2.26 * PI);
ctx.lineTo(x + l, y);
ctx.arc(x + l + r - 2, y + l / 2, r, 1.21 * PI, 2.78 * PI);
ctx.lineTo(x + l, y + l);
ctx.lineTo(x, y + l);
ctx.arc(x + r - 2, y + l / 2, r + 0.4, 2.76 * PI, 1.24 * PI, true);
ctx.lineTo(x, y);
ctx.lineWidth = 2;
ctx.fillStyle = "rgba(255, 255, 255, 0.7)";
ctx.strokeStyle = "rgba(255, 255, 255, 0.7)";
ctx.stroke();
ctx.globalCompositeOperation = "destination-over";
operation === "fill" ? ctx.fill() : ctx.clip();
};Component Skeleton (Vue 3 + TypeScript)
<script lang="ts" setup>
import { ref, watch, onMounted } from "vue";
interface VertifyType {
spliced: boolean;
verified: boolean;
left: number;
destX: number;
}
interface IProps {
width?: number;
visible?: boolean;
height?: number;
refreshIcon?: string;
l?: number;
r?: number;
imgUrl?: string;
text?: string;
onDraw?: (l: number) => {};
onCustomVertify?: (arg: VertifyType) => VertifyType;
onBeforeRefresh?: () => void;
onSuccess?: VoidFunction;
onFail?: VoidFunction;
onRefresh?: VoidFunction;
}
const props = withDefaults(defineProps<IProps>(), {
width: 320,
visible: true,
height: 160,
refreshIcon: "http://cdn.dooring.cn/dr/icon12.png",
l: 42,
r: 9,
imgUrl: "",
text: "",
});
// refs for DOM elements and state
const canvasRef = ref<any>(null);
const blockRef = ref<any>(null);
const isMouseDownRef = ref<boolean>(false);
const sliderLeft = ref(0);
const textTip = ref(props.text);
const PI = Math.PI;
const L = props.l + props.r * 2 + 3;
// ... other reactive variables
</script>Event handling for dragging uses onMouseDown, onMouseMove, and onMouseUp (or touch equivalents) to update the slider position, calculate the trail, and trigger success/failure callbacks based on verification logic.
const handleDragMove = (e) => {
if (!isMouseDownRef.value) return false;
e.preventDefault();
const eventX = e.clientX || e.touches[0].clientX;
const eventY = e.clientY || e.touches[0].clientY;
const moveX = eventX - originXRef.value;
const moveY = eventY - originYRef.value;
if (moveX < 0 || moveX + 36 >= width) return false;
sliderLeft.value = moveX;
const blockLeft = (width - props.l - 2 * props.r) / (width - props.l) * moveX;
blockRef.value.style.left = blockLeft + 'px';
};After the component is complete, the article shows how to package it with Vite, configure the library build, and publish the distribution to npm. Example Vite config and npm installation commands are provided.
export default defineConfig({
...baseConfig,
build: {
outDir: 'dist',
lib: {
entry: resolve(__dirname, '../packages/index.ts'),
name: 'vue-slider-vertify',
fileName: (format) => `vue-slider-vertify.${format}.js`,
},
rollupOptions: {
external: ['vue'],
output: {
globals: { vue: 'Vue' },
},
},
},
plugins: [...baseConfig.plugins, dts()],
});Finally, the article encourages readers to explore further graphics applications such as 3D visualization, editors, and charts, and invites contributions via the author's GitHub repositories.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
