vue+canvas实现图片滑块拼图验证码
效果图
完整代码
<template>
<div class="content" @mousemove="sideronDrag" @mouseup="stopDrag2">
<div>
<p>{{ text }}</p>
</div>
<canvas ref="background" id="background" width="500" height="400"></canvas>
<canvas ref="Puzzle" id="Puzzle" width="500" height="400"></canvas>
<div class="sliderBox">
<div
class="sider"
@mousedown="startDrag"
@mouseup="stopDrag2"
:style="{ transform: `translate(${x}px, ${y}px)` }"
oncontextmenu="return disableRightClick(event)">
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
text: "拖动下方滑块完成拼图",
stop: false,
x: 0,
y: 0,
Puzzle: {
size: 50,
},
gapX: 200,
gapY: 100,
dragging: false,
startX: 0,
startY: 0,
imageX: 0,
imageY: 0,
image: new Image(),
image2: new Image(),
// image2:"",
};
},
created() {},
mounted() {
this.gapX = Math.round(
((1 + Math.random()) * this.$refs.background.width) / 3
);
const canvas = document.getElementById("background");
const ctx = canvas.getContext("2d");
const Puzzle = document.getElementById("Puzzle");
const Puzzlectx = Puzzle.getContext("2d");
//导入图片路径
this.image.src = require("@/assets/images/头像01.jpeg");
this.image.onload = () => {
ctx.drawImage(this.image, 0, 0);
ctx.fillStyle = "white";
ctx.rect(this.gapX, this.gapY, this.Puzzle.size, this.Puzzle.size);
ctx.fill();
Puzzlectx.drawImage(
this.image,
this.gapX,
this.gapY,
50,
50,
0,
this.gapY,
this.Puzzle.size,
this.Puzzle.size
);
this.image2.src = Puzzle.toDataURL("image/png");
};
},
methods: {
disableRightClick(event) {
if (event.button === 2) { // 右键点击的按钮编号是2
event.preventDefault(); // 阻止默认行为
}
},
//绘制图片
draw() {
const background = this.$refs.background;
const Puzzle = this.$refs.Puzzle;
const Puzzlectx = Puzzle.getContext("2d");
Puzzle.width = background.width;
Puzzle.height = background.height;
Puzzlectx.drawImage(this.image2, this.imageX, this.imageY);
},
//开始绘制
startDrag(e) {
this.dragging = true;
this.startX = e.clientX - this.x;
},
//在绘制中
onDrag(e) {
if (!this.dragging) return;
const dx = e.clientX - this.startX;
this.imageX += dx;
this.startX = e.clientX;
this.draw();
},
sideronDrag(e) {
if (!this.dragging || this.stop == true) return;
if (this.x > 500 - 50) {
this.x = this.x - 3;
return;
}
if (this.x < 0) {
this.x = this.x + 3;
return;
}
this.x = e.clientX - this.startX;
this.imageX = this.x;
this.draw();
},
//停止绘制
stopDrag2() {
this.dragging = false;
if (this.imageX >= this.gapX - 3 && this.imageX <= this.gapX + 3) {
var c = document.getElementById("background");
var ctx = c.getContext("2d");
ctx.font = "30px Arial";
ctx.fillText(
"验证成功",
background.width / 2 - 60,
background.height / 2
);
this.text = "验证成功!!!!!!";
this.stop = true;
}
},
},
computed: {},
};
</script>
<style lang="scss" scoped>
.content {
position: relative;
margin: auto;
width: fit-content;
canvas {
border: 1px solid black;
}
#background {
}
#Puzzle {
position: absolute;
left: 0;
}
.sliderBox {
margin-top: 10px;
border: 1px solid black;
border-radius: 10px;
height: 50px;
padding: 3px;
background-color: #f7f9fa;
color: #45454c;
border: 1px solid #e4e7eb;
.sider {
border-radius: 10px;
height: 40px;
width: 50px;
border: 0px solid #1991fa;
background-color: #d1e9fe;
color: white;
font-size: 25x;
display: flex;
justify-content: center;
align-items: center;
.line {
border: 1px solid white;
background-color: white;
width: 2px;
height: 25px;
margin: 6px;
}
}
}
}
</style>