You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:如何用CSS和JS修改2行3列拼图的方块形状

自定义形状拼图块实现方案

我正在尝试用CSS和JavaScript制作一个2行3列的拼图,拼图块均为黑色且需切割成不同形状,用户需拖拽拼图块到面板完成拼接。已编写JavaScript代码生成面板与拼图块,并实现了拖拽功能,但不知如何将方形拼图块修改为其他形状,寻求技术帮助。

方法1:使用CSS clip-path 自定义形状

这是轻量化方案,无需额外图片,直接通过CSS裁剪出不规则形状,同时保证面板对应位置与拼图块形状匹配。

实现步骤

  1. 为2行3列的6个拼图块定义不同的形状类名
  2. 用div代替img作为拼图元素,通过CSS设置黑色背景和clip-path路径
  3. 保持原有拖拽逻辑,仅调整元素类型和样式

代码调整示例

CSS 样式

body {
  font-family: Arial, Helvetica, sans-serif;
  text-align: center;
}

#board {
  width: 390px;
  height: 380px;
  border: 2px solid purple;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
}

#pieces {
  width: 780px;
  height: 200px;
  border: 2px solid purple;
  margin: 20px auto;
  display: flex;
  gap: 10px;
  padding: 5px;
  box-sizing: border-box;
  justify-content: center;
  align-items: center;
}

.board-tile, .piece-tile {
  width: 130px;
  height: 190px;
  background-color: black;
  cursor: grab;
}

.board-tile:active, .piece-tile:active {
  cursor: grabbing;
}

/* 6种自定义形状 */
.shape-1 {
  clip-path: polygon(0 0, 100% 0, 100% 80%, 80% 100%, 0 100%);
}
.shape-2 {
  clip-path: polygon(0 0, 100% 0, 100% 100%, 20% 100%, 0 80%);
}
.shape-3 {
  clip-path: polygon(0 20%, 20% 0, 100% 0, 100% 100%, 0 100%);
}
.shape-4 {
  clip-path: polygon(0 0, 80% 0, 100% 20%, 100% 100%, 0 100%);
}
.shape-5 {
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, 20% 50%);
}
.shape-6 {
  clip-path: polygon(0 0, 100% 0, 80% 50%, 100% 100%, 0 100%);
}

JavaScript 逻辑

var rows = 2;
var columns = 3;

var currTile;
var otherTile;

var turns = 0;

// 定义6种形状类名
const shapeClasses = ['shape-1', 'shape-2', 'shape-3', 'shape-4', 'shape-5', 'shape-6'];

window.onload = function() {
  // 初始化2x3面板
  for (let r = 0; r < rows; r++) {
    for (let c = 0; c < columns; c++) {
      let tile = document.createElement("div");
      tile.classList.add('board-tile', shapeClasses[r*3 + c]);
      tile.draggable = true;

      // 绑定拖拽事件
      tile.addEventListener("dragstart", dragStart);
      tile.addEventListener("dragover", dragOver);
      tile.addEventListener("dragenter", dragEnter);
      tile.addEventListener("dragleave", dragLeave);
      tile.addEventListener("drop", dragDrop);
      tile.addEventListener("dragend", dragEnd);

      document.getElementById("board").append(tile);
    }
  }

  // 生成并打乱拼图块
  let pieces = [...shapeClasses];
  for (let i = pieces.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [pieces[i], pieces[j]] = [pieces[j], pieces[i]];
  }

  for (let i = 0; i < pieces.length; i++) {
    let tile = document.createElement("div");
    tile.classList.add('piece-tile', pieces[i]);
    tile.draggable = true;

    // 绑定拖拽事件
    tile.addEventListener("dragstart", dragStart);
    tile.addEventListener("dragover", dragOver);
    tile.addEventListener("dragenter", dragEnter);
    tile.addEventListener("dragleave", dragLeave);
    tile.addEventListener("drop", dragDrop);
    tile.addEventListener("dragend", dragEnd);

    document.getElementById("pieces").append(tile);
  }
}

// 拖拽核心逻辑
function dragStart() {
  currTile = this;
}

function dragOver(e) {
  e.preventDefault();
}

function dragEnter(e) {
  e.preventDefault();
}

function dragLeave() {}

function dragDrop() {
  otherTile = this;
}

function dragEnd() {
  // 仅允许拼图块与面板位置交换
  if (!currTile.classList.contains('piece-tile') || !otherTile.classList.contains('board-tile')) {
    return;
  }
  // 交换形状类名实现匹配
  const currShape = currTile.classList[1];
  const otherShape = otherTile.classList[1];
  
  currTile.classList.remove(currShape);
  currTile.classList.add(otherShape);
  
  otherTile.classList.remove(otherShape);
  otherTile.classList.add(currShape);

  turns += 1;
  // 如需显示步数,可添加元素并赋值:document.getElementById("turns").innerText = turns;
}

HTML 结构

<body>
  <br>
  <div id="board"></div>
  <div id="pieces"></div>
</body>

其他可选方案

  • SVG绘制复杂形状:用SVG路径定义更精细的拼图形状,直接嵌入到div中或作为独立文件引入
  • 带透明通道的PNG图片:用图像编辑工具制作不规则黑色拼图块(透明区域为裁剪部分),替换原代码中的图片资源

内容的提问来源于stack exchange,提问作者user15442201

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 07:35:20