我正在创建一个简单的拼图游戏。为了做到这一点,我需要将我正在使用的图片切成 20 块。 Javascript 有没有办法将一张图片切成 20 个相等的部分,并将它们保存为网页中的 20 个不同的对象?或者我只需要进入 Photoshop 自己剪下每张图片并调用它?
使用 Canvas 很容易做到这一点。总体思路是:
var image = new Image();
image.onload = cutImageUp;
image.src = 'myimage.png';
function cutImageUp() {
var imagePieces = [];
for(var x = 0; x < numColsToCut; ++x) {
for(var y = 0; y < numRowsToCut; ++y) {
var canvas = document.createElement('canvas');
canvas.width = widthOfOnePiece;
canvas.height = heightOfOnePiece;
var context = canvas.getContext('2d');
context.drawImage(image, x * widthOfOnePiece, y * heightOfOnePiece, widthOfOnePiece, heightOfOnePiece, 0, 0, canvas.width, canvas.height);
imagePieces.push(canvas.toDataURL());
}
}
// imagePieces now contains data urls of all the pieces of the image
// load one piece onto the page
var anImageElement = document.getElementById('myImageElementInTheDom');
anImageElement.src = imagePieces[0];
}
您可以通过将图像设置为 div 上的背景,然后设置其背景位置来实现此目的。这与使用 CSS Sprites 基本相同。
(假设作品大小为 100 x 100 像素)
<div class="puzzle piece1"></div>
<div class="puzzle piece2"></div>
CSS:
.puzzle {
background-image:url(/images/puzzle.jpg);
width:100px;
height:100px;
}
.piece1 {
background-position:0 0
}
.piece2 {
background-position:-100px -100px
}
您可以使用drawImage方法对源图像的一部分进行切片并将它们绘制到画布上:
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Using_images
类似的东西:
document.getElementById("vangogh").onclick=function()
{
draw();
};
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
ctx.drawImage(document.getElementById('source'),33,45);
}
然后为您的新实体创建可拖动的内容:
<div id="columns">
<div class="column" draggable="true"><header>A</header></div>
<div class="column" draggable="true"><header>B</header></div>
<div class="column" draggable="true"><header>C</header></div>
</div>
如果您想将图像分成单独的部分,您可以创建具有相同背景图像 URL 的元素,并给它们不同的背景坐标。
initializeAllPuzzles();
document.querySelector('button[data-action="shuffle"]')
.addEventListener('click', (e) => {
shuffleChildren(document.querySelector('.puzzle'));
});
function initializeAllPuzzles() {
document.querySelectorAll('.puzzle').forEach(initializePuzzle);
}
function initializePuzzle(puzzle) {
const options = {
imgSrc: puzzle.dataset.src,
width: +puzzle.dataset.width,
height: +puzzle.dataset.height,
size: +puzzle.dataset.size
};
const columns = options.width / options.size;
Object.assign(puzzle.style, {
display: 'grid',
gridTemplateColumns: `repeat(${columns}, 1fr)`,
});
for (let y = 0; y < options.height; y += options.size) {
for (let x = 0; x < options.width; x += options.size) {
puzzle.append(createPiece(x, y, options));
}
}
}
function createPiece(x, y, options) {
const piece = document.createElement('div');
Object.assign(piece.style, {
width: `${options.size}px`,
height: `${options.size}px`,
background: `url(${options.imgSrc}) -${x}px -${y}px`
});
return piece;
}
function shuffleChildren(el) {
const tmp = el.cloneNode(true);
for (let i = tmp.children.length - 1; i >= 0; i--) {
tmp.appendChild(tmp.children[Math.random() * i |0]);
}
el.parentNode.replaceChild(tmp, el);
}
.puzzle {
gap: 0.125rem;
}
<button type="button" data-action="shuffle">Shuffle</button>
<div
class="puzzle"
data-src="https://i.stack.imgur.com/C4Ayj.jpg"
data-width="1500"
data-height="1500"
data-size="60"></div>