当前位置: 首页 > 科技观察

鸿蒙第三方组件-SwipeCaptcha滑动拼图验证组件

时间:2023-03-19 16:43:59 科技观察

更多内容请访问:与华为官方共建的鸿蒙技术社区https://harmonyos.51cto.com前言基于Android平台SwipeCaptcha(https://github.com/mcxtzhang/SwipeCaptcha),实现了鸿蒙核心功能的迁移重构,代码已经开源到(https://gitee.com/isrc_ohos/SwipeCaptcha),欢迎下载使用和提出宝贵意见!后台在页面登录或注册时,为了保证不是机器人操作,会要求用户手动验证。验证方式有两种:滑动拼图验证和滑动验证。本文中的SwipeCaptcha组件可以实现滑动拼图的验证方法。操作简单,安全性强。许多APP都在使用它。组件效果显示,使用鸿蒙系统的SwipeCaptcha组件时,有两个比较重要的图片:滑块和原图。两张图片放在同一水平线上,用户拖动滑块到原图,误差在一定范围内则验证成功。每次调用SwipeCaptcha组件时,滑块和原图的位置会随机变化,登录时更不易被暴力破解,安全性更高。在SwipeCaptcha组件的验证界面中,也有当前进度值和验证状态的说明。当前进度值表示滑块在水平方向的滑动进度。当进度为100时,表示滑块正在向最右侧滑动。进度值下方是当前验证状态,分为:“开始”、“验证失败,请重新验证”三种状态,“验证成功”。下面依次展示SwipeCaptcha组件拼图验证失败和成功的效果图。1.验证失败效果用户没有将滑块拖动到原图,导致滑块与原图位置误差较大,验证失败。图1验证失败的效果2.验证成功的效果。用户将滑块拖动到原始图像。如果误差在一定范围内,则验证成功。图2验证成功效果样本分析样本主要包括以下四个部分:1)拼图背景导入手机。2)作物滑块。3)绘制滑块。4)验证拼图是否成功。以下四个部分将通过具体步骤进行详细说明。1.数据初始化这一步包括三个部分的数据设置:(1)获取手机屏幕的宽度信息;(2)设置进度值和验证状态的初始提示文字,如“当前进度值”、“请滑动滑块验证”;(3)初始化画笔信息,定义画笔属性;//获取手机屏幕宽度displayAttributes.widthDisplayManagerdisplayManager=DisplayManager.getInstance();Displaydisplay=displayManager.getDefaultDisplay(this).get();DisplayAttributesdisplayAttributes=display.getAttributes();windowWidth=displayAttributes.width;//进度值初始化text=newText(this);text.setMarginTop(800);//距离上边框的距离text.setText("当前进度值"+progress);//设置文字text.setTextSize(100);//设置字体大小myLayout.addComponent(text);//添加到布局//验证状态初始化text2=newText(this);text2.setMarginTop(1000);text2.setText("PleaseSlidingsliderverification");text2.setTextSize(100);myLayout.addComponent(text2);//初始化画笔的信息mPaint=newPaint();mPaint.setColor(Color.BLACK);//定义颜色mPaint.setAntiAlias(true);//定义虚线和实线mPaint.setStrokeWidth(5f);//定义宽度mPaint.setStyle(Paint.Style.STROKE_STYLE);//定义绘制方法2.绘制背景图通过手机屏幕的宽度除以背景图片的宽度,得到背景图片的缩放比例,当图片在手机上显示时,可以根据需要进行缩放使这个比例与屏幕的宽度相同。该比例用于使背景图像适应不同型号的手机屏幕。//背景图的缩放比例floatratio=(float)windowWidth/(float)img.getImageInfo().size.width;//背景图绘制Componentimage=newComponent(this);Component.DrawTaskdrawTask=newComponent.DrawTask(){@OverridepublicvoidonDraw(Componentcomponent,Canvascanvas){//按比例缩放canvas.scale(ratio,ratio);//绘制canvas.drawPixelMapHolder(pixelMapHolder,0,0,newPaint());}};image.addDrawTask(drawTask);myLayout.addComponent(图像);3.确定滑块和原图的位置图3滑块和原图的位置可见puzzleWidth为滑块或原图的宽度;top是一个随机值,表示滑块的顶部或原始图像到背景图像顶部的距离;puzzel2left也是一个随机值,表示原图左边到背景图左边的距离。有了以上三个变量,就可以确定组件中滑块和原始图像的初始位置和大小(滑块初始位于屏幕最左侧)。下面描述如何计算上述属性。//puzzleWidth为屏幕宽度的1/6puzzleWidth=windowWidth/6;//top为缩放后图片高度与抠图高度之差乘以随机数top=(float)Math.random()*(img.getImageInfo().size.height*ratio-puzzleWidth);//原图位置必须在滑块位置右侧//屏幕宽度减去两个拼图宽度*随机数,然后向右平移滑块的长度puzzel2left=((windowWidth-puzzleWidth*2)*(float)Math.random())+puzzleWidth;4、获取滑块这一步需要根据原图片的位置解码出一张图片作为滑块。首先设置滑块的形状为矩形,根据上述puzzel2left和puzzleWidth属性确定矩形所在的区域,根据缩放比例将矩形区域映射到原始刻度图上,解码image获取滑块图像数据。PixelMappuzzlePixelMap=getPuzzlePixelMap(this,ResourceTable.Media_longa,newRect((int)(puzzel2left/ratio),(int)(top/ratio),(int)(puzzleWidth/ratio),(int)(puzzleWidth/ratio)));PixelMapHolderpixelMapHolder1=newPixelMapHolder(puzzlePixelMap);5.绘制滑块滑块是用画笔绘制的,它的位置要根据滑动进度条的进度移动,而且要适配不同的手机屏幕。同时,为了与用户友好交互,我们还需要给滑块画一个边框,告知用户边框就是滑块所在的位置(原图也需要画一个边框,原理是一样的)。绘制滑块和边框的代码如下://绘制滑块Component.DrawTaskpuzzelDrawTask=newComponent.DrawTask(){@OverridepublicvoidonDraw(Componentcomponent,Canvascanvas){Paintpaint=newPaint();//移动小滑块拼图画布。translate(slider.getProgress()*displayAttributes.width/100,top);//适当缩放canvas.scale(ratio,ratio);canvas.drawPixelMapHolder(pixelMapHolder1,0,0,paint);}};//绘制sliderBorderComponentpuzzleFrame=newComponent(this);Component.DrawTaskdrawTask2=newComponent.DrawTask(){@OverridepublicvoidonDraw(Componentcomponent,Canvascanvas){//框的左边位置floatleft=slider.getProgress()*windowWidth/100;//绘制theborderLeftcanvas.drawLine(newPoint(left,top),newPoint(left,top+puzzleWidth),mPaint);//绘制边框的上边canvas.drawLine(newPoint(left,top),newPoint(left+puzzleWidth,top),mPaint);//画边框右侧canvas.drawLine(newPoint(left+puzzleWidth,top),newPoint(left+puzzleWidth,top+puzzleWidth),mPaint);//绘制边框的下边canvas.drawLine(newPoint(left,top+puzzleWidth),newPoint(left+puzzleWidth,top+puzzleWidth),mPaint);}};6.进度条通过滑动来更新,为进度条设置监听。拖动进度条会引起三个更新:(1)更新滑块的位置和滑块边框的位置;(2)更新进度值;(3)更新验证状态在验证状态的更新中,需要在用户拖动进度条时判断验证状态。block与原图的位置差距是否在误差范围内,在误差范围内表示验证成功,不在误差范围内表示验证失败,提示需要重新验证。//设置进度条监听slider.setValueChangedListener(newSlider.ValueChangedListener(){@Override//拖动进度条引起的更新publicvoidonProgressUpdated(Sliderslider,inti,booleanb){//滑块位置更新puzzle.invalidate();//更新滑块框的位置puzzleFrame.invalidate();//更新进度值text.setText("当前进度值:"+slider.getProgress());}}//当用户开始滑动进度条,验证状态是否变为“开始”。publicvoidonTouchStart(Sliderslider){//开始拖动的方法text2.setText("Start");}//判断是否左边的位置滑块的一侧位于原始图像左侧的位置publicvoidonTouchEnd(Sliderslider){if(((slider.getProgress()*windowWidth/100)<(puzzel2left+puzzleWidth/10))&??&((slider.getProgress()*windowWidth/100)>(puzzel2left-puzzleWidth/10)))){text2.setText("验证成功");}else{text2.setText("验证失败,pleasere-verify");slider.setProgressValue(10);}}项目贡献者赵柏仪郑森文朱伟陈美茹张鑫想了解更多信息请访问:https://harmonyos.51cto.com,与华为合作共建的鸿蒙科技社区