啥也不说直接上图:
HTML代码:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="Cache-Control" content="no-cache, must-revalidate" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="author" content="mxj">
<meta name="keywords" content="">
<meta name="description" content="">
<title>登陆</title>
<link rel="shortcut icon" href="favicon.ico" />
<script type="text/javascript" src="jquery-1.7.2.min.js"></script>
<script type="text/javascript">
</script>
<style>
* {
font-size: 14px;
}
body{
background-image:url('img/bg2.png');
}
#shiqux option {
font-size: 12px;
height:30px;
}
#captcha {
position: relative;
width: 300px;
height: 150px;
background-image: url('app.php?act=img'); /* 引用生成验证码图片的PHP脚本 */
background-size: cover;
}
#slider {
position: absolute;
left: 0px; /* 初始位置 */
top: 70px;
width: 42px;
height: 42px;
/* background-image: url('img/icon-button-normal.png');*/ /* 引用生成验证码图片的PHP脚本 */
background-size: cover;
background-color: rgba(255, 255, 255, 0.1); /* 设置半透明背景 */
/*opacity: 0.6; 整个div 50% 透明度 */
cursor: move;
z-index:1001;
}
.modal {
display: none;
justify-content: center;
align-items: center;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5); /* 半透明背景 */
backdrop-filter: blur(5px); /* 虚化背景 */
}
.form-control{
border-color:#fff;
margin-bottom:10px;
}
</style>
</head>
<body>
<div class="content_m" >
<div class="container" style="margin-top: 30%;padding:30px;background: rgba(255,255,255,0.1);border-radius: 16px;">
<form id="login" method="post" action="/login" class="form-horizontal">
<input type="hidden" text="0" id="verifycode" name="sliderPos">
<div class="row">
<input type="user" placeholder='请输入用户名' name="username" value="" class="form-control mar_top_30" style="font-size: 14px;height: 40px;line-height: 40px;border-radius: 10px;width:80%;margin-left:10%;">
</div>
<div class="row">
<input type="password" placeholder='请输入密码' name="password" class="form-control mar_top_30" style="font-size: 14px;height: 40px;line-height: 40px;border-radius: 10px;width:80%;margin-left:10%;">
</div>
<div class="row" style="border:1px solid #ccc;background-color:#fff; width:40%;height:40px;margin-left:10%;line-height: 40px;border-radius: 10px;">
<span class="form-control verify" style="font-size: 14px;height: 40px;line-height: 40px;border-radius: 10px;width:40%;margin-left:10%;text-align:center;color:green;">点击验证</span>
</div>
<!---->
<div class="row " style="color:#FAFEBD;margin-top: 10px;">
<button type="submit" class="btn btn-primary col-xs-2 col-sm-2 mar_l_20" style="font-size: 14px;height: 30px;border-radius: 10px;margin-top:20px;margin-left:30%;width:40%;border-color:blue;color:red">登录</button>
</div>
</form>
</div>
<p style="margin-bottom: 28px;padding: 24px;text-align: center;display:none;">
<a href="https://beian.miit.gov.cn">浙ICPxxxxxxxx号-1</a>
</p>
</div>
<div class="modal">
<div class="captchacode" style="padding:5px;background-color:#fff;border-radius:5px;">
<div id="captcha">
<div id="slider"></div>
</div>
<div style="width:100%;margin-top:15px;position:relative;">
<p style="width:100%;height:36px;line-height:36px;text-align:center;padding-left:0px;border-radius:20px;border:1px solid #fff;background-color:#CCCCCC; color:blue;">
拖动左边滑块完成上方图片验证
</p>
<p style="height:50px;line-height:50px;text-align:center;width:50px;border-radius:40px;border:1px solid #CCCCCC;position:absolute;top:-22px;background-color:#fff;" id="movep"><font color="blue">|||</font></p>
</div>
<div style="margin-top:0px;height:30px;line-height:30px;border-top:1px solid #CCCCCC;text-align:right;">
<!-- <font style="font-size:32px;margin-right:10px;color:#ccc;margin-top:10px;">◎</font>-->
<font style="font-size:22px;margin-right:60px;color:blue;" class="tishi"></font>
<font style="font-size:22px;margin-right:10px;" class="closeimgcode">✖</font>
</div>
</div>
</div>
<script>
// JavaScript处理滑块拖动和验证
$(document).ready(function() {
let isMouseDown = false;
let startX;
let slider = $('#slider');
let captcha = $('#captcha');
let movep = $('#movep');
$('.closeimgcode').click(function () {
$('.modal').hide();
})
$('.verify').click(function () {
$('.modal').css('display','flex');
$('.modal').show();
});
slider.css("background-image","url('app.php?act=getcimg')");
slider.on("touchstart", function(event) {
// 处理 touchstart 事件的代码
isMouseDown = true;
//console.log('touchstart');
});
movep.on("touchstart", function(event) {
// 处理 touchstart 事件的代码
isMouseDown = true;
//console.log('touchstart');
});
movep.on("touchmove", function(event) {
//console.log('touchmove');
if (!isMouseDown) return;
// 获取触摸点的坐标
var touch = event.originalEvent.touches[0];
var x = touch.pageX-50;
// 移动元素
$("#slider").css("left", x);
movep.css("left", x);
});
captcha.on("touchmove", function(event) {
//console.log('touchmove');
if (!isMouseDown) return;
// 获取触摸点的坐标
var touch = event.originalEvent.touches[0];
var x = touch.pageX-50;
// 移动元素
$("#slider").css("left", x);
movep.css("left", x);
});
captcha.on("touchend", function(event) {
//console.log('touchend');
isMouseDown = false;
// 处理 touchend 事件的代码
var sliderPos = slider.position().left;
sendverify(sliderPos);
});
movep.on("touchend", function(event) {
//console.log('touchend');
isMouseDown = false;
// 处理 touchend 事件的代码
var sliderPos = slider.position().left;
sendverify(sliderPos);
});
function sendverify(sliderPos){
$('#verifycode').val(sliderPos);
// 发送滑块位置到后端验证
$.post('app.php?act=verify', { sliderPos: sliderPos }, function(result) {
if (result.success) {
$('.tishi').text('验证成功');
$('.modal').hide();
$('.verify').html("<font color=blue>验证成功</font>");
} else {
$('.tishi').text('验证失败,请重试');
// 重置滑块位置
slider.css('left', '0px');
movep.css("left", '0px');
}
});
}
$('#login').submit(function() {
var code = $('#verifycode').val();
//console.log('code:'+code);
if (code == 0) {
$('.modal').css('display','flex');
$('.modal').show();
return false;
}
$.ajax({
url: 'app.php?act=login',
dataType: 'json',
type: 'post',
data: $(this).serialize(),
success: function(res) {
if (res.retcode == 0) {
window.location.href = "?index";
} else {
alert(res.msg);
$('#verifycode').val(0);
$('.verify').html("<font color=blue>点击验证</font>");
$('.tishi').text('');
}
// console.log(res);
}
});
return false;
});
});
</script>
</body>
</html>
PHP代码:
<?php
/**
* H5 + jq + php 图片滑动验证
*
* @author mxj <745139633@qq.com>
*
*/
// 启动会话 开启session很重要,如果不想用session,可以memcache或者Redis
session_start();
//获取背景图片
function img()
{
$width = 300;//设置背景图片宽度
$height = 150;//设置背景图片高度
$sliderImg = rand(1,5);//随机更换背景图
$im = imagecreatefromjpeg('./img/'.$sliderImg.'.jpg');
//获取当前待修改图片像素(内置函数)
$x = imagesx($im);
$y = imagesy($im);
//新建一个真彩色图像(内置函数)
$image = imagecreatetruecolor($width, $height);
//重采样拷贝部分图像并调整大小(内置函数)
imagecopyresampled($image, $im, 0, 0, 0, 0, floor($width), floor($height), $x, $y);
// 绘制滑块 40*140
$sliderColor = imagecolorallocate($image, 190, 190, 190);
$sliderX = rand(50, $width - 50);
imagerectangle($image, $sliderX, 70, $sliderX + 40, 110, $sliderColor);
// 存储滑块的正确位置(用于后续验证)
$_SESSION['sliderPos'] = $sliderX;
$_SESSION['sliderImg'] = $sliderImg;
// 输出图片
header("Content-Type: image/jpeg");
//imagepng($image);
imagejpeg($image);
imagedestroy($image);
}
//获取移动图片
function getcimg(){
$width = 300;//设置背景图片宽度
$height = 150;//设置背景图片高度
$sliderImg = $_SESSION['sliderImg']?$_SESSION['sliderImg']:1 ;
$im = imagecreatefromjpeg('./img/'.$sliderImg.'.jpg');
//获取当前待修改图片像素(内置函数)
$x = imagesx($im);
$y = imagesy($im);
//新建一个真彩色图像(内置函数)
$sourceImage = imagecreatetruecolor($width, $height);
//重采样拷贝部分图像并调整大小(内置函数)
imagecopyresampled($sourceImage, $im, 0, 0, 0, 0, floor($width), floor($height), $x, $y);
// 设置剪切区域,这里以中心42x42像素为例
$x = $_SESSION['sliderPos'];
$y = 70;//这个70要和前端设置一样的值,否则,位置会偏移,无法重合
$croppedWidth = 42;
$croppedHeight = 42;
// 剪切图片
$croppedImage = imagecrop($sourceImage, ['x' => $x, 'y' => $y, 'width' => $croppedWidth, 'height' => $croppedHeight]);
// 输出图片
header("Content-Type: image/png");
imagepng($croppedImage);
// 释放内存
imagedestroy($sourceImage);
imagedestroy($croppedImage);
}
function verify(){
// 验证用户操作的PHP脚本
if ($_SERVER['REQUEST_METHOD'] === 'POST') {//$_REQUST
$sliderPos = $_REQUEST['sliderPos'] ?? 0;
$correctPos = $_SESSION['sliderPos'] ?? 0;
// 简单的验证逻辑:判断滑块位置是否在正确位置的一定范围内
$isClose = abs($sliderPos - $correctPos) < 5;
$result = [
'success' => $isClose,
'sliderPos'=>$sliderPos,
'correctPos'=>$correctPos
];
header('Content-type:text/json;charset=UTF-8;');
echo json_encode($result);}
}
//登录
function login()
{
header('Content-type:text/json;charset=UTF-8;');
$sliderPos = $_REQUEST['sliderPos'] ?? 0;
$correctPos = $_SESSION['sliderPos'] ?? 0;
// 简单的验证逻辑:判断滑块位置是否在正确位置的一定范围内
$isClose = abs($sliderPos - $correctPos) < 5;
if (!$isClose) {
$retutrue = [
"retcode"=> "606",
"msg"=> "验证码不通过"
];
echo json_encode($retutrue);die;
}
if(empty($_POST) || empty($_POST['username']) || empty($_POST['password'])){
$retutrue = [
"retcode"=> "9",
"msg"=> "账号或密码不能为空"
];
} else{
if($_POST['username'] != 'admin'){
$retutrue = [
"retcode"=> "1005",
"msg"=> "密码错误或用户不存在"
];
}else if ($_POST['password'] != '123456')
{
$retutrue = [
"retcode"=> "1005",
"msg"=> "密码错误或用户不存在"
];
}else{
//登陆 成功
$retutrue = [
"retcode"=> "0",
"msg"=> "登陆成功"
];
}
}
echo json_encode($retutrue);
}
if ($_GET['act']=='img') {
img();
} else if ($_GET['act']=='getcimg'){
getcimg();
}else if ($_GET['act']=='verify'){
verify();
}else if ($_GET['act']=='login'){
login();
}
码云:
H5+jq+php图片滑动验证: H5+jq+php图片滑动验证https://gitee.com/manxingjiang/H5jqphp