【问题标题】:Chess moves in D3D3中的国际象棋移动
【发布时间】:2016-07-06 06:47:02
【问题描述】:

这个问题讨论了用 D3 画棋盘:

How to draw a chess board in D3?

另外,@jbkunst 还有一个令人难以置信的 D3 棋盘插件:

d3-chessboard plugin

但是,我想制作国际象棋的动画,如下所示:

(但更流畅;具有可配置的持续时间等)

你有什么建议吗,D3 风格?

我会很高兴现在只有一个动作的动画。稍后我将构建更通用的解决方案。

【问题讨论】:

  • 我知道这个问题需要d3,但是那里有很多国际象棋插件,功能齐全,可能会做得更好。话虽这么说,我想了解你是如何移动这些碎片的。你是在使用国际象棋插件,还是像第一个链接那样自己画?
  • @SideriteZackwehdex 我更喜欢独立的解决方案,而不是依赖插件的解决方案,但两者都可能很有趣。

标签: javascript animation d3.js svg chess


【解决方案1】:

如果你知道开始位置和停止位置,你可以为任何移动碎片的进程设置一个transition()。这将以动画的方式在各州之间进行补间。不过,这将是线性的,因此对于沿网格直线移动的任何人来说都会看起来不错,如果不这样做(例如骑士),那就不太好。对于骑士,我会先沿一个轴过渡,然后沿另一个轴过渡。

