1.随机滑块位置
2.绘制背景,随机位置扣滑块
3.绘制滑块
4.事件处理
示例:
1.html代码
<!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>Document</title>
<link rel="stylesheet" href="./005.css">
<style>
* {
padding: 0;
margin: 0;
}
body,
html {
/* background: #000; */
height: 100%;
width: 100%;
}
.box {
width: 800px;
height: 500px;
position: relative;
}
</style>
</head>
<body>
<div class="box">
</div>
<button id="btn" >shuaxin </button>
</body>
<script src="./005.js"></script>
<script>
let box = document.querySelector(".box");
let successCallback=()=>{
alert("success");
init.handleinit()
}
let errorCallback=()=>{
alert("error");
init.handleinit()
}
let imgs=["../img/lyf.webp"]
let init=new Init(box,successCallback,errorCallback,imgs);
console.log(init)
document.getElementById("btn").onclick=()=>{
init.handleinit()
}
</script>
</html>
2.js代码
//props
// element:Element
// successCallback:Function
// errorCallback:Function
// imgs:Arroy
function Init(element, successCallback, errorCallback, imgs) {
//容器宽度大于200高度大于100
let boxW = element.offsetWidth, boxH = element.offsetHeight;
let bigw = boxW, bigh = boxH - 60;
let smallw = 70, smallh = boxH - 60;
let errorValue = 5;
let x = 200, y = 200;
// 创建canvas背景
let canvasbg = document.createElement("canvas");
canvasbg.setAttribute("id", "canvasbg")
canvasbg.setAttribute("width", bigw)
canvasbg.setAttribute("height", bigh)
box.appendChild(canvasbg)
// 创建canvas滑块
let canvas = document.createElement("canvas");
canvas.setAttribute("id", "canvas")
canvas.setAttribute("width", smallw)
canvas.setAttribute("height", smallh)
box.appendChild(canvas)
// 创建下方滑块轨迹
let codecanvas = document.createElement("canvas");
codecanvas.setAttribute("id", "codecanvas")
codecanvas.setAttribute("width", "50")
codecanvas.setAttribute("height", "50")
box.appendChild(codecanvas);
let code = document.createElement("div");
code.setAttribute("class", "code");
code.appendChild(codecanvas)
let codebox = document.createElement("div");
codebox.setAttribute("class", "codebox")
codebox.appendChild(code)
let bottomcode = document.createElement("div");
bottomcode.setAttribute("class", "bottomcode")
bottomcode.appendChild(codebox);
box.appendChild(bottomcode)
let imgsrc = ""
// 处理图片问题
function handleImgs() {
if (imgs && imgs.length > 0) {
let index = handleRandom(0, imgs.length - 1);
console.log(index)
imgsrc = imgs[index]
} else {
// 默认图片源自己搞定
imgsrc = ""
}
}
// 处理canvas背景
// let canvasbg = document.getElementById("canvasbg");
let ctxbg = canvasbg.getContext("2d");
function drawBg() {
ctxbg.save()
let imgbg = new Image();
imgbg.src = imgsrc;
imgbg.onload = () => {
ctxbg.drawImage(imgbg, 0, 0, bigw, bigh);
// 拼图形状
ctxbg.beginPath();
ctxbg.moveTo(x, y);
ctxbg.lineTo(x + 15, y);
ctxbg.arc(x + 25, y, 10, Math.PI, 2 * Math.PI, false);
ctxbg.lineTo(x + 50, y);
ctxbg.lineTo(x + 50, y + 15);
ctxbg.arc(x + 50, y + 25, 10, Math.PI * 3 / 2, Math.PI / 2, false);
ctxbg.lineTo(x + 50, y + 50);
ctxbg.lineTo(x, y + 50);
ctxbg.lineTo(x, y + 50 - 15);
ctxbg.arc(x, y + 25, 10, Math.PI / 2, Math.PI * 3 / 2, true);
ctxbg.lineTo(x, y);
ctxbg.fillStyle = "rgba(255,255,255,0.8)"
ctxbg.fill()
}
}
//处理canvas滑块
// let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d")
// 拼图形状
function drawCode() {
console.log(y)
ctx.save()
let heart = new Path2D()
heart.moveTo(0, y);
heart.lineTo(0 + 15, y);
heart.arc(0 + 25, y, 10, Math.PI, 2 * Math.PI, false);
heart.lineTo(0 + 50, y);
heart.lineTo(0 + 50, y + 15);
heart.arc(0 + 50, y + 25, 10, Math.PI * 3 / 2, Math.PI / 2, false);
heart.lineTo(0 + 50, y + 50);
heart.lineTo(0, y + 50);
heart.lineTo(0, y + 50 - 15);
heart.arc(0, y + 25, 10, Math.PI / 2, Math.PI * 3 / 2, true);
heart.lineTo(0, y);
ctx.clip(heart)
let img = new Image();
img.src = imgsrc;
img.onload = () => {
// ctx.drawImage(img, x, y, 50, 50, 0, y, 50, 50);
let imgw = img.width;
let imgh = img.height;
ctx.drawImage(img, x / bigw * imgw, 0, smallw / bigw * imgw, smallh / bigh * imgh, 0, 0, smallw, smallh);
ctx.strokeStyle = 'rgba(255,255,255,0.8)';
ctx.lineWidth = 2;
ctx.stroke(heart);
}
}
// 处理滑块鼠标事件
let flag = false;
canvas.onmousedown = (e) => {
flag = true;
}
let body = document.getElementsByTagName("body")[0]
body.onmouseup = () => {
if (flag) {
flag = false;
if (canvas.offsetLeft > x - errorValue && canvas.offsetLeft < x + errorValue) {
if (successCallback) {
successCallback()
} else {
fixCodeBox("success")
wait(() => { fixCanvasCoordinate(0) }, 1000)
}
} else {
if (errorCallback) {
errorCallback()
} else {
fixCodeBox("error")
wait(() => { fixCanvasCoordinate(0) }, 1000)
}
}
}
}
body.onmousemove = (e) => {
if (flag) {
let left = e.clientX - canvasbg.getBoundingClientRect().left;
if (left > bigw - smallw / 2) {
return false
}
if (left < smallw / 2) {
return false
}
fixCanvasCoordinate(left - smallw / 2)
}
}
// 处理下方滑块鼠标事件
let codeBox = document.querySelector(".codebox");
let codeBoxWidth = codeBox.offsetWidth;
// let code = document.querySelector(".code");
code.onmousedown = (e) => {
flag = true;
}
// 修改下方滑块轨迹颜色
function fixCodeBox(type) {
if (type == "success") {
codeBox.style.background = "rgb(63, 247, 78)"
} else if (type == "error") {
codeBox.style.background = "rgb(223, 86, 161)"
} else {
codeBox.style.background = "rgb(0,150,200)"
}
}
// 修改canvas位置
fixCanvasCoordinate = (num = 0) => {
canvas.style.left = num + "px"
codeBox.style.width = (codeBoxWidth + num) + "px"
}
function wait(func, time) {
let timer = setTimeout(() => {
func();
fixCodeBox()
clearTimeout(timer)
}, time)
}
// 随机整数,最小值和范围
function handleRandom(min, range) {
return Math.floor(Math.random() * (range + 1) + min)
}
//绘制箭头
// let codecanvas = document.getElementById("codecanvas");
let codecanvastx = codecanvas.getContext("2d");
function drawArrow() {
codecanvastx.moveTo(10, 23);
codecanvastx.lineTo(30, 23);
codecanvastx.lineTo(30, 18);
codecanvastx.lineTo(40, 25.5);
codecanvastx.lineTo(30, 33);
codecanvastx.lineTo(30, 28);
codecanvastx.lineTo(10, 28);
codecanvastx.lineTo(10, 23);
codecanvastx.fillStyle = "rgba(0,0,0,0.8)"
codecanvastx.fill();
}
this.handleinit = () => {
fixCanvasCoordinate(0)
// 初始化
ctx.restore()
ctxbg.restore()
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctxbg.clearRect(0, 0, canvasbg.width, canvasbg.height)
x = handleRandom(100, bigw - 100 - smallw);
y = handleRandom(70, bigh - 70 - smallw);
handleImgs();
drawArrow();
drawBg();
drawCode();
}
x = handleRandom(100, bigw - 100 - smallw);
y = handleRandom(70, bigh - 70 - smallw);
handleImgs();
drawArrow();
drawBg();
drawCode();
}
3.css
#canvasbg{
position: absolute;
left: 0px;
top: 0px;
}
#canvas {
position: absolute;
left: 0px;
top: 0px;
}
.bottomcode {
width: 100%;
height: 55px;
box-sizing: border-box;
border: 1px solid #ddd;
border-radius: 3px;
background-color: #fff;
position: absolute;
left: 0px;
bottom:0px;
}
.codebox {
width: 52px;
height: 54px;
position: relative;
box-sizing: border-box;
border: 1px solid #ddd;
background: rgb(0, 150, 200);
border-radius: 3px;
}
.code {
width: 50px;
height: 52px;
line-height: 52px;
text-align: center;
/* border: 1px solid #000; */
border-radius: 3px;
box-sizing: border-box;
cursor: pointer;
position: absolute;
right: 0;
background: #fff;
}```