在html页面中,利用vue.js实现自定义指令完成拼图
时间: 2024-01-21 22:20:15 浏览: 158
以下是一个利用Vue.js实现自定义指令完成拼图的示例代码:
HTML部分:
```html
<div id="app">
<div class="puzzle" v-puzzle="image"></div>
</div>
```
JavaScript部分:
```javascript
Vue.directive('puzzle', {
inserted: function(el, binding) {
const imageUrl = binding.value; // 获取图片URL
const image = new Image();
image.src = imageUrl;
image.onload = function() {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const width = el.clientWidth;
const height = el.clientHeight;
canvas.width = width;
canvas.height = height;
const rows = 3; // 拼图行数
const cols = 3; // 拼图列数
const pieceWidth = width / cols;
const pieceHeight = height / rows;
const pieces = [];
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
const piece = {
x: j * pieceWidth,
y: i * pieceHeight,
imageX: j * pieceWidth,
imageY: i * pieceHeight,
imageWidth: pieceWidth,
imageHeight: pieceHeight,
index: i * cols + j
};
pieces.push(piece);
}
}
shuffle(pieces); // 打乱拼图
pieces.forEach(function(piece) {
ctx.drawImage(image, piece.imageX, piece.imageY, piece.imageWidth, piece.imageHeight, piece.x, piece.y, pieceWidth, pieceHeight);
});
el.appendChild(canvas);
const puzzle = new Puzzle(canvas, pieces, rows, cols, pieceWidth, pieceHeight);
puzzle.render();
};
}
});
function Puzzle(canvas, pieces, rows, cols, pieceWidth, pieceHeight) {
this.canvas = canvas;
this.ctx = canvas.getContext('2d');
this.pieces = pieces;
this.rows = rows;
this.cols = cols;
this.pieceWidth = pieceWidth;
this.pieceHeight = pieceHeight;
this.selectedPiece = null;
this.mouseX = 0;
this.mouseY = 0;
}
Puzzle.prototype.render = function() {
const self = this;
this.canvas.addEventListener('mousedown', function(event) {
const rect = self.canvas.getBoundingClientRect();
self.mouseX = event.clientX - rect.left;
self.mouseY = event.clientY - rect.top;
self.selectedPiece = self.getPieceAt(self.mouseX, self.mouseY);
if (self.selectedPiece) {
self.canvas.addEventListener('mousemove', onMouseMove);
}
});
function onMouseMove(event) {
const rect = self.canvas.getBoundingClientRect();
self.mouseX = event.clientX - rect.left;
self.mouseY = event.clientY - rect.top;
self.selectedPiece.x = self.mouseX - self.pieceWidth / 2;
self.selectedPiece.y = self.mouseY - self.pieceHeight / 2;
self.ctx.clearRect(0, 0, self.canvas.width, self.canvas.height);
self.pieces.forEach(function(piece) {
self.ctx.drawImage(self.canvas, piece.imageX, piece.imageY, piece.imageWidth, piece.imageHeight, piece.x, piece.y, self.pieceWidth, self.pieceHeight);
self.ctx.strokeStyle = 'white';
self.ctx.strokeRect(piece.x, piece.y, self.pieceWidth, self.pieceHeight);
});
}
this.canvas.addEventListener('mouseup', function(event) {
if (!self.selectedPiece) {
return;
}
self.canvas.removeEventListener('mousemove', onMouseMove);
const target = self.getPieceAt(self.selectedPiece.x + self.pieceWidth / 2, self.selectedPiece.y + self.pieceHeight / 2);
if (target) {
const tempX = self.selectedPiece.x;
const tempY = self.selectedPiece.y;
self.selectedPiece.x = target.x;
self.selectedPiece.y = target.y;
target.x = tempX;
target.y = tempY;
self.checkWin();
} else {
self.selectedPiece.x = self.selectedPiece.imageX;
self.selectedPiece.y = self.selectedPiece.imageY;
}
self.selectedPiece = null;
self.ctx.clearRect(0, 0, self.canvas.width, self.canvas.height);
self.pieces.forEach(function(piece) {
self.ctx.drawImage(self.canvas, piece.imageX, piece.imageY, piece.imageWidth, piece.imageHeight, piece.x, piece.y, self.pieceWidth, self.pieceHeight);
self.ctx.strokeStyle = 'white';
self.ctx.strokeRect(piece.x, piece.y, self.pieceWidth, self.pieceHeight);
});
});
};
Puzzle.prototype.getPieceAt = function(x, y) {
for (let i = 0; i < this.pieces.length; i++) {
const piece = this.pieces[i];
if (x >= piece.x && x < piece.x + this.pieceWidth && y >= piece.y && y < piece.y + this.pieceHeight) {
return piece;
}
}
return null;
};
Puzzle.prototype.checkWin = function() {
const solved = this.pieces.every(function(piece) {
return piece.x === piece.imageX && piece.y === piece.imageY;
});
if (solved) {
alert('You win!');
}
};
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
const temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
```
在这个示例中,我们定义了一个名为`puzzle`的自定义指令,用于处理拼图功能。该指令接收一个图片URL作为参数,并在插入到DOM后创建一个画布,将图片分割成若干个小块并打乱顺序。用户可以通过鼠标拖动来移动小块,直到拼图完成。
在JavaScript部分,我们使用了`Puzzle`类来管理拼图的状态和行为。`render`方法用于初始化拼图,`getPieceAt`方法用于获取指定坐标上的小块,`checkWin`方法用于检查拼图是否完成。我们还定义了一个`shuffle`函数,用于打乱小块的顺序。
该示例演示了如何利用Vue.js自定义指令来实现复杂的交互功能,同时也展示了如何使用Canvas API来进行图形渲染和交互。
阅读全文