<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
body {
margin: 0;
}
#canvas {
border: 1px solid red;
}
</style>
</head>
<body>
<div id="app">
<canvas id="canvas" width="800" height="800" @click="main($event)"></canvas>
<button id="undo" :disabled='prohibit' @click="redo">撤销</button>
<button id="que" @click="determine">确定</button>
<button class="clear" @click="clear">取消</button>
<button class="draw" @click="draw($event)">绘制</button>
</div>
</body>
<script src="./vue.js"></script>
<script src="./pako.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: "#app",
data: {
clicks: 0,
lastClick: [0, 0],
coordinateA: [],
coordinateB: [],
// 撤销的数组
undoHistoryA: [],
undoHistoryB: [],
a: {},
b: {},
x: 0,
y: 0,
prohibit: true,
chu: true,
},
watch: {
},
methods: {
getCursorPosition(e) {
if (e.pageX != undefined && e.pageY != undefined) {
var rect = canvas.getBoundingClientRect();
this.x = e.clientX - rect.left * (canvas.width / rect.width);
this.y = e.clientY - rect.top * (canvas.height / rect.height);
} else {
this.x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
this.y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
return [this.x, this.y];
},
drawLine(e) {
var canvas = document.getElementById("canvas")
context = canvas.getContext('2d');
context.beginPath();
this.x = this.getCursorPosition(e)[0]
this.y = this.getCursorPosition(e)[1]
if (this.chu == true) {
// 保存画布的像素数据
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
const compressed = pako.deflate(new Uint8Array(imageData.data)); // 压缩,减小存储开销
this.undoHistoryA.push(compressed);
console.log(this.undoHistoryA.length, '刚开始存入的值')
this.chu = false
}
context.arc(this.x, this.y, 10, 0, 10 * Math.PI)
context.stroke();
if (this.clicks != 1) {
this.clicks++;
} else {
// 不绘制, 只是将当前位置移动到新的目的坐标(x, y);
context.moveTo(this.lastClick[0], this.lastClick[1]);
// 不仅将当前位置移动到新的目标坐标(x,y),而且在两个坐标之间画一条直线。
context.lineTo(this.x, this.y, 6);
context.strokeStyle = '#000000';
context.stroke();
this.clicks = 0;
}
this.lastClick = [this.x, this.y];
if (this.clicks == 0) {
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
const compressed = pako.deflate(new Uint8Array(imageData.data)); // 压缩,减小存储开销
this.undoHistoryA.push(compressed);
this.prohibit = false
var x = this.x
var y = this.y
this.b = {
x,
y
}
this.coordinateB.push(this.b)
} else {
var x = this.x
var y = this.y
this.a = {
x,
y
}
this.coordinateA.push(this.a)
}
},
main(e) {
this.drawLine(e)
},
redo() {
// 撤销
{
this.undoHistoryA.pop();
const compressed = this.undoHistoryA[this.undoHistoryA.length - 1]
//算法
this.coordinateA.pop()
this.coordinateB.pop()
try {
const decompressed = pako.inflate(compressed); // 解压
const uint8ClampedArray = new Uint8ClampedArray(decompressed);
const imageData = new ImageData(uint8ClampedArray, canvas.width, canvas.height);
context.putImageData(imageData, 0, 0);
} catch (error) {
console.error(error);
}
if (this.undoHistoryA.length === 0) {
this.prohibit = true;
}
}
},
determine() {
console.log(this.coordinateA, this.coordinateB, '坐标信息数组')
},
clear() {
context.clearRect(0, 0, canvas.width, canvas.height);
},
draw(e) {
this.main(e)
}
},
mounted() {
},
})
</script>
</html>
</html>
</html>
canvans绘制鼠标点击遍绘制一条直线,并支持撤销
最新推荐文章于 2024-07-30 10:56:44 发布