图片滑块验证功能很难吗?做个可以自己抠形状的图片滑块验证组件

简介: 图片滑块验证功能很难吗?做个可以自己抠形状的图片滑块验证组件

说在前面

在当今数字化世界中,网络安全和用户验证变得至关重要。随着恶意机器人和自动化攻击的增加,传统的验证码系统已经不再足够保障网站的安全性。为了提高用户体验和防止恶意攻击,图片滑块验证成为了一个热门的选择。今天,我们一起来实现一个可以自己扣形状的图片滑块验证组件

效果展示

体验地址

http://jyeontu.xyz/jvuewheel/#/JImgVerifyView

实现步骤

一、使用canvas展示背景图片

首先我们应该先了解一下怎么在canvas上绘制图片:

  • 1.获取Canvas元素和2D上下文:首先获取到需要绘制图片的Canvas元素,并从中获取2D上下文(Context)。可以使用以下代码获取Canvas元素和2D上下文:
const canvas = document.getElementById('myCanvas'); // 获取Canvas元素
const ctx = canvas.getContext('2d'); // 获取2D上下文
  • 2.创建Image对象并设置src:创建一个Image对象,然后设置其src属性为要绘制的图片的URL。确保图片加载完成后再进行绘制操作。
const image = new Image();
image.onload = function() {
  // 在图片加载完成后进行绘制操作
};
image.src = 'path_to_your_image.jpg'; // 设置图片路径
  • 3.绘制图片,在图片加载完成后,可以使用ctx.drawImage()方法在Canvas上绘制图片。
image.onload = function() {
  ctx.drawImage(image, x, y, width, height); // 在Canvas上绘制图片
};

在上面的代码中,x和y表示图片在Canvas上的起始坐标,width和height表示图片的宽度和高度。

二、背景图片抠出滑块缺口

1、获取到canvas元素和2D上下文ctx
const canvas = this.$refs.canvas;
const ctx = canvas.getContext("2d");
2、创建一个image对象,将图片绘制到canvas上

在图片加载完成后,函数设置了图片的宽度和高度,并将canvas的宽度和高度设置为与图片相同,然后通过ctx.drawImage()方法绘制图片。

const image = new Image();
image.onload = () => {
    image.width = parseInt(this.width);
    image.height = parseInt(this.height);
    canvas.width = image.width;
    canvas.height = image.height;
    // 绘制图片
    ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
};
image.src = this.imgSrc;
3、根据抠图路径,将区域镂空

这里的镂空区域我们可以设置为透明,也可以填充上我们自己喜欢的颜色。

// 创建镂空区域的路径
this.cutImg(ctx, this.cutPath, image, canvas);
// 在路径内部清除像素
if (this.fillStyle) {
    ctx.fillStyle = this.fillStyle; // 设置填充颜色
} else {
    ctx.globalCompositeOperation = "destination-out";
}
ctx.fill();
resolve();

然后我们就可以得到这么一张图片

三、抠出一个滑块图片

前面我们生成了一张扣出了滑块缺口的图片,那么我们还需要一张图片可以来填充这个缺口,所以我们需要再抠出一张图片

1、获取到canvas元素和2D上下文ctx
const canvas = this.$refs.canvas2;
const ctx = canvas.getContext("2d");
2、创建一个image对象,将图片绘制到canvas上

在图片加载完成后,函数设置了图片的宽度和高度,并将canvas的宽度和高度设置为与图片相同。

const image = new Image();
image.onload = () => {
    image.width = parseInt(this.width);
    image.height = parseInt(this.height);
    canvas.width = image.width;
    canvas.height = image.height;
    ……
};
image.src = this.imgSrc;
3、根据抠图路径,抠出指定区域图片

创建了一个剪切路径,如果定义了strokeStyle属性,则设置绘制路径的颜色,然后用ctx.stroke()方法绘制路径。接着,使用ctx.clip()方法将当前路径设置为剪切路径。这意味着后续绘制的所有内容都将被剪切成路径内部的形状。

最后,使用ctx.drawImage()方法将图片绘制到Canvas上。

// 定义剪切路径
this.cutImg(ctx, this.cutPath, image, canvas);
if (this.strokeStyle) {
    ctx.strokeStyle = this.strokeStyle;
}
ctx.stroke();
ctx.clip();
// 绘制图片
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
resolve();

然后我们就可以得到这么一张图片

四、滑动条控制滑块滑动

1、图块跟随滑动条滑动
  • 初始滑动回调
    使用startSliding来标记是否初始滑动,是初始滑动时执行start回调。
  • 滑动位置计算
    滑动条滑动距离 = 图片总宽度 * 当前滑动比例;
  • 控制图片滑块不滑出图片区域

我们假设背景图片的宽度为width,滑块最左边的x坐标为minX,最右端的X坐标为maxX,那么滑块的最大宽度则为maxX - minX,则滑块的可滑动范围应该是[0,widht - maxX + minX],如下图:

