当然,里面一些效果还是要根据自己所需要的来修改,大体功能完善了而已。
拼图也可以进行随机,多准备几张图,设置img src随机数组
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>简易滑动拼图解锁</title>
<style>
* {
margin: 0px;
padding: 0px;
}
img,
canvas {
width: 300px;
height: 200px;
}
img {
display: none;
}
#myCanvas {
position: absolute;
float: left;
}
.verify {
position: relative;
width: 300px;
height: 50px;
background-color: pink;
line-height: 50px;
text-align: center;
color: #fff;
}
.verify .slide {
position: absolute;
width: 55px;
height: 50px;
background-color: skyblue;
}
/* position:relative 移动端左移会滑动 */
/* position:fixed 解决左移滑动问题*/
.lockBox {
position: fixed;
}
.bigBox {
width: 300px;
margin: 10px auto;
}
</style>
</head>
<body>
<div class="bigBox">
<!-- 图片 -->
<div class="lockBox">
<div class="topCanvas">
<img src="../beauty.png" alt="随机拼图">
<canvas id="myCanvas"></canvas>
<canvas id="block"></canvas>
</div>
<!-- 滑块 -->
<div class="verify">
<!-- 滑块 -->
<div class="slide">
</div>
</div>
</div>
</div>
<script>
const w = 300 // canvas宽度
const h = 200 // canvas高度
const l = 55 // 滑块边长
const r = 9 // 滑块半径
const PI = Math.PI
const L = l + r * 2 + 3 // 滑块实际边长
// 拼图滑块
var c = document.querySelector("#myCanvas");
var ctx = c.getContext("2d");
// 拼图背景图
var c2 = document.querySelector("#block");
var ctx2 = c2.getContext("2d");
var img = document.querySelector("img");
// 绘制拼图背景
function drawImage() {
ctx.drawImage(img, 0, 0, 300, 200);
ctx2.drawImage(img, 0, 0, 300, 200);
}
img.onload = function() {
// 初始化拼图
drawImage();
}
// 拼图滑块挖掘
function drawPath(ctx, x, y, operation) {
ctx.beginPath()
ctx.moveTo(x, y)
ctx.arc(x + l / 2, y - r + 2, r, 0.72 * PI, 2.26 * PI)
ctx.lineTo(x + l, y)
ctx.arc(x + l + r - 2, y + l / 2, r, 1.21 * PI, 2.78 * PI)
ctx.lineTo(x + l, y + l)
ctx.lineTo(x, y + l)
ctx.arc(x + r - 2, y + l / 2, r + 0.4, 2.76 * PI, 1.24 * PI, true)
ctx.lineTo(x, y)
ctx.lineWidth = 2
ctx.fillStyle = 'rgba(255, 255, 255, 0.7)'
ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)'
ctx.stroke()
ctx.globalCompositeOperation = 'destination-over'; //重要
operation === 'fill' ? ctx.fill() : ctx.clip()
}
// 随机位置但是要同高度
function randomNum(start, end) {
return Math.floor(Math.random() * (end - start) + start);
}
// 随机位置创建拼图
let x = randomNum(L + 10, w - L - 20);
let y = randomNum(10 + 2 * r, h - L - 20);
// 不动的挖空
drawPath(ctx2, x, y, 'fill');
// 滑块切割,
drawPath(ctx, x, y, 'clip');
// 控制同等高度,定位在左边
document.querySelector("#myCanvas").style.left = -x + 'px';
// 网页端滑动解锁 事件
// 监听滑块事件
document.querySelector(".slide").onmousedown = function(e) {
document.onmousemove = function(e2) {
// 最大滑动距离为下方盒子长-滑块长
//范围内拖动
if (e2.clientX > e.clientX && e2.clientX - e.clientX <= w - L + 10) {
// 使得滑块和拼图一起动
document.querySelector(".slide").style.left = e2.clientX - e.clientX + 'px';
document.querySelector("#myCanvas").style.left = -x + e2.clientX - e.clientX + 'px';
}
document.onmouseup = function() {
// 判断拼图位置是否正确,拖拉距离是否是随机生成的拼图x
let result = false;
// 正确提示正确,误差为10以内为正确
if (e2.clientX - e.clientX - 10 <= x && x <= e2.clientX - e.clientX + 10) {
result = true;
// alert("验证成功!");
// 滑块消失
document.querySelector(".slide").style.display = "none";
document.querySelector(".verify").innerHTML = "解锁成功!";
} else {
// 不正确提示不正确,且返回原点
alert("验证失败");
// 滑块消失
// 重新刷新
location.reload();
}
// 解除以下事件
document.onmousemove = null;
document.onmouseup = null;
}
}
}
// 移动端
document.querySelector(".slide").ontouchstart = function(e) {
let touch = e.targetTouches[0];
document.ontouchmove = function(e2) {
let touch2 = e2.targetTouches[0];
// 最大滑动距离为下方盒子长-滑块长
//范围内拖动
if (touch2.pageX > touch.pageX && touch2.pageX - touch.pageX <= w - L + 10) {
// 使得滑块和拼图一起动
document.querySelector(".slide").style.left = touch2.pageX - touch.pageX + 'px';
document.querySelector("#myCanvas").style.left = -x + touch2.pageX - touch.pageX + 'px';
}
document.ontouchend = function() {
// 判断拼图位置是否正确,拖拉距离是否是随机生成的拼图x
let result = false;
// 正确提示正确,误差为10以内为正确
if (touch2.pageX - touch.pageX - 10 <= x && x <= touch2.pageX - touch.pageX + 10) {
result = true;
// 滑块消失
document.querySelector(".slide").style.display = "none";
document.querySelector(".verify").innerHTML = "解锁成功!";
} else {
// 重新刷新
location.reload();
}
// 解除以下事件
document.ontouchmove = null;
document.ontouchend = null;
}
}
}
</script>
</body>
</html>
上效果图:
滑动前:
(拖蓝色滑块便可以进行滑动)
滑动成功:
滑动失败:(目前设置了直接刷新,可以根据自己实际情况修改)