{"id":2931,"date":"2020-05-07T12:03:43","date_gmt":"2020-05-07T04:03:43","guid":{"rendered":"http:\/\/www.yuguoxy.com\/geekhome\/?p=2931"},"modified":"2026-08-18T12:35:30","modified_gmt":"2026-08-18T04:35:30","slug":"%e8%b6%85%e7%ba%a7%e7%ae%80%e5%8d%95%e7%9a%84%e7%ba%afjs-%e8%b1%a1%e6%a3%8b%e7%9c%8b%e4%b8%80%e9%81%8d%e4%bd%a0%e4%b9%9f%e4%bc%9a%e5%86%99","status":"publish","type":"post","link":"https:\/\/ai.zhousir.top\/?p=2931","title":{"rendered":"\u8d85\u7ea7\u7b80\u5355\u7684\u7eafjs \u8c61\u68cb,\u770b\u4e00\u904d\u4f60\u4e5f\u4f1a\u5199"},"content":{"rendered":"<section id=\"wenyan\" style=\"font-family: system-ui, 'Apple Color Emoji', 'Segoe UI', 'Segoe UI Symbol', 'Noto Sans', Roboto, sans-serif; line-height: 1.75; font-size: 16px; color: #000000; caret-color: #000000;\" data-provider=\"WenYan\">\n<p style=\"margin: 1em 0px;\">\u8fd9\u662f\u4e00\u4e2a\u4e0b\u5348\u5199\u5b8c\u7684\u7eaf JS <strong style=\"color: #4870ac;\">\u4e2d\u56fd\u8c61\u68cb<\/strong>\uff1a\u7528 HTML5 Canvas \u753b\u68cb\u76d8\u3001\u68cb\u5b50\u548c\u9009\u4e2d\u52a8\u753b\uff0c\u4e3b\u8981\u8d70\u5b50\u903b\u8f91\u90fd\u5728\u4e00\u4efd\u811a\u672c\u91cc\u3002<\/p>\n<p style=\"margin: 1em 0px;\">\u68cb\u76d8\u662f 10 \u884c 9 \u5217\u5171 90 \u4e2a\u5750\u6807\uff1b\u68cb\u5b50\u5e26\u989c\u8272\u3001\u8d70\u6cd5\uff08\u9a6c\u8d70\u65e5\u3001\u76f8\u8d70\u7530\uff09\u3001\u9009\u4e2d\u6001\u548c\u5f53\u524d\u5750\u6807\u3002\u5b8c\u6574\u4ee3\u7801\u548c\u6548\u679c\u56fe\u90fd\u4fdd\u7559\u3002<\/p>\n<table style=\"display: table; text-align: left; overflow: auto; border-collapse: collapse; margin: 1.4em auto; max-width: 100%; table-layout: fixed; overflow-wrap: break-word; word-break: break-all;\" width=\"800\">\n<thead>\n<tr>\n<th style=\"border: 1px solid #d9dfe4; padding: 9px 12px; font-size: 0.75em; line-height: 22px; vertical-align: top; text-align: center; font-weight: bold; color: #4870ac; background: #f7f7f7;\">\u90e8\u5206<\/th>\n<th style=\"border: 1px solid #d9dfe4; padding: 9px 12px; font-size: 0.75em; line-height: 22px; vertical-align: top; text-align: center; font-weight: bold; color: #4870ac; background: #f7f7f7;\">\u505a\u4ec0\u4e48<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"border: 1px solid #d9dfe4; padding: 9px 12px; font-size: 0.75em; line-height: 22px; vertical-align: top;\">\u68cb\u76d8<\/td>\n<td style=\"border: 1px solid #d9dfe4; padding: 9px 12px; font-size: 0.75em; line-height: 22px; vertical-align: top;\">10 \u884c 9 \u5217\u300190 \u4e2a\u70b9\u3001\u70b9\u51fb\u5b9a\u4f4d<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #d9dfe4; padding: 9px 12px; font-size: 0.75em; line-height: 22px; vertical-align: top;\">\u68cb\u5b50<\/td>\n<td style=\"border: 1px solid #d9dfe4; padding: 9px 12px; font-size: 0.75em; line-height: 22px; vertical-align: top;\">\u7ea2\/\u9ed1\u3001\u8d70\u6cd5\u89c4\u5219\u3001\u9009\u4e2d\u6001\u3001\u5f53\u524d\u5750\u6807<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #d9dfe4; padding: 9px 12px; font-size: 0.75em; line-height: 22px; vertical-align: top;\">\u811a\u672c<\/td>\n<td style=\"border: 1px solid #d9dfe4; padding: 9px 12px; font-size: 0.75em; line-height: 22px; vertical-align: top;\">init \u753b\u5e03\u3001drawQipan\u3001\u7ed1\u5b9a\u4e8b\u4ef6\u3001\u8d70\u5b50\u6821\u9a8c<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p style=\"margin: 1em 0px;\">\u8fd9\u662f\u6211\u7b2c\u4e00\u6b21\u5199\u6e38\u620f\uff0c\u4e5f\u662f\u968f\u5174\u82b1\u4e86\u4e00\u4e0b\u5348\u5199\u7684\uff0c\u4ee3\u7801\u7ed3\u6784\u53ef\u80fd\u6ca1\u6709\u8bbe\u8ba1\u7684\u5f88\u6e05\u6670\uff0c\u4f46\u662f\u4e3b\u8981\u903b\u8f91\u8fd8\u662f\u5f88\u6e05\u695a\u3002\u8fd9\u6b21\u5229\u7528\u4e86html5 canvas \u753b\u5e03\u6548\u679c\uff0c\u628a\u68cb\u76d8\uff0c\u3002\u68cb\u5b50\uff0c\u52a8\u753b\u5199\u51fa<\/p>\n<p style=\"margin: 1em 0px;\">\u5199\u4efb\u4f55\u4e1c\u897f\uff0c\u9996\u5148\u8981\u77e5\u9053\u5b83\u7684\u7ec4\u6210\u90e8\u5206\u3002\u6bd4\u5982\u76d6\u5b50\uff0c\u4f60\u5f97\u5148\u51c6\u5907\u597d\uff0c\u6c99\u5b50\uff0c\u6c34\u6ce5\uff0c\u94a2\u7b4b\uff0c\u77f3\u7816\uff0c\u518d\u6253\u6210\u5730\u57fa\u518d\u4e00\u5c42\u4e00\u5c42\u7684\u76d6<\/p>\n<h2 style=\"padding: 1px 12.5px; color: #ffffff; margin: 1.2em 0px 1em; border-radius: 4px; display: inline-block; background-color: #4870ac; font-size: 1.3em;\">\u8c61\u68cb\u6e38\u620f\u7ec4\u6210\u90e8\u5206\u5f88\u7b80\u5355\u3002<\/h2>\n<p style=\"margin: 1em 0px;\">\u68cb\u76d8: \u670910 \u884c 9\u5217 \u62fc\u6210\u768490\u4e2a\u4e0d\u540c\u7684\u5750\u6807\u70b9,\u7ed9\u68cb\u5b50\u79fb\u52a8,\u68cb\u76d8\u4e8b\u4ef6\u6355\u6349\uff0c\u901a\u8fc7\u9f20\u6807\u70b9\u51fb\u68cb\u76d8\u4e0a\u9762\u5750\u6807\uff0c\u53bb\u5b9a\u4f4d\u70b9\u51fb\u5728\u68cb\u76d8\u54ea\u4e2a\u4f4d\u7f6e<\/p>\n<p style=\"margin: 1em 0px;\">\u68cb\u5b50:\uff5b<\/p>\n<p style=\"margin: 1em 0px;\">\u57fa\u672c\u5c5e\u6027\uff1a<\/p>\n<p style=\"margin: 1em 0px;\">\u989c\u8272:\u7ea2\u6216\u9ed1<\/p>\n<p style=\"margin: 1em 0px;\">\u79fb\u52a8\u89c4\u5219\u8bbe\u5b9a:\u4f8b\u5982\u5982\uff0c\u9a6c\u53ea\u80fd\u8d70\u65e5\uff0c\u76f8\u53ea\u80fd\u8d70\u7530<\/p>\n<p style=\"margin: 1em 0px;\">\u68cb\u5b50\u9009\u62e9\u4e2d\u72b6\u6001\u4e0b\u68cb\u5b50\u5f62\u72b6\u53d8\u5316<\/p>\n<p style=\"margin: 1em 0px;\">\u68cb\u5b50\u5f53\u524d\u5750\u6807\u4f4d\u7f6e<\/p>\n<p style=\"margin: 1em 0px;\">\uff5d<\/p>\n<p style=\"margin: 1em 0px;\">&nbsp;<\/p>\n<h2 style=\"padding: 1px 12.5px; color: #ffffff; margin: 1.2em 0px 1em; border-radius: 4px; display: inline-block; background-color: #4870ac; font-size: 1.3em;\">\u4e0b\u9762\u662f\u4ee3\u7801:<\/h2>\n<pre style=\"overflow: auto hidden; word-break: normal; white-space: pre; tab-size: 2; border-radius: 5px; line-height: 2; margin: 1em 0.5em; padding: 0.5em; box-shadow: rgba(0, 0, 0, 0.55) 0px 1px 5px; font-size: 12px; background: #002b36; max-width: 100%; overflow-wrap: normal;\"><code class=\"hljs\" style=\"word-break: normal; white-space: nowrap; tab-size: 2; font-size: 12px; font-family: Menlo, Monaco, Consolas, 'Liberation Mono', 'Roboto Mono', 'Courier New', 'Microsoft YaHei', monospace; display: block; overflow-x: auto; margin: 0.5em; padding: 3px 5px; color: #93a1a1; background: #002b36; overflow-wrap: normal;\">&lt;canvas id=&quot;xqCanvas&quot;&gt;&lt;\/canvas&gt;\n    &lt;script&gt;\n       (function () {\n           var XiangQi = window.XiangQi = function (id) {\n               this.canvas.w = this.canvas.w || document.body.clientWidth;\n               this.init(id);\n           }\n           XiangQi.prototype = {\n               canvas: {\n                   w: 0, \/\/ \u753b\u5e03\u5bbd\n                   h: 1000 \/\/ \u753b\u5e03\u9ad8\n               },\n               qipan: {\n                   cellSize: 100,  \/\/ \u68cb\u683c\u5927\u5c0f\n                   lineWidth: 2, \/\/ \u753b\u7b14\u5927\u5c0f\n                   strokeStyle: &quot;#000&quot;, \/\/ \u753b\u7b14\u989c\u8272\n                   markLen: 30,  \/\/ \u6807\u8bb0\u957f\u5ea6\n                   markPadding: 10 \/\/ \u6807\u8bb0\u95f4\u8ddd\n               },\n               init: function (id) {\n                   \/\/\u79c1\u6709\u5c5e\u6027\n                   var\n                       that = this;\n\n\n                   that.bodys = [];\n\n\n                   that.element = document.getElementById(id);\n                   that.element.width = that.canvas.w;\n                   that.element.height = that.canvas.h;\n                   that.ctx = that.element.getContext(&quot;2d&quot;);\n\n\n\n\n                   that.render();\n               },\n\n\n               render: function () {\n                   this.bindevent();\n               },\n               drawQipan: function () {\n\n\n                   var that = this, ctx = that.ctx, bodys = that.bodys\n                   ,\n\n\n                   r = 9,\n                   c = 8,\n                   cellSize = that.qipan.cellSize,\n                    w = cellSize * 8,\n                   h = r * cellSize,\n                   startX = (that.canvas.w - w) \/ 2,\n                   startY = (that.canvas.h - h) \/ 2,\n                   cX = 0,\n                   cY = 0,\n                   rX = 0,\n                   rY = 0\n                   ;\n                   ctx.beginPath();\n                   ctx.lineWidth = that.qipan.lineWidth;\n                   ctx.strokeStyle = that.qipan.strokeStyle;\n\n\n                   that.qipan.w = w;\n                   that.qipan.h = h;\n\n\n                   that.startX = startX;\n                   that.startY = startY;\n                   that.radius = cellSize \/ 2;\n                   that.maxR = r;\n                   that.maxC = c;\n                   for (var i = 0; i &lt;= r; i++) {\n                       cX = startX;\n                       cY = startY + (i * cellSize);\n                       ctx.moveTo(cX, cY);\n                       ctx.lineTo(cX + w, cY);\n\n\n                       bodys[i] = bodys[i] || [];\n                       for (var k = 0; k &lt;= c; k++) {\n\n\n                           rX = startX + (k * cellSize);\n                           rY = startY + (i * cellSize);\n\n\n                           bodys[i][k] = bodys[i][k] || {};\n                           bodys[i][k].x = rX;\n                           bodys[i][k].y = rY;\n                           bodys[i][k].r = i;\n                           bodys[i][k].c = k;\n                           \/\/{\n                           \/\/    x: rX,\n                           \/\/    y: rY,\n                           \/\/    r:i,\n                           \/\/    c:k\n                           \/\/});\n                           if (i == 4 &amp;&amp; k != 0 &amp;&amp; k != 8 || i == 9) {\n                               continue;\n                           }\n\n\n                           ctx.moveTo(rX, cY);\n                           ctx.lineTo(rX, rY + cellSize);\n                       }\n\n\n\n\n                   }\n                   ctx.stroke();\n\n\n\n\n                   ctx.restore();\n                   var fontOffsetY = bodys[4][0].y + that.radius;\n                   ctx.fillStyle = &quot;#000&quot;;\n                   ctx.font = &quot;bold 40px Arial&quot;;\n                   ctx.textBaseline = &quot;middle&quot;;\n\n\n                   ctx.fillText(&quot;\u6c49&quot;, startX + cellSize, fontOffsetY);\n                   ctx.fillText(&quot;\u754c&quot;, startX + cellSize * 2, fontOffsetY);\n                   ctx.fillText(&quot;\u695a&quot;, startX + cellSize * 5, fontOffsetY);\n                   ctx.fillText(&quot;\u6cb3&quot;, startX + cellSize * 6, fontOffsetY);\n                   ctx.save();\n\n\n\n\n                   ctx.beginPath();\n                   ctx.strokeStyle = &quot;#000&quot;;\n                   ctx.lineWidth = 2;\n                   ctx.moveTo(bodys[0][3].x, bodys[0][3].y);\n                   ctx.lineTo(bodys[2][5].x, bodys[2][5].y);\n                   ctx.moveTo(bodys[0][5].x, bodys[0][5].y);\n                   ctx.lineTo(bodys[2][3].x, bodys[2][3].y);\n\n\n\n\n\n\n                   ctx.moveTo(bodys[7][3].x, bodys[7][3].y);\n                   ctx.lineTo(bodys[9][5].x, bodys[9][5].y);\n                   ctx.moveTo(bodys[7][5].x, bodys[7][5].y);\n                   ctx.lineTo(bodys[9][3].x, bodys[9][3].y);\n\n\n                   ctx.stroke();\n\n\n\n\n\n\n\n\n                   function drawTopLeft(x, y, l, o) {\n                       var s = x - o - l, e = s + l, c = y - o;\n                       ctx.moveTo(s, c);\n                       ctx.lineTo(e, c);\n                       ctx.lineTo(e, c - l);\n                   }\n                   function drawTopRight(x, y, l, o) {\n                       var s = x + o + l, e = s - l, c = y - o;\n                       ctx.moveTo(s, c);\n                       ctx.lineTo(e, c);\n                       ctx.lineTo(e, c - l);\n                   }\n                   function drawBottomLeft(x, y, l, o) {\n                       var s = x - o - l, e = s + l, c = y + o;\n                       ctx.moveTo(s, c);\n                       ctx.lineTo(e, c);\n                       ctx.lineTo(e, c + l);\n                   }\n                   function drawBottomRight(x, y, l, o) {\n                       var s = x + o + l, e = s - l, c = y + o;\n                       ctx.moveTo(s, c);\n                       ctx.lineTo(e, c);\n                       ctx.lineTo(e, c + l);\n                   }\n\n\n                   function drawX(r, c, pos) {\n                       var x = bodys[r][c][\/c].x,\n                           y = bodys[r][c][\/c].y;\n                       ctx.beginPath();\n                       ctx.lineWidth = 3;\n                       ctx.strokeStyle = &quot;#000&quot;;\n                       if (pos[0]) {\n                           drawTopLeft(x, y, that.qipan.markLen, that.qipan.markPadding);\n                       }\n                       if (pos[1]) {\n                           drawTopRight(x, y, that.qipan.markLen, that.qipan.markPadding);\n                       }\n                       if (pos[2]) {\n                           drawBottomLeft(x, y, that.qipan.markLen, that.qipan.markPadding);\n                       }\n                       if (pos[3]) {\n                           drawBottomRight(x, y, that.qipan.markLen, that.qipan.markPadding);\n                       }\n                       ctx.stroke();\n\n\n                   }\n                   drawX(2, 1, [1, 1, 1, 1]);\n                   drawX(2, 7, [1, 1, 1, 1]);\n\n\n                   drawX(3, 0, [0, 1, 0, 1]);\n                   drawX(3, 2, [1, 1, 1, 1]);\n                   drawX(3, 4, [1, 1, 1, 1]);\n                   drawX(3, 6, [1, 1, 1, 1]);\n                   drawX(3, 8, [1, 0, 1, 0]);\n\n\n                   drawX(7, 1, [1, 1, 1, 1]);\n                   drawX(7, 7, [1, 1, 1, 1]);\n\n\n                   drawX(6, 0, [0, 1, 0, 1]);\n                   drawX(6, 2, [1, 1, 1, 1]);\n                   drawX(6, 4, [1, 1, 1, 1]);\n                   drawX(6, 6, [1, 1, 1, 1]);\n                   drawX(6, 8, [1, 0, 1, 0]);\n\n\n                   ctx.beginPath();\n                   ctx.lineWidth = 5;\n                   ctx.rect(startX - 5, startY - 5, w + 10, h + 10);\n                   ctx.stroke();\n\n\n\n\n\n\n               }\n\n\n           ,\n               renderQiJu: function (redBottom) {\n                   var qiJu = this.qiJu = [\n                   [&#39;\u8f66&#39;, &#39;\u9a6c&#39;, &#39;\u76f8&#39;, &#39;\u4ed5&#39;, &#39;\u5e05&#39;, &#39;\u4ed5&#39;, &#39;\u76f8&#39;, &#39;\u9a6c&#39;, &#39;\u8f66&#39;],\n                   [],\n                   [&#39;&#39;, &#39;\u70ae&#39;, &#39;&#39;, &#39;&#39;, &#39;&#39;, &#39;&#39;, &#39;&#39;, &#39;\u70ae&#39;, &#39;&#39;],\n                      [&#39;\u5175&#39;, &#39;&#39;, &#39;\u5175&#39;, &#39;&#39;, &#39;\u5175&#39;, &#39;&#39;, &#39;\u5175&#39;, &#39;&#39;, &#39;\u5175&#39;],\n                   [],\n                   [],\n                       [&#39;\u5352&#39;, &#39;&#39;, &#39;\u5352&#39;, &#39;&#39;, &#39;\u5352&#39;, &#39;&#39;, &#39;\u5352&#39;, &#39;&#39;, &#39;\u5352&#39;],\n                   [&#39;&#39;, &#39;\u70ae&#39;, &#39;&#39;, &#39;&#39;, &#39;&#39;, &#39;&#39;, &#39;&#39;, &#39;\u70ae&#39;, &#39;&#39;],\n                   [],\n                   [&#39;\u8eca&#39;, &#39;\u99ac&#39;, &#39;\u8c61&#39;, &#39;\u58eb&#39;, &#39;\u5c06&#39;, &#39;\u58eb&#39;, &#39;\u8c61&#39;, &#39;\u99ac&#39;, &#39;\u8eca&#39;],\n                   ];\n                   this.bodys = [];\n                   this.clearCanvas();\n                   this.drawQipan();\n                   this.redBottom = !!redBottom;\n                   if (this.redBottom) {\n                       qiJu.reverse();\n                   }\n                   this.drawQiJu(qiJu);\n               },\n               drawQiJu: function (qiJu) {\n                   for (var i = 0; i &lt; qiJu.length; i++) {\n                       for (var k = 0; k &lt; qiJu[i].length; k++) {\n                           if (qiJu[i][k] != &#39;&#39;) {\n                               this.bodys[i][k].qizi = new QiZi(this, i, k, qiJu[i][k], (this.redBottom &amp;&amp; i &gt; 5 || this.redBottom == false &amp;&amp; i &lt; 5) ? true : false);\n\n\n                           } else {\n                               this.bodys[i][k].qizi = null;\n                           }\n                       }\n                   }\n               },\n               clearCanvas: function () {\n                   this.ctx.clearRect(0, 0, this.canvas.w, this.canvas.h);\n               },\n               resetQiJu: function () {\n\n\n                   this.clearCanvas();\n                   this.drawQipan();\n\n\n                   this.eachBody(function (d) {\n                       if (d.qizi) {\n                           d.qizi.draw();\n                       }\n                   });\n\n\n\n\n               },\n               moveQizi: function (r, c, tr, tc) {\n                   this.bodys[tr][tc].qizi = this.bodys[r][c][\/c].qizi;\n                   this.bodys[r][c][\/c].qizi = null;\n                   this.resetQiJu();\n\n\n               }\n           ,\n               getPositions: function (e) {\n                   var x = e.x, y = e.y;\n                   if (e.layerX) {\n\n\n                       x = e.layerX;\n                       y = e.layerY;\n                   } else {\n                       x += document.body.scrollLeft;\n                       y += document.body.scrollTop;\n\n\n                   }\n\n\n\n\n                   return { x: x, y: y };\n               },\n               check: function (x, y) {\n                   var that = this,\n                       minX = that.startX - that.radius,\n                       minY = that.startY - that.radius,\n                       maxX = that.startX + that.qipan.w + that.radius,\n                           maxY = that.startY + that.qipan.h + that.radius\n                   ;\n\n\n                   return x &gt;= minX &amp;&amp; x &lt;= maxX &amp;&amp; y &gt;= minY &amp;&amp; y &lt;= maxY;\n               },\n\n\n               eachBody: function (handler) {\n                   var bodys = this.bodys, len = bodys.length;\n\n\n                   for (var i = 0; i &lt; len; i++) {\n\n\n                       for (var k = 0, len2 = bodys[i].length; k &lt; len2; k++) {\n                           if (handler(bodys[i][k], i, k) === true) {\n                               return bodys[i][k];\n                           }\n                       }\n                   }\n                   return null;\n               },\n               findPos: function (x, y) {\n                   var that = this, r = that.radius;\n                   return this.eachBody(function (pos) {\n\n\n                       var minX = pos.x - r, maxX = pos.x + r, minY = pos.y - r, maxY = pos.y + r;\n                       if (x &gt;= minX &amp;&amp; x &lt;= maxX &amp;&amp; y &gt;= minY &amp;&amp; y &lt;= maxY) {\n                           return true;\n                       }\n                   });\n               },\n               messages: {\n                   step1: &quot;\u7ea2\u65b9\u8d70&quot;,\n                   step2: &quot;\u9ed1\u65b9\u8d70&quot;\n               },\n               each: function (data, fn) {\n                   for (var i = 0, len = data.length; i &lt; len; i++) {\n                       fn.call(data[i], i, data[i]);\n                   }\n               },\n               showMess: function (mess) {\n                   this.ctx.fillStyle = &quot;red&quot;;\n                   this.ctx.font = &quot;16px&quot;;\n                   this.ctx.fillText(mess, 0, this.startY + this.qipan.h \/ 2);\n\n\n                   \/\/ this.ctx.st\n               },\n               bindevent: function () {\n                   var that = this;\n                   that.qiziRedMove = true;\n                   that.qiziSelected = false;\n                   that.qiziCurrent = null;\n                   this.element.addEventListener(&quot;click&quot;, function (e) {\n\n\n                       var xy = that.getPositions(e);\n\n\n                       if (that.check(xy.x, xy.y)) {\n                           var pos = that.findPos(xy.x, xy.y);\n                           if (pos != null) {\n\n\n\n\n                               if (pos.qizi &amp;&amp; pos.qizi.isred == that.qiziRedMove) {\n                                   that.resetQiJu();\n                                   that.qiziCurrent = pos.qizi;\n                                   that.qiziSelected = true;\n                                   pos.qizi.select();\n\n\n                                   return;\n                               }\n\n\n                               if (that.qiziSelected &amp;&amp; that.qiziCurrent != null &amp;&amp; that.qiziCurrent.moveTo(pos.r, pos.c)) {\n\n\n                                   that.qiziRedMove = !that.qiziRedMove;\n                                   that.qiziSelected = false;\n                               }\n                           }\n                       }\n                   });\n                   that.showMess(that.messages.step1);\n               },\n               save: function () {\n                   this.ctx.save();\n               },\n               restore: function () {\n                   this.ctx.restore();\n               }\n           };\n           var QiZi = function (qipan, r, c, text, isred) {\n               this.text = text;\n               this.isred = isred;\n               this.ctx = qipan.ctx;\n               this.qipan = qipan;\n               this.r = r;\n               this.c = c;\n\n               this.draw();\n               var that = this, maxR = that.qipan.maxR, maxC = that.qipan.maxC;\n               this.checkstep = (function () {\n                   if (text == &quot;\u5175&quot; || text == &quot;\u5352&quot;) {\n                       if (that.r &gt; 4) {\n\n                           return function (r, c) {\n                               return this.r &gt; 4 &amp;&amp; (this.r - 1) == r &amp;&amp; this.c == c\n                                   || this.r &lt;= 4 &amp;&amp; this.r == r &amp;&amp; ((this.c - 1) == c || (this.c + 1) == c)\n                                   || this.r &lt;= 4 &amp;&amp; (this.r - 1) == r &amp;&amp; this.c == c;\n                           }\n\n                       } else {\n                           return function (r, c) {\n                               return this.r &lt; 5 &amp;&amp; (this.r + 1) == r &amp;&amp; this.c == c || this.r &gt;= 5 &amp;&amp; this.r == r &amp;&amp; ((this.c - 1) == c || (this.c + 1) == c) || this.r &gt;= 5 &amp;&amp; (this.r + 1) == r &amp;&amp; this.c == c;\n                           }\n                       }\n                   } else if (text == &quot;\u70ae&quot;) {\n                       return function (r, c) {\n                           if (this.r != r &amp;&amp; this.c != c) {\n                               return false;\n                           }\n                           var bodys = this.qipan.bodys, step = this.getMoveRange(r, c);\n                           return bodys[r][c][\/c].qizi != null &amp;&amp; step == 1 || bodys[r][c][\/c].qizi == null &amp;&amp; step == 0;\n\n\n                       }\n                   } else if (text == &quot;\u8f66&quot; || text == &quot;\u8eca&quot;) {\n                       return function (r, c) {\n                           if (this.r != r &amp;&amp; this.c != c) {\n                               return false;\n                           }\n                           return this.getMoveRange(r, c) == 0;\n                       }\n                   } else if (text == &quot;\u9a6c&quot; || text == &quot;\u99ac&quot;) {\n                       return function (r, c) {\n\n\n                           return this.r - 2 == r &amp;&amp; this.c - 1 == c &amp;&amp; this.isEnemyOrEmpty(this.r - 1, this.c)\n                               || this.r - 2 == r &amp;&amp; this.c + 1 == c &amp;&amp; this.isEnemyOrEmpty(this.r - 1, this.c)\n                                   || this.r + 2 == r &amp;&amp; this.c - 1 == c &amp;&amp; this.isEnemyOrEmpty(this.r + 1, this.c)\n                               || this.r + 2 == r &amp;&amp; this.c + 1 == c &amp;&amp; this.isEnemyOrEmpty(this.r + 1, this.c)\n                                   || this.r - 1 == r &amp;&amp; this.c - 2 == c &amp;&amp; this.isEnemyOrEmpty(this.r, this.c - 1)\n                               || this.r - 1 == r &amp;&amp; this.c + 2 == c &amp;&amp; this.isEnemyOrEmpty(this.r, this.c + 1)\n                                 || this.r + 1 == r &amp;&amp; this.c - 2 == c &amp;&amp; this.isEnemyOrEmpty(this.r, this.c - 1)\n                               || this.r + 1 == r &amp;&amp; this.c + 2 == c &amp;&amp; this.isEnemyOrEmpty(this.r, this.c + 1)\n                           ;\n                       }\n                   } else if (text == &quot;\u76f8&quot; || text == &quot;\u8c61&quot;) {\n                       return function (r, c) {\n                           return this.r - 2 == r &amp;&amp; this.c - 2 == c &amp;&amp; this.isEnemyOrEmpty(this.r - 1, this.c - 1)\n                           || this.r - 2 == r &amp;&amp; this.c + 2 == c &amp;&amp; this.isEnemyOrEmpty(this.r - 1, this.c + 1)\n                               || this.r + 2 == r &amp;&amp; this.c - 2 == c &amp;&amp; this.isEnemyOrEmpty(this.r + 1, this.c - 1)\n                           || this.r + 2 == r &amp;&amp; this.c + 2 == c &amp;&amp; this.isEnemyOrEmpty(this.r + 1, this.c + 1)\n                           ;\n                       }\n                   } else if (text == &quot;\u58eb&quot; || text == &quot;\u4ed5&quot;) {\n                       if (that.r &gt; 4) {\n                           return function (r, c) {\n                               var l = 7, l2 = 9, b = 3, b2 = 5;\n                               if (r &lt; l || r &gt; l2 || c &lt; b || c &gt; b2) {\n                                   return false;\n                               }\n                               return this.r - 1 == r &amp;&amp; this.c - 1 == c\n                                   || this.r - 1 == r &amp;&amp; this.c + 1 == c\n                                   || this.r + 1 == r &amp;&amp; this.c - 1 == c\n                                 || this.r + 1 == r &amp;&amp; this.c + 1 == c\n                               ;\n                           }\n                       } else {\n                           return function (r, c) {\n                               var l = 0, l2 = 3, b = 3, b2 = 5;\n                               if (r &lt; l || r &gt; l2 || c &lt; b || c &gt; b2) {\n                                   return false;\n                               }\n                               return this.r - 1 == r &amp;&amp; this.c - 1 == c\n                                   || this.r - 1 == r &amp;&amp; this.c + 1 == c\n                                   || this.r + 1 == r &amp;&amp; this.c - 1 == c\n                                 || this.r + 1 == r &amp;&amp; this.c + 1 == c\n                               ;\n                           }\n                       }\n\n\n                   } else if (text == &quot;\u5c06&quot; || text == &quot;\u5e05&quot;) {\n                       if (that.r &gt; 4) {\n                           return function (r, c) {\n                               var l = 7, l2 = 9, b = 3, b2 = 5;\n                               if (r &lt; l || r &gt; l2 || c &lt; b || c &gt; b2) {\n                                   return false;\n                               }\n                               return this.r - 1 == r &amp;&amp; this.c == c\n                                   || this.r + 1 == r &amp;&amp; this.c == c\n                                   || this.r == r &amp;&amp; this.c - 1 == c\n                                 || this.r == r &amp;&amp; this.c + 1 == c\n                               ;\n                           }\n                       } else {\n                           return function (r, c) {\n                               var l = 0, l2 = 3, b = 3, b2 = 5;\n                               if (r &lt; l || r &gt; l2 || c &lt; b || c &gt; b2) {\n                                   return false;\n                               }\n                               return this.r - 1 == r &amp;&amp; this.c == c\n                               || this.r + 1 == r &amp;&amp; this.c == c\n                               || this.r == r &amp;&amp; this.c - 1 == c\n                             || this.r == r &amp;&amp; this.c + 1 == c\n                               ;\n                           }\n                       }\n                   }\n                   return function () {\n\n                   };\n\n               }());\n           }\n           QiZi.prototype = {\n               isEnemyOrEmpty: function (r, c) {\n                   return this.qipan.bodys[r][c][\/c].qizi == null;\n               },\n               getMoveRange: function (r, c) {\n                   var\n                               step = 0,\n                               bodys = this.qipan.bodys,\n                               minR = Math.min(this.r, r), maxR = Math.max(this.r, r), minC = Math.min(this.c, c), maxC = Math.max(this.c, c);\n\n\n                   if (this.r != r &amp;&amp; this.c == c) {\n                       for (var i = minR; i &lt; maxR; i++) {\n\n\n                           if (i != this.r &amp;&amp; i != r &amp;&amp; bodys[i][c][\/c].qizi != null) {\n\n\n                               step++;\n                           }\n                       }\n                   } else if (this.r == r &amp;&amp; this.c != c) {\n                       for (var i = minC; i &lt; maxC; i++) {\n\n\n                           if (i != this.c &amp;&amp; i != c &amp;&amp; bodys[r][i].qizi != null) {\n                               step++;\n                           }\n                       }\n                   }\n                   return step;\n               },\n               draw: function () {\n                   var\n                       qipan = this.qipan,\n                       isred = this.isred,\n                ctx = this.ctx,\n                bodys = qipan.bodys,\n                radius = qipan.radius,\n                xy = this.getPostion(this.r, this.c)\n                   ;\n                   ctx.beginPath();\n                   ctx.strokeStyle = isred ? &quot;red&quot; : &quot;#000&quot;;\n                   ctx.lineWidth = 1;\n\n\n                   this.x = xy.x;\n                   this.y = xy.y;\n                   this.left = xy.x - radius;\n                   this.top = xy.y - radius;\n                   this.right = xy.x + radius;\n                   this.bottom = xy.y + radius;\n\n\n                   ctx.arc(xy.x, xy.y, radius, 0, 2 * Math.PI);\n\n\n                   ctx.fillStyle = &quot;rgba(250, 240, 240,1)&quot;;\n                   ctx.fill();\n                   ctx.stroke();\n\n\n                   ctx.fillStyle = isred ? &quot;red&quot; : &quot;#000&quot;;\n                   ctx.textAlign = &quot;center&quot;;\n                   ctx.fillText(this.text, xy.x, xy.y);\n               },\n               getPostion: function (r, c) {\n                   return {\n                       x: this.qipan.bodys[r][c][\/c].x,\n                       y: this.qipan.bodys[r][c][\/c].y\n                   };\n               },\n\n               moveTo: function (r, c) {\n                   if (this.checkstep(r, c)) {\n                       var r2 = this.r, c2 = this.c;\n                       this.r = r;\n                       this.c = c;\n                       this.qipan.moveQizi(r2, c2, r, c);\n                       return true;\n                   }\n                   return false;\n\n               },\n               select: function () {\n                   var that = this, ctx = that.ctx, len = 15;\n                   ctx.beginPath();\n                   ctx.strokeStyle = &quot;#00ff21&quot;;\n                   ctx.lineWidth = 5;\n\n\n                   ctx.moveTo(that.left, that.top + len);\n                   ctx.lineTo(that.left, that.top);\n                   ctx.lineTo(that.left + len, that.top);\n\n\n                   ctx.moveTo(that.left, that.bottom - len);\n                   ctx.lineTo(that.left, that.bottom);\n                   ctx.lineTo(that.left + len, that.bottom);\n\n\n                   ctx.moveTo(that.right, that.top + len);\n                   ctx.lineTo(that.right, that.top);\n                   ctx.lineTo(that.right - len, that.top);\n\n\n                   ctx.moveTo(that.right, that.bottom - len);\n                   ctx.lineTo(that.right, that.bottom);\n                   ctx.lineTo(that.right - len, that.bottom);\n                   ctx.stroke();\n               }\n           }\n       }())\n\n       var xq = new XiangQi(&quot;xqCanvas&quot;);\n       xq.renderQiJu(true);\n&lt;\/script&gt;\n<\/code><\/pre>\n<p><a href=\"https:\/\/ai.zhousir.top\/wp-content\/uploads\/2020\/05\/20200507120230.png\" rel=\"fancybox\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/ai.zhousir.top\/wp-content\/uploads\/2020\/05\/20200507120230.png\" alt=\"20200507120230\" width=\"761\" height=\"827\" class=\"alignnone size-full wp-image-2933\" \/><\/a><\/p>\n<p style=\"margin: 1em 0px;\">\u539f\u6587\u94fe\u63a5\uff1a<a href='https:\/\/blog.csdn.net\/long5305350\/java\/article\/details\/44056963' target='_blank' class='url'>https:\/\/blog.csdn.net\/long5305350\/java\/article\/details\/44056963<\/a><\/p>\n<blockquote style=\"display: block; font-size: 0.9em; border-left: 3px solid #4870ac; padding: 0.5em 1em; margin: 0px; background: #f6f8fa; color: #40464f;\">\n<p style=\"margin: 1em 0px;\"><strong style=\"color: #4870ac;\">\u4e00\u53e5\u8bdd\u603b\u7ed3\uff1aCanvas \u753b 10\u00d79 \u68cb\u76d8\uff0c\u7528\u5750\u6807\u70b9\u9009\u68cb\u5b50\uff0c\u518d\u6309\u5404\u5b50\u8d70\u6cd5\u6821\u9a8c\u843d\u70b9\u2014\u2014\u89c4\u5219\u5199\u8fdb\u68cb\u5b50\u5bf9\u8c61\uff0c\u6e32\u67d3\u548c\u70b9\u51fb\u7ed1\u5b9a\u5728\u540c\u4e00\u4efd\u811a\u672c\u3002<\/strong><\/p>\n<\/blockquote>\n<\/section>\n","protected":false},"excerpt":{"rendered":"<p>\u8fd9\u662f\u4e00\u4e2a\u4e0b\u5348\u5199\u5b8c\u7684\u7eaf JS \u4e2d\u56fd\u8c61\u68cb\uff1a\u7528 HTML5 Canvas \u753b\u68cb\u76d8\u3001\u68cb\u5b50\u548c\u9009\u4e2d\u52a8\u753b\uff0c\u4e3b\u8981\u8d70\u5b50\u903b\u8f91\u90fd\u5728\u4e00 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[109,105],"tags":[150,144],"_links":{"self":[{"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=\/wp\/v2\/posts\/2931"}],"collection":[{"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2931"}],"version-history":[{"count":3,"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=\/wp\/v2\/posts\/2931\/revisions"}],"predecessor-version":[{"id":2936,"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=\/wp\/v2\/posts\/2931\/revisions\/2936"}],"wp:attachment":[{"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2931"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2931"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ai.zhousir.top\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2931"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}