最近有需求要实现拼图滑动验证码,找了点资料做了个demo看看。
思路
简单来说就是后端随机获取图片,随即切割后把处理完的两张图片,拼图和背景存放到对应文件夹,之后将文件地址(名称)和拼图位置信息返回到前端,实现拖动重合效果即可。
传递数据格式
由bean类进行数据存放,包括拼图左上角的x,y坐标位置,拼图和背景文件名称。
public class VerificationCodePlace {
private String backName;
private String markName;
private int xLocation;
private int yLocation;
public VerificationCodePlace(){
}
public VerificationCodePlace(String backName, String markName, int xLocation, int yLocation){
this.backName = backName;
this.markName = markName;
this.xLocation = xLocation;
this.yLocation = yLocation;
}
public String getBackName() {
return backName;
}
public void setBackName(String backName) {
this.backName = backName;
}
public String getMarkName() {
return markName;
}
public void setMarkName(String markName) {
this.markName = markName;
}
public int getxLocation() {
return xLocation;
}
public void setxLocation(int xLocation) {
this.xLocation = xLocation;
}
public int getyLocation() {
return yLocation;
}
public void setyLocation(int yLocation) {
this.yLocation = yLocation;
}
}
拼图切割工具类
该工具类的随机切割方法主要参考https://www.jianshu.com/p/eb190c26fb5b中提供的方法,利用一个图片宽×图片高的数组来存放像素透明,保持原状或者半透明的信息,来实现拼图造型的随机生成。
public class VerificationCodeAdapter {
/**
* 源文件宽度
*/
private static int ORI_WIDTH = 300;
/**
* 源文件高度
*/
private static int ORI_HEIGHT = 150;
/**
* 模板图宽度
*/
private static int CUT_WIDTH = 50;
/**
* 模板图高度
*/
private static int CUT_HEIGHT = 50;
/**
* 抠图凸起圆心
*/
private static int circleR = 5;
/**
* 抠图内部矩形填充大小
*/
private static int RECTANGLE_PADDING = 8;
/**
* 抠图的边框宽度
*/
private static int SLIDER_IMG_OUT_PADDING = 1;
// 生成拼图样式
private static int[][] getBlockData(){
int[][] data = new int[CUT_WIDTH][CUT_HEIGHT];
Random random = new Random();
//(x-a)²+(y-b)²=r²
//x中心位置左右5像素随机
double x1 = RECTANGLE_PADDING + (CUT_WIDTH - 2 * RECTANGLE_PADDING) / 2.0 - 5 + random.nextInt(10);
//y 矩形上边界半径-1像素移动
double y1_top = RECTANGLE_PADDING - random.nextInt(3);
double y1_bottom = CUT_HEIGHT - RECTANGLE_PADDING + random.nextInt(3);
double y1 = random.nextInt(2) == 1 ? y1_top : y1_bottom;
double x2_right = CUT_WIDTH - RECTANGLE_PADDING - circleR + random.nextInt(2 * circleR - 4);
double x2_left = RECTANGLE_PADDING + circleR - 2 - random.nextInt(2 * circleR - 4);
double x2 = random.nextInt(2) == 1 ? x2_right : x2_left;
double y2 = RECTANGLE_PADDING + (CUT_HEIGHT - 2 * RECTANGLE_PADDING) / 2.0 - 4 + random.nextInt(10);
double