这样想那你就错了,滑块整个的大小其实是和原图片一样的,如下图:

所以其移动范围的计算方式应该是这样的:

还是假设背景图片的宽度为width,滑块最左边的x坐标为minX,最右端的X坐标为maxX,那么滑块的最大宽度则为maxX - minX,则滑块的可滑动范围应该是:[-minX,width - maxX],如下图:

onSliderChange(sliderValue) {
    if (!this.startSliding) {
        this.startSliding = true;
        this.$emit("start");
    }
    const left = parseInt(this.width) * (sliderValue / 100);
    this.startLeft = Math.min(
        parseInt(this.originLeft) + parseInt(left),
        parseInt(this.width) - this.sliderInfo.maxX
    );
}
2、判断滑块结束位置是否通过

滑块和缺口完全重合的时候,滑块滑动的距离应该是0,这里我们设置一个误差属性passDiff,默认为3px,最后判断滑块滑动的距离是否在误差范围里即可,具体代码如下:

confirmSlider() {
    if (Math.abs(this.startLeft) <= this.passDiff) {
        this.$JToast("验证通过");
    } else if (this.failedText) {
        this.$JToast(this.failedText);
    }
    setTimeout(() => {
        this.init();
    }, 1000);
    this.startSliding = false;
    this.$emit("end", Math.abs(this.startLeft) <= this.passDiff);
}

五、更换自己喜欢的滑块形状

1、抠图工具

默认的滑块形状是下面这样的:

如果你不喜欢的话也可以换成自己喜欢的形状,前面我分享过一篇文章《使用canvas实现一个锚点抠图功能》,看过这篇文章的同学可能记得我在里面留了一个坑,现在就把它填上,我们可以利用这个工具来获取到我们自定义的滑块形状路径:

工具地址:http://jyeontu.xyz/JDemo/#/imgCut

如上图,我们现在的滑块形状也是通过这个工具获取到的,我们也可以做成下面这些样子的:

总之就是想要什么形状都可以自己抠出来,当然,喜欢直接算坐标的直接算也可以

2、注意

抠图注意将宽高设置为与组件宽高一致,不然滑块大小可能会和你想象中的不一样

源码地址

gitee

https://gitee.com/zheng_yongtao/jyeontu-component-warehouse.git

公众号

关注公众号『前端也能这么有趣』发送 组件库即可获取源码。

组件使用

目前该组件库已经发布到npm,除了图片滑块验证之外还有其他许多好玩的组件,后续会继续维护,源码也已经开源,感兴趣的朋友可以瞧瞧,觉得有点意思的可以顺手点个star

组件文档:http://jyeontu.xyz/jvuewheel/#/installView

组件仓库:https://gitee.com/zheng_yongtao/jyeontu-component-warehouse.git

说在后面

🎉 这里是 JYeontu,现在是一名前端工程师,有空会刷刷算法题,平时喜欢打羽毛球 🏸 ,平时也喜欢写些东西,既为自己记录 📋,也希望可以对大家有那么一丢丢的帮助,写的不好望多多谅解 🙇,写错的地方望指出,定会认真改进 😊,偶尔也会在自己的公众号『前端也能这么有趣』发一些比较有趣的文章,有兴趣的也可以关注下。在此谢谢大家的支持,我们下文再见 🙌。

目录
相关文章
|
1月前
|
索引
【sgPhotoPlayer】自定义组件:图片预览,支持点击放大、缩小、旋转图片
【sgPhotoPlayer】自定义组件:图片预览,支持点击放大、缩小、旋转图片
|
1月前
|
JavaScript 容器
富文本的图片添加点击放大功能
思路:富文本加载后,dom出全部img元素,然后各自单独添加点击事件
85 3
|
1月前
|
JavaScript 前端开发
图片滑动验证
图片滑动验证
16 0
|
1月前
|
测试技术
【sgTileImage】自定义组件:瓦片图拖拽局部加载、实现以鼠标为中心缩放
【sgTileImage】自定义组件:瓦片图拖拽局部加载、实现以鼠标为中心缩放
|
7月前
|
JavaScript
图片旋转验证原来这么简单
图片旋转验证原来这么简单
80 0
|
Web App开发 移动开发 前端开发
移动端图片操作(二)——预览、旋转、合成
在上一节中已经提到了预览,预览可以通过data: URL格式或URL对象。
移动端图片操作(二)——预览、旋转、合成
|
11月前
|
JavaScript
滑动图片验证
滑动图片验证
40 0
|
12月前
图片和文件预览组件(部分源码),可拖动,缩小,放大。 #41
图片和文件预览组件(部分源码),可拖动,缩小,放大。 #41
97 0
|
12月前
|
JavaScript 前端开发 容器
手写图片拖拽、鼠标点位缩放
如题,无关技术背景,什么vue、react自己想用就用,这就是js加一点点css实现,意思就是可以任意迁。
151 0
|
C# 图形学
C#绘制自定义小人
C#绘制自定义小人

热门文章

最新文章