0


web前端之行为验证码、不同设备和屏幕尺寸呈现不同大小、元素宽度根据视口宽度进行调整、元素或图片裁剪、图片验证码

MENU


前言

1、版本一的样式比较齐全;
2、版本二的JS逻辑和功能效果比较完善,且是别人的代码,后续会对样式进行完善。[Gitee | 哔哩哔哩];
3、两个版本各有千秋,主要学习里面的一些技巧,这里主要介绍版本一的样式技巧;
4、行为验证码一般是后端实现,而且大概率是使用第三方插件,因为涉及到的逻辑和内容比较多,前后端实现起来都比较麻烦。


版本一(html+JS+css)

案例公共样式

body{margin: 0;padding: 0;display: flex;justify-content: center;align-items: center;min-height: 100vh;}

案例一(clip-path裁剪的应用)

<style>.clip_path{width: 300px;height: 300px;background-color: #ff0000;}.clip_path:first-child{float: left;background-color: #0000ff;clip-path:inset(50px 20px 30px 40px round 10px);}</style><div><divclass="clip_path"></div><divclass="clip_path"></div></div>

案例一解析

代码块中包含两个

元素,每个元素都有类名为clip_path。此外,还有一些CSS样式被应用于这些元素。


CSS样式部分
**1、clip_path类指定了一个固定的宽度(300像素)、高度(300像素)和背景颜色(红色)的区域。
2、clip_path:first-child选择器用于选择第一个具有类名clip_path的元素,并对其应用特定样式。
2.1、

float: left;

将第一个元素左浮动,使其在其右侧的元素之前显示。
2.2、

background-color: #0000ff;

将第一个元素的背景颜色更改为蓝色。
2.3、

clip-path: inset(50px 20px 30px 40px round 10px);

将剪切路径应用于第一个元素,剪切路径的形状是一个矩形,内边距为50px 20px 30px 40px,并且角是圆形的,半径为10px。**


HTML部分
两个

元素被包含在一个外部
中。
每个
元素都有类名为clip_path,因此它们都受到了相同的CSS样式的影响。


综上所述,代码将显示两个相同大小的红色方块,但第一个方块的背景颜色为蓝色,并具有一种剪切路径,使其内部形成一个圆角矩形区域。


案例一效果图

case11


案例二(clamp最大值最小值的应用)

<style>.clamp{width:clamp(300px, 50vw, 600px);height: 300px;background-color: #ff0000;}</style><divclass="clamp"></div>

案例二解析

一段简单的HTML和CSS代码段,用于创建一个具有限制宽度的元素。


**1、<style>标签用于在HTML文档中定义CSS样式。
2、.clamp是一个CSS类选择器,它用于选择具有类名为"clamp"的HTML元素。
3、

width: clamp(300px, 50vw, 600px);

是一个CSS属性,它使用clamp()函数来设置元素的宽度。clamp()函数接受三个参数,分别是最小宽度、首选宽度和最大宽度。在这个例子中,元素的宽度将被限制在300像素、视窗宽度的50%和600像素之间,以保证在不同设备和屏幕尺寸下有不同的大小。
4、

height: 300px;

设置元素的高度为300像素。
5、

background-color: #ff0000;

设置元素的背景颜色为红色。**


是一个HTML
元素,它具有一个类名为"clamp",因此应用了上述定义的CSS样式。这个
元素将具有限制宽度的特性,宽度将根据视窗宽度和定义的最小和最大宽度进行调整,以便在不同设备和屏幕尺寸下呈现出不同的大小。


案例二效果图

case21


case22


功能效果图

imageverificationCodeV11


imageverificationCodeV12


imageverificationCodeV13


html

<divid="captcha"><divid="handle"><spanonmousedown="onmousedownFn()"mousemove="mousemoveFn()"></span></div></div>

JavaScript

const captcha = document.querySelector('#captcha');const handle = document.querySelector('#handle');const button = document.querySelector('#handle span');const oLeft = handle.getBoundingClientRect().left;const buttonWidth = button.getBoundingClientRect().width;let flag =false;functiononmousedownFn(){
    flag =true;}

window.addEventListener('mousemove',({ clientX })=>{if(flag){
        captcha.style.setProperty('--moved',`${clientX - oLeft - buttonWidth /2}px`);}});

window.addEventListener('mouseup',({ clientX })=>{if(flag){const dis = clientX - oLeft;if(dis >=430&& dis <=450){
            captcha.classList.add('passed');alert('验证通过!');}else{
            captcha.style.setProperty('--moved','0px');}

        flag =false;}});

style

*{margin: 0;padding: 0;}body{--width: 400px;--height: 260px;--puzzle-width: 80px;--puzzle-height: 80px;--moved: 0px;background-color: #008b8b;width: 100vw;height: 100vh;display: flex;justify-content: center;align-items: center;}#captcha{width:var(--width);height:var(--height);background-image:url('https://cn.bing.com/th?id=OHR.AlmondBloom_ZH-CN9441550492_1920x1080.jpg');background-size: cover;background-position: center;position: relative;border-radius: 4px;box-shadow: 0px 2px 4px rgba(0, 0, 0, .3);}#captcha::before,
#captcha::after{display: flex;position: absolute;content:'';width: inherit;height: inherit;background-image: inherit;background-size: inherit;background-position: inherit;clip-path:inset(calc((var(--height) - var(--puzzle-height)) / 2)var(--puzzle-width)calc((var(--height) - var(--puzzle-height)) / 2)calc(var(--width) - var(--puzzle-width) * 2));}#captcha::after{transform:translateX(clamp(calc(var(--width) * -1),calc(var(--width) * -1 + var(--moved)),var(--puzzle-width)));transition: .25s all ease-in-out;cursor: pointer;}#captcha:active::after{transition: none;}#captcha::before{background-color:rgba(0, 0, 0, .6);background-blend-mode: multiply;}#handle{height: 30px;width:calc(var(--width) + var(--puzzle-width) * 2);border-radius: 18px;background-color: #eeeeee;box-shadow: inset 0 0 12px rgba(0, 0, 0, .2);border: 3px solid #eeeeee;position: absolute;bottom: -50px;left:calc(var(--puzzle-width) * 2 * -1);}#handle span{width:var(--puzzle-width);height: inherit;display: block;border-radius: inherit;background-color: #fff;box-shadow: 0 0 6px rgba(0, 0, 0, .25), 0 2px 4px rgba(0, 0, 0, .3);cursor: move;transform:translateX(clamp( 0px,var(--moved),calc(var(--width) + var(--puzzle-width))));cursor: pointer;transition: .25s all ease-in-out;}#captcha:active #handle span{transition: none;}#captcha.passed::before,
#captcha.passed::after,
#captcha.passed #handle{opacity: 0;}

版本二(html+JS+css+canvas)

效果图

imageverificationCodeV21


imageverificationCodeV22


imageverificationCodeV23


html

<divclass="container"><divid="captcha"style="position: relative;"></div><divid="msg"></div></div><scriptsrc="./indexV2.js"></script><script>
    captcha.init(document.getElementById('captcha'),function(){
        document.getElementById('msg').innerHTML ='验证成功';setTimeout(()=>{
            document.getElementById('msg').innerHTML ='';},2000);},function(){
        document.getElementById('msg').innerHTML ='验证失败';setTimeout(()=>{
            document.getElementById('msg').innerHTML ='';},1000);})</script>

JavaScript

(function(win){// 滑块边长let l =42,// 滑块半径
        r =10,// canvas宽度
        w =310,//canvas高度
        h =155,PI= Math.PI;// 滑块的实际边长const ll = l + r *2;// 获取指定区间内的随机数functiongetRandomNumberByRange(start, end){return Math.round(Math.random()*(end - start)+ start);}// 创建元素functioncreateElement(tagName){return document.createElement(tagName);}// 创建画布functioncreateCanvas(width, height){const canvas =createElement('canvas');

        canvas.width = width;
        canvas.height = height;return canvas;}// 获取随机图片functiongetRandomImg(){// 这个网站可以生成随机图片return'https://picsum.photos/300/150/?image='+getRandomNumberByRange(0,100);}// 创建图片functioncreateImg(onload){const img =createElement('img');

        img.crossOrigin ='Anonymous';
        img.onload = onload;
        img.onerror=()=>{
            img.src =getRandomImg();}
        img.src =getRandomImg();return img;}// 添加样式functionaddClass(tag, className){
        tag.classList.add(className);}// 移除样式functionremoveClass(tag, className){
        tag.classList.remove(className);}// 绘制functiondraw(ctx, operation, x, y){
        ctx.beginPath();
        ctx.moveTo(x, y);
        ctx.lineTo(x + l /2, y);
        ctx.arc(x + l /2, y - r +2, r,0,2*PI);
        ctx.lineTo(x + l /2, y);
        ctx.lineTo(x + l, y);
        ctx.lineTo(x + l, y + l /2);
        ctx.arc(x + l + r -2, y + l /2, r,0,2*PI);
        ctx.lineTo(x + l, y + l /2);
        ctx.lineTo(x + l, y + l);
        ctx.lineTo(x, y + l);
        ctx.lineTo(x, y);
        ctx.fillStyle ='#fff';
        ctx[operation]();
        ctx.beginPath();
        ctx.arc(x, y + l /2, r,1.5*PI,0.5*PI);
        ctx.globalCompositeOperation ='xor';
        ctx.fill();}// 求和functionsum(x, y){return x + y;}// 求平方functionsquare(x){return x * x;}// 验证码类classcaptcha{// 构造器constructor(el, success, fail){this.el = el;this.success = success;this.fail = fail;}// 初始化init(){this.initDOM();this.initImg();this.draw();this.bindEvents();}// 初始化DOMinitDOM(){const canvas =createCanvas(w, h),
                block = canvas.cloneNode(true),
                sliderContainer =createElement('div'),
                sliderMask =createElement('div'),
                slider =createElement('div'),
                refreshIcon =createElement('div'),
                sliderIcon =createElement('span'),
                text =createElement('span');

            block.className ='block';
            sliderContainer.className ='slider-container';
            sliderMask.className ='slider-mask';
            slider.className ='slider';
            refreshIcon.className ='refresh-icon';
            sliderIcon.className ='slider-icon';
            text.className ='slider-text';
            text.innerHTML ='向右滑动滑块填充拼图';const el =this.el;

            el.appendChild(canvas);
            el.appendChild(refreshIcon);
            el.appendChild(block);
            slider.appendChild(sliderIcon);
            sliderMask.appendChild(slider);
            sliderContainer.appendChild(sliderMask);
            sliderContainer.appendChild(text);
            el.appendChild(sliderContainer);

            Object.assign(this,{
                canvas,
                block,
                sliderContainer,
                refreshIcon,
                slider,
                sliderMask,
                sliderIcon,
                text,canvasCtx: canvas.getContext('2d'),blockCtx: block.getContext('2d')});}// 初始化图像initImg(){const img =createImg(()=>{this.canvasCtx.drawImage(img,0,0, w, h);this.blockCtx.drawImage(img,0,0, w, h);const y =this.y - r *2+2;const imageData =this.blockCtx.getImageData(this.x, y, ll, ll);this.block.width = ll;this.blockCtx.putImageData(imageData,0, y);});this.img = img;}// 绘画draw(){this.x =getRandomNumberByRange(ll +10, w -(ll +10));this.y =getRandomNumberByRange(10+ r *2, h -(ll +10));draw(this.canvasCtx,'fill',this.x,this.y);draw(this.blockCtx,'clip',this.x,this.y);}// 清除clean(){this.canvasCtx.clearRect(0,0, w, h);this.blockCtx.clearRect(0,0, w, h);this.block.width = w;}// 绑定事件bindEvents(){this.el.onselectstart=()=>false;this.refreshIcon.onclick=()=>{this.reset();}let originX, originY, trail =[],
                isMouseDown =false;this.slider.addEventListener('mousedown',function(e){
                originX = e.x;
                originY = e.y;
                isMouseDown =true;});
            document.addEventListener('mousemove',(e)=>{if(!isMouseDown)returnfalse;const moveX = e.x - originX;const moveY = e.y - originY;if(moveX <0|| moveX +38>= w)returnfalse;this.slider.style.left = moveX +'px';var blockLeft =(w -40-20)/(w -40)* moveX;this.block.style.left = blockLeft +'px';addClass(this.sliderContainer,'slider-container-active');this.sliderMask.style.width = moveX +'px';
                trail.push(moveY);});
            document.addEventListener('mouseup',(e)=>{if(!isMouseDown)returnfalse;
                isMouseDown =false;if(e.x == originX)returnfalse;removeClass(this.sliderContainer,'slider-container-active');this.trail = trail;const spliced =this.verify();if(spliced){addClass(this.sliderContainer,'slider-container-success');this.success &&this.success();}else{addClass(this.sliderContainer,'slider-container-fail');this.fail &&this.fail();setTimeout(()=>{this.reset();},1000);}});}// 重置reset(){this.sliderContainer.className ='slider-container';this.slider.style.left =0;this.block.style.left =0;this.sliderMask.style.width =0;this.clean();this.img.src =getRandomImg();this.draw();}// 验证verify(){const left =parseInt(this.block.style.left);//10表示容错率,值越小,需要拼得越精确return Math.abs(left -this.x)<10;}}

    win.captcha ={init:function(element, success, fail){newcaptcha(element, success, fail).init();}}}(window));