【讨论】:

    【解决方案2】:

    好吧,经过一些研究,我发现了这个:http://blog.visual.ly/creating-animations-and-transitions-with-d3-js/,它给出的答案几乎与 nucleon 相同:当您想要更改 d3 中元素的属性(如位置)并且执行类似 d3.select( selector).attr(attribute,value) 并且你必须使用 d3.select(selector).transition().attr(attribute,value)

    但是,插件绘制棋盘的方式,例如,您有 g 表示正方形的元素,包含一个矩形和一个文本。 rect 是正方形的颜色,而 text 是一块。如果您在 g 元素范围之外更改文本的转换,它就会消失。无论哪种方式,移动部件的模型都是错误的。

    假设您正在绘制您的棋盘,然后独立地绘制您的棋子,您可以使用上面链接中的示例将棋子移动到您想要的位置。小心骑士,你应该用两个过渡来移动它,也许你应该考虑一下捕捉动画。

    这就是我的全部。

    【讨论】:

      【解决方案3】:

      这是一个使用链式转换的快速实现,可让各个部分全面展开。我试图解释两种不同类型的运动,即棋子沿直线移动的“线”(即主教、城堡)和逐步移动的“步”(即骑士)。我是根据您在上一个问题中的工作得出的。

      // piece is the text element to move
      // position is an object like { x: 4, y: 6 } of the board position to move to
      // type is "step" or "line"
      function movePiece(piece, position, type) {
      
        var p = d3.select(piece),
            d = p.datum();
      
        (function repeat() {
      
          if (type === "step"){
            if (position.y === d.y) {
              if (position.x === d.x) {
                return;
              } else if (position.x > d.x) {
                d.x += 1;
              } else {
                d.x -= 1;
              }
            } else {
              if (position.y > d.y) {
                d.y += 1;
              } else {
                d.y -= 1;
              }
            }
          } else {
            if (position.x === d.x &&
                position.y === d.y) {
                return;
            }
            else {
              if (position.x != d.x){
                if (position.x > d.x) {
                  d.x += 1;
                } else {
                  d.x -= 1;
                }
              }
              if (position.y != d.y){
                if (position.y > d.y) {
                  d.y += 1;
                } else {
                  d.y -= 1;
                }
              }
            }
          }
      
          p = p.transition()
            .transition()
            .attr("x", d.x * fieldSize)
            .attr("y", d.y * fieldSize)
            .each("end", repeat);
        })();
      }
      

      注意,我并没有尝试编写代码是否合法。


      完整示例:

      <!DOCTYPE html>
      <html>
      
      <head>
        <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
        <link rel="stylesheet" href="style.css" />
        <script src="script.js"></script>
      </head>
      
      <body>
        <script>
          var pieces = {
            NONE: {
              name: "None",
              code: " "
            },
            WHITE_KING: {
              name: "White King",
              code: "\u2654"
            },
            WHITE_QUEEN: {
              name: "White Queen",
              code: "\u2655"
            },
            WHITE_ROOK: {
              name: "White Rook",
              code: "\u2656"
            },
            WHITE_BISHOP: {
              name: "White Bishop",
              code: "\u2657"
            },
            WHITE_KNIGHT: {
              name: "White Knight",
              code: "\u2658"
            },
            WHITE_POWN: {
              name: "White Pown",
              code: "\u2659"
            },
            BLACK_KING: {
              name: "Black King",
              code: "\u265A"
            },
            BLACK_QUEEN: {
              name: "Black Queen",
              code: "\u265B"
            },
            BLACK_ROOK: {
              name: "Black Rook",
              code: "\u265C"
            },
            BLACK_BISHOP: {
              name: "Black Bishop",
              code: "\u265D"
            },
            BLACK_KNIGHT: {
              name: "Black Knight",
              code: "\u265E"
            },
            BLACK_POWN: {
              name: "Black Pown",
              code: "\u265F"
            },
          };
      
          var board = [],
            boardDimension = 8,
            fieldSize = 40;
      
          for (var i = 0; i < boardDimension * boardDimension; i++) {
            board.push({
              x: i % boardDimension,
              y: Math.floor(i / boardDimension),
              piece: pieces.NONE
            });
          };
      
          board[0].piece = pieces.BLACK_ROOK
          board[1].piece = pieces.BLACK_KNIGHT
          board[2].piece = pieces.BLACK_BISHOP
          board[3].piece = pieces.BLACK_QUEEN
          board[4].piece = pieces.BLACK_KING
          board[5].piece = pieces.BLACK_BISHOP
          board[6].piece = pieces.BLACK_KNIGHT
          board[7].piece = pieces.BLACK_ROOK
      
          board[8].piece = pieces.BLACK_POWN
          board[9].piece = pieces.BLACK_POWN
          board[10].piece = pieces.BLACK_POWN
          board[11].piece = pieces.BLACK_POWN
          board[12].piece = pieces.BLACK_POWN
          board[13].piece = pieces.BLACK_POWN
          board[14].piece = pieces.BLACK_POWN
          board[15].piece = pieces.BLACK_POWN
      
          board[6 * 8 + 0].piece = pieces.WHITE_POWN
          board[6 * 8 + 1].piece = pieces.WHITE_POWN
          board[6 * 8 + 2].piece = pieces.WHITE_POWN
          board[6 * 8 + 3].piece = pieces.WHITE_POWN
          board[6 * 8 + 4].piece = pieces.WHITE_POWN
          board[6 * 8 + 5].piece = pieces.WHITE_POWN
          board[6 * 8 + 6].piece = pieces.WHITE_POWN
          board[6 * 8 + 7].piece = pieces.WHITE_POWN
      
          board[7 * 8 + 0].piece = pieces.WHITE_ROOK
          board[7 * 8 + 1].piece = pieces.WHITE_KNIGHT
          board[7 * 8 + 2].piece = pieces.WHITE_BISHOP
          board[7 * 8 + 3].piece = pieces.WHITE_QUEEN
          board[7 * 8 + 4].piece = pieces.WHITE_KING
          board[7 * 8 + 5].piece = pieces.WHITE_BISHOP
          board[7 * 8 + 6].piece = pieces.WHITE_KNIGHT
          board[7 * 8 + 7].piece = pieces.WHITE_ROOK
      
          var svg = d3.select('body')
            .append('svg')
            .attr('width', 500)
            .attr('height', 500);
      
          svg.selectAll("rect")
            .data(board)
            .enter()
            .append("rect")
            .style("class", "fields")
            .style("class", "rects")
            .attr("x", function(d) {
              return d.x * fieldSize;
            })
            .attr("y", function(d) {
              return d.y * fieldSize;
            })
            .attr("width", fieldSize + "px")
            .attr("height", fieldSize + "px")
            .style("fill", function(d) {
              if (((d.x % 2 == 0) && (d.y % 2 == 0)) ||
                ((d.x % 2 == 1) && (d.y % 2 == 1)))
                return "beige";
              else
                return "tan";
            });
      
          var pieces = svg.selectAll("text")
            .data(board)
            .enter().append("text")
            .attr("x", function(d) {
              d.piece.x = d.x;
              return d.x * fieldSize;
            })
            .attr("y", function(d) {
              d.piece.y = d.y;
              return d.y * fieldSize;
            })
            .style("font-size", "40")
            .attr("text-anchor", "middle")
            .attr("dy", "35px")
            .attr("dx", "20px")
            .text(function(d) {
              return d.piece.code;
            })
      
          pieces
            .append("title")
            .text(function(d) {
              return d.piece.name;
            });
      
          movePiece(pieces[0][6], {
            x: 5,
            y: 2
          }, "step");
          
          movePiece(pieces[0][58], {
            x: 5,
            y: 4
          }, "line");
          
          function movePiece(piece, position, type) {
            
            var p = d3.select(piece),
                d = p.datum();
                
            (function repeat() {
      
              if (type === "step"){
                if (position.y === d.y) {
                  if (position.x === d.x) {
                    return;
                  } else if (position.x > d.x) {
                    d.x += 1;
                  } else {
                    d.x -= 1;
                  }
                } else {
                  if (position.y > d.y) {
                    d.y += 1;
                  } else {
                    d.y -= 1;
                  }
                }
              } else {
                if (position.x === d.x &&
                    position.y === d.y) {
                    return;
                }
                else {
                  if (position.x != d.x){
                    if (position.x > d.x) {
                      d.x += 1;
                    } else {
                      d.x -= 1;
                    }
                  }
                  if (position.y != d.y){
                    if (position.y > d.y) {
                      d.y += 1;
                    } else {
                      d.y -= 1;
                    }
                  }
                }
              }
      
              p = p.transition()
                .transition()
                .attr("x", d.x * fieldSize)
                .attr("y", d.y * fieldSize)
                .each("end", repeat);
            })();
          }
        </script>
      </body>
      
      </html>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-07-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-11
        • 2013-05-24
        • 2022-06-17
        • 1970-01-01
        相关资源
        最近更新 更多