style

*{margin: 0;padding: 0;background-color: #333333;}body{/* 方便演示,满屏居中 */height: 100vh;display: flex;justify-content: center;align-items: center;}/* 小拼图 */.block{position: absolute;left: 0;top: 0;}/* 滑动条 */.slider-container{position: relative;text-align: center;width: 310px;height: 40px;line-height: 40px;margin-top: 15px;background-color: #f7f9fa;color: #45454c;border: 1px solid #e4e7eb;}.slider-mask{position: absolute;left: 0;top: 0;height: 40px;border: 0px solid #1991fa;background-color: #d1e9fe;}.slider{position: absolute;left: 0;top: 0;width: 40px;height: 40px;background: #fff;box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);cursor: pointer;transition: background 0.2s linear;}.slider-icon{position: absolute;left: 13px;top: 15px;width: 14px;height: 10px;background:url(/images/icon_light.png) 0 -26px;background-size: 34px 471px;}/* 滑动条活动态 */.slider-container-active .slider{height: 38px;top: -1px;border: 1px solid #1991fa;}.slider-container-active .slider-mask{height: 38px;border-width: 1px;}/* 滑动条成功态 */.slider-container-success .slider{height: 38px;top: -1px;border: 1px solid #52ccba;background-color: #52ccba !important;}.slider-container-success .slider-mask{height: 38px;border: 1px solid #52ccba;background-color: #d2f4ef;}/* 成功图标 */.slider-container-success .slider-icon{background-position: 0 0 !important;}/* 滑动条失败态 */.slider-container-fail .slider{height: 38px;top: -1px;border: 1px solid #f57a7a;background-color: #f57a7a !important;}.slider-container-fail .slider-mask{height: 38px;border: 1px solid #f57a7a;background-color: #fce1e1;}/* 失败图标 */.slider-container-fail .slider-icon{background-position: 0 -83px !important;}.slider-container-active .slider-text,
.slider-container-success .slider-text,
.slider-container-fail .slider-text{display: none;}.slider:hover{background: #1991fa;}.slider:hover .slider-icon{background-position: 0 -13px;}.refresh-icon{position: absolute;right: 0;top: 0;width: 34px;height: 34px;background:url(/images/icon_light.png) 0 -437px;background-size: 34px 471px;cursor: pointer;}#msg{height: 20px;line-height: 20px;text-align: center;margin-top: 15px;}
标签: 前端 javascript html

本文转载自: https://blog.csdn.net/weixin_51157081/article/details/122976165
版权归原作者 牧码人MJ682517 所有, 如有侵权,请联系我们删除。

“web前端之行为验证码、不同设备和屏幕尺寸呈现不同大小、元素宽度根据视口宽度进行调整、元素或图片裁剪、图片验证码”的评论:

还没有评论