{"id":7362,"date":"2018-02-05T02:57:54","date_gmt":"2018-02-04T18:57:54","guid":{"rendered":"http:\/\/www.zhangxinxu.com\/wordpress\/?p=7362"},"modified":"2018-02-05T02:57:54","modified_gmt":"2018-02-04T18:57:54","slug":"canvas-text-break-line-letter-spacing-vertical","status":"publish","type":"post","link":"https:\/\/www.zhangxinxu.com\/wordpress\/2018\/02\/canvas-text-break-line-letter-spacing-vertical\/","title":{"rendered":"canvas\u6587\u672c\u7ed8\u5236\u81ea\u52a8\u6362\u884c\u3001\u5b57\u95f4\u8ddd\u3001\u7ad6\u6392\u7b49\u5b9e\u73b0"},"content":{"rendered":"<p>by <a href=\"http:\/\/www.zhangxinxu.com\/\">zhangxinxu<\/a> from <a href=\"http:\/\/www.zhangxinxu.com\/wordpress\/?p=7362\">http:\/\/www.zhangxinxu.com\/wordpress\/?p=7362<\/a><br \/>\n\u672c\u6587\u53ef\u5168\u6587\u8f6c\u8f7d\uff0c\u4f46\u9700\u5f97\u5230\u539f\u4f5c\u8005\u4e66\u9762\u8bb8\u53ef\uff0c\u540c\u65f6\u4fdd\u7559\u539f\u4f5c\u8005\u548c\u51fa\u5904\uff0c\u6458\u8981\u5f15\u6d41\u5219\u968f\u610f\u3002<\/p>\n<h3>\u4e00\u3001canvas\u5bf9\u6587\u5b57\u6392\u7248\u7684\u652f\u6301\u5f88\u5f31<\/h3>\n<p>\u548cCSS\u76f8\u6bd4\uff0cSVG\u4ee5\u53cacanvas\u5bf9\u6587\u5b57\u6392\u7248\u7684\u652f\u6301\u5f88\u5f31\u3002<\/p>\n<p>\u5728CSS\u4e2d\u5929\u7136\u652f\u6301\u7684\u6587\u672c\u81ea\u52a8\u6362\u884c\uff0c\u5176\u4ed6<code>letter-sapcing<\/code>\u5b57\u95f4\u8ddd\uff0c<code>writing-mode<\/code>\u7ad6\u6392\u7b49\u90fd\u662f\u4e00\u4e2aCSS\u5c5e\u6027\u5c31\u53ef\u4ee5\u5b9e\u73b0\u3002\u4f46\u662f\u5728canvas\u4e2d\uff0c\u5168\u90e8\u90fd\u4e0d\u652f\u6301\u3002<\/p>\n<p>canvas\u7ed8\u5236\u6587\u672cAPI\u4e3a\uff1a<\/p>\n<pre>CanvasRenderingContext2D.fillText(text, x, y [, maxWidth]);<\/pre>\n<dl>\n<dt><strong>text<\/strong><\/dt>\n<dd><code>text<\/code>\u662f\u9700\u8981\u7ed8\u5236\u7684\u6587\u672c\u3002<\/dd>\n<dt><strong>x<\/strong><\/dt>\n<dd><code>x<\/code>\u662f\u6587\u672c\u7ed8\u5236\u7684\u6c34\u5e73\u53c2\u8003\u70b9\u5750\u6807\u3002\u968f\u7740<code>CanvasRenderingContext2D.textAlign<\/code>\u7684\u8bbe\u7f6e\u4e0d\u540c\uff0c<code>x<\/code>\u7684\u5750\u6807\u4f4d\u7f6e\u4e5f\u4e0d\u540c\u3002\u53ef\u4ee5\u8868\u793a\u8fd9\u6bb5\u6587\u5b57\u5185\u5bb9\u5de6\u4fa7\u5750\u6807\uff0c\u6216\u6c34\u5e73\u4e2d\u5fc3\u5750\u6807\uff0c\u6216\u53f3\u4fa7\u5750\u6807\u3002<\/dd>\n<dt><strong>y<\/strong><\/dt>\n<dd><code>y<\/code>\u662f\u6587\u672c\u7ed8\u5236\u7684\u5782\u76f4\u53c2\u8003\u70b9\u5750\u6807\u3002\u968f\u7740<code>CanvasRenderingContext2D.textBaseline<\/code>\u7684\u8bbe\u7f6e\u4e0d\u540c\uff0c<code>y<\/code>\u7684\u5750\u6807\u4f4d\u7f6e\u4e5f\u4e0d\u540c\u3002\u652f\u6301\u591a\u79cd\u57fa\u7ebf\u7c7b\u578b\uff08CSS\u4e2d\u4e5f\u6709\u5bf9\u5e94\u6982\u5ff5\uff09\uff0c<a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/CanvasRenderingContext2D\/textBaseline\" rel=\"nofollow\" target=\"_blank\">MDN<\/a>\u4e0a\u6709\u4e00\u5f20\u56fe\u53ef\u4ee5\u5f88\u597d\u5730\u8868\u793a\u6587\u672c\u57fa\u7ebf\u548c\u6587\u672c\u5782\u76f4\u4f4d\u7f6e\u7684\u5173\u7cfb\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/image.zhangxinxu.com\/image\/blog\/201802\/textBaseline-png8.png\" width=\"275\" height=\"250\" alt=\"canvas\u6587\u672c\u7ed8\u5236\u57fa\u7ebf\u548c\u5bf9\u9f50\u793a\u610f\" class=\"alignnone\" \/><\/dd>\n<dt><strong>maxWidth<\/strong><\/dt>\n<dd><code>maxWidth<\/code>\u8868\u793a\u6587\u672c\u5185\u5bb9\u5360\u636e\u7684\u6700\u5927\u5bbd\u5ea6\u3002\u8fd9\u91cc\u7684<code>maxWidth<\/code>\u6982\u5ff5\u548cCSS\u4e2d\u7684<code>max-width<\/code>\u5dee\u522b\u5f88\u5927\uff0c\u5176\u6700\u7ec8\u7684\u6587\u672c\u8868\u73b0\u662f\uff1a\u5f53\u6587\u672c\u5360\u636e\u5bbd\u5ea6\u8d85\u8fc7<code>maxWidth<\/code>\u7684\u540e\uff0c\u6240\u6709\u7684\u6587\u672c\u81ea\u52a8\u53d8\u7a84\u4ee5\u9002\u5e94\u8fd9\u4e2a\u6700\u5927\u5bbd\u5ea6\u9650\u5236\u3002\u8868\u73b0\u7c7b\u4f3c\u8fd9\u6837\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/image.zhangxinxu.com\/image\/blog\/201802\/2018-02-04_212217.png\" width=\"210\" height=\"40\" alt=\"maxWidth\u9650\u5236\u7684\u6587\u672c\" class=\"alignnone\" \/><\/p>\n<p>\u60a8\u53ef\u4ee5\u72e0\u72e0\u5730\u70b9\u51fb\u8fd9\u91cc\uff1a<a href=\"http:\/\/www.zhangxinxu.com\/study\/201802\/canvas-filltext-maxwidth.html\" rel=\"noopener\" target=\"_blank\">maxWidth\u53c2\u6570\u8ba9\u6587\u5b57\u53d8\u7a84demo<\/a><\/p>\n<p>\u76f8\u5173\u6d4b\u8bd5\u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n<pre>var canvas = document.querySelector('canvas');\nvar context = canvas.getContext('2d');\ncontext.font = '32px sans-serif';\ncontext.fillText('\u6211\u662f\u4e00\u6bb5\u88abmaxWidth\u9650\u5236\u7684\u6587\u672c', 0, 50, 200<\/pre>\n<p>\u5982\u679c\u6ca1\u6709<code>maxWidth<\/code>\u9650\u5236\uff0c\u5219\u6587\u672c\u4f1a\u4e00\u884c\u8d70\u5230\u5e95\uff0c\u76f4\u5230\u8d85\u51fa\u753b\u5e03\u5c3a\u5bf8\uff0c\u6709\u70b9\u7c7b\u4f3cCSS\u4e2d\u8bbe\u7f6e\u5bb9\u5668<code>white-space:nowrap<\/code> + <code>overflow:hidden<\/code>\u7684\u8868\u73b0\u3002\n<\/dd>\n<\/dl>\n<h3>\u4e8c\u3001\u5982\u4f55\u8ba9canvas\u652f\u6301\u81ea\u52a8\u6362\u884c\uff1f<\/h3>\n<p>\u5982\u4f55\u8ba9canvas\u652f\u6301\u81ea\u52a8\u6362\u884c\uff1f<\/p>\n<p>\u9996\u5148\u6709\u4e00\u70b9\u53ef\u4ee5\u80af\u5b9a\uff0c\u5c31\u662f\u5230\u76ee\u524d\u4e3a\u6b62\uff0ccanvas\u4e2d\u5e76\u6ca1\u6709\u4efb\u4f55\u53ef\u4ee5\u8ba9\u6587\u672c\u81ea\u52a8\u6362\u884c\u7684\u73b0\u6210\u7684API\u3002<\/p>\n<p>\u56e0\u6b64\u6ce8\u5b9a\u8fd9\u4e2a\u770b\u4e0a\u53bb\u7b80\u5355\u7684\u4e8b\u60c5\u5b9e\u8df5\u8d77\u6765\u5e76\u6ca1\u6709\u90a3\u4e48\u5bb9\u6613\u3002<\/p>\n<p>\u901a\u5e38\u6bd4\u8f83\u597d\u7684\u5b9e\u73b0\u65b9\u6cd5\u6709\u4e0b\u9762\u4e24\u79cd\uff1a<\/p>\n<h3>1. canvas\u8ba1\u7b97\u4e0e\u9010\u884c\u7ed8\u5236<\/h3>\n<p>\u5b9e\u73b0\u539f\u7406\u7684\u6838\u5fc3\u662f<code>CanvasRenderingContext2D.measureText(text)<\/code>\u8fd9\u4e2aAPI\uff0c\u53ef\u4ee5\u8fd4\u56de\u4e00\u4e2aTextMetrics\u5bf9\u8c61\uff0c\u5176\u4e2d\u5305\u542b\u4e86\u5f53\u524d\u4e0a\u4e0b\u6587\u73af\u5883\u4e0b<code>text<\/code> <code>double<\/code>\u7cbe\u5ea6\u7684\u5360\u636e\u5bbd\u5ea6\uff0c\u4e8e\u662f\u6211\u4eec\u5c31\u53ef\u4ee5\u901a\u8fc7\u6bcf\u4e2a\u5b57\u7b26\u5bbd\u5ea6\u7684\u4e0d\u65ad\u7d2f\u52a0\uff0c\u7cbe\u786e\u8ba1\u7b97\u54ea\u4e2a\u4f4d\u7f6e\u5e94\u8be5\u53ef\u4ee5\u6362\u884c\u3002<\/p>\n<p>\u4e0b\u9762\u5c31\u662f\u6211\u6269\u5c55\u7684\u6587\u672c\u81ea\u52a8\u6362\u884c\u65b9\u6cd5JS\u4ee3\u7801\uff1a<\/p>\n<pre>CanvasRenderingContext2D.prototype.wrapText = function (text, x, y, maxWidth, lineHeight) {\n    if (typeof text != 'string' || typeof x != 'number' || typeof y != 'number') {\n        return;\n    }\n    \n    var context = this;\n    var canvas = context.canvas;\n    \n    if (typeof maxWidth == 'undefined') {\n        maxWidth = (canvas &amp;&amp; canvas.width) || 300;\n    }\n    if (typeof lineHeight == 'undefined') {\n        lineHeight = (canvas &amp;&amp; parseInt(window.getComputedStyle(canvas).lineHeight)) || parseInt(window.getComputedStyle(document.body).lineHeight);\n    }\n    \n    <span style=\"color:green;\">\/\/ \u5b57\u7b26\u5206\u9694\u4e3a\u6570\u7ec4<\/span>\n    var arrText = text.split('');\n    var line = '';\n    \n    for (var n = 0; n &lt; arrText.length; n++) {\n        var testLine = line + arrText[n];\n        var metrics = context.measureText(testLine);\n        var testWidth = metrics.width;\n        if (testWidth &gt; maxWidth &amp;&amp; n &gt; 0) {\n            context.fillText(line, x, y);\n            line = arrText[n];\n            y += lineHeight;\n        } else {\n            line = testLine;\n        }\n    }\n    context.fillText(line, x, y);\n};<\/pre>\n<p>API\u5982\u4e0b\uff1a<\/p>\n<pre>CanvasRenderingContext2D.wrapText(text, x, y, maxWidth, lineHeight)<\/pre>\n<p>\u5176\u4e2d<code>text<\/code>, <code>x<\/code>, <code>y<\/code> 3\u4e2a\u53c2\u6570\u548c<code>fillText()<\/code>\u65b9\u6cd5\u4e2d\u7684\u8fd93\u4e2a\u53c2\u6570\u542b\u4e49\u662f\u4e00\u6837\u7684\uff0c\u4e0d\u8d58\u8ff0\u3002<br \/>\n\u800c<code>maxWidth<\/code>\u8868\u793a\u7684\u542b\u4e49\u53ef\u5c31\u4e0d\u4e00\u6837\u4e86\uff0c\u8868\u793a\u6700\u5927\u9700\u8981\u6362\u884c\u7684\u5bbd\u5ea6\uff0c\u6b64\u53c2\u6570\u53ef\u7f3a\u7701\uff0c\u9ed8\u8ba4\u4f1a\u4f7f\u7528canvas\u753b\u5e03\u7684<code>width<\/code>\u5bbd\u5ea6\u4f5c\u4e3a<code>maxWidth<\/code>\uff1b<code>lineHeight<\/code>\u8868\u793a\u884c\u9ad8\uff0c\u540c\u6837\u53ef\u7f3a\u7701\uff0c\u9ed8\u8ba4\u4f1a\u4f7f\u7528<code>&lt;canvas&gt;<\/code>\u5143\u7d20\u5728DOM\u4e2d\u7ee7\u627f\u7684<code>line-height<\/code>\u4f5c\u4e3a\u884c\u9ad8\u3002<\/p>\n<p>\u4f7f\u7528\u793a\u4f8b\u5982\u4e0b\uff1a<\/p>\n<pre>var canvas = document.querySelector('canvas');\nvar context = canvas.getContext('2d');\ncontext.font = '16px sans-serif';\ncontext.textBaseline = 'top';\n<span style=\"color:#cd0000;\">context.wrapText('\u6211\u662f\u4e00\u6bb5\u4f1a\u6362\u884c\u7684\u6587\u5b57\u5566\u5566\u5566', 0, 0);<\/span><\/pre>\n<p>\u7528\u6cd5\u5f88\u7b80\u5355\uff0c\u4f7f\u7528<code>wrapText<\/code>\u4ee3\u66ff\u539f\u751f\u7684<code>fillText<\/code>\u5373\u53ef\uff01<\/p>\n<p>\u60a8\u53ef\u4ee5\u72e0\u72e0\u7684\u70b9\u51fb\u8fd9\u91cc\uff1a<a href=\"http:\/\/www.zhangxinxu.com\/study\/201802\/canvas-wrapText.html\" rel=\"noopener\" target=\"_blank\">\u81ea\u52a8\u6362\u884c\u6269\u5c55API wrapText\u6f14\u793ademo<\/a><\/p>\n<p>\u4e0b\u9762\u622a\u56fe\u5c31\u662fdemo\u9875\u9762\u7ed8\u5236\u6548\u679c\uff08\u622a\u81eaIE9\u6d4f\u89c8\u5668\uff09\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/image.zhangxinxu.com\/image\/blog\/201802\/2018-02-04_223042.png\" width=\"410\" height=\"355\" alt=\"\u81ea\u52a8\u6362\u884c\u6548\u679c\u793a\u610f\" class=\"alignnone\" \/><\/p>\n<p>\u53ef\u4ee5\u770b\u5230\u4e0a\u65b9\u7ed8\u5236\u7684\u6587\u5b57\u5728\u6838\u5b9e\u4f4d\u7f6e\u81ea\u52a8\u6362\u884c\u4e86\uff0c\u60a8\u53ef\u4ee5\u4fee\u6539<code>&lt;textarea&gt;<\/code>\u4e2d\u7684\u6587\u5b57\u5185\u5bb9\uff0c\u70b9\u51fb\u201c\u7ed8\u5236\u201d\u6309\u94ae\u4f53\u9a8c\u4e0b\u5176\u4ed6\u6587\u672c\u5185\u5bb9\u7684\u81ea\u52a8\u6362\u884c\u7ed8\u5236\u6548\u679c\u3002<\/p>\n<h3>2. \u501f\u52a9SVG &lt;foreignObject&gt;\u76f4\u63a5\u628aCSS\u6548\u679c\u7ed8\u5236\u4e0a\u53bb<\/h3>\n<p>\u5173\u4e8eSVG <code>&lt;foreignObject&gt;<\/code>\u8ba9HTML\u8f6c\u6362\u6210canvas\u56fe\u7247\u7684\u539f\u7406\u548c\u7ec6\u8282\u53ef\u4ee5\u53c2\u89c1\u6211\u4e4b\u524d\u5199\u7684\u201c<a href=\"http:\/\/www.zhangxinxu.com\/wordpress\/2017\/08\/svg-foreignobject\/\">SVG &lt;foreignObject&lt;\u7b80\u4ecb\u4e0e\u622a\u56fe\u7b49\u5e94\u7528<\/a>\u201d\u8fd9\u7bc7\u6587\u7ae0\u3002<\/p>\n<p>\u57fa\u672c\u4e0a\uff0c\u672c\u6587\u540e\u9762\u4f1a\u4ecb\u7ecd\u5230\u7684\u5b57\u7b26\u95f4\u8ddd\uff0c\u6587\u5b57\u7ad6\u6392\u7b49\u5b9e\u73b0\u90fd\u53ef\u4ee5\u4f7f\u7528\u8fd9\u4e2a\u65b9\u6cd5\u5b9e\u73b0\uff0c\u56e0\u6b64\uff0c\u4e3a\u4e86\u907f\u514d\u4e0d\u5fc5\u8981\u7684\u5570\u55e6\uff0c\u4ec5\u672c\u6548\u679c\u4f1a\u5177\u4f53\u6f14\u793a\u4ee3\u7801\u7ec6\u8282\uff0c\u540e\u9762\u6548\u679c\u5927\u5bb6\u81ea\u884c\u62f7\u8d1d\u6539\u6539\u5c31\u597d\u4e86\u3002<\/p>\n<p>\u6211\u4eec\u5148\u770b\u5b9e\u4f8b\uff0c\u60a8\u53ef\u4ee5\u72e0\u72e0\u5730\u70b9\u51fb\u8fd9\u91cc\uff1a<a href=\"http:\/\/www.zhangxinxu.com\/study\/201802\/canvas-wraptext-foreignobject.html\" rel=\"noopener\" target=\"_blank\">canvas\u501f\u52a9SVG foreignObject\u5b9e\u73b0\u6587\u672c\u81ea\u52a8\u6362\u884cdemo<\/a><\/p>\n<p>\u7ed3\u679cChrome\u6d4f\u89c8\u5668\u4e0b\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/image.zhangxinxu.com\/image\/blog\/201802\/2018-02-04_230326.png\" width=\"343\" height=\"339\" alt=\"Chrome\u4e0b\u7684canvas\u81ea\u52a8\u6362\u884c\" class=\"alignnone\" \/><\/p>\n<p>JS\u5b9e\u73b0\u5982\u4e0b\uff1a<\/p>\n<pre>var canvas = document.querySelector('canvas');\nvar context = canvas.getContext('2d');\ncontext.font = '16px sans-serif';\nvar width = canvas.width;\nvar height = canvas.height;\n\nvar tempImg = new Image();\ntempImg.width = width;\ntempImg.height = height;\ntempImg.onload = function () {\n    <span style=\"color:green;\">\/\/ \u628aimg\u7ed8\u5236\u5728canvas\u753b\u5e03\u4e0a<\/span>\n    context.drawImage(this, 0, 0, width, height);\n};\ntempImg.src = 'data:image\/svg+xml;charset=utf-8,&lt;svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\"&gt;&lt;foreignObject width=\"'+ width +'\" height=\"'+ height +'\"&gt;&lt;body xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\" style=\"margin:0;font:'+ context.font +';\"&gt;\u6211\u662f\u4e00\u6bb5\u9700\u8981\u6362\u884c\u7684\u6587\u5b57\u5566\u5566\u5566&lt;\/body&gt;&lt;\/foreignObject&gt;&lt;\/svg&gt;';<\/pre>\n<p>\u6b64\u65b9\u6cd5\u4f18\u70b9\u5728\u4e8e\u8db3\u591f\u7b80\u5355\uff0c\u53ea\u8981\u4e00\u6bb5\u5e26<code>style<\/code>\u6837\u5f0f\u7684HTML\u4ee3\u7801\u5373\u53ef\uff01<\/p>\n<p>\u552f\u4e00\u4e0d\u8db3\u5728\u4e8e\u517c\u5bb9\u6027\uff0cIE\u6d4f\u89c8\u5668\u4e0d\u652f\u6301<code>&lt;foreignObject&gt;<\/code>\uff0c\u6700\u65b0\u7684Firefox\u6d4f\u89c8\u5668\u867d\u7136\u652f\u6301<code>&lt;foreignObject&gt;<\/code>\uff0c\u4f46\u662f\u53ea\u80fd\u4ee5<code>&lt;img&lt;<\/code>\u5f62\u5f0f\u5448\u73b0\uff0c\u65e0\u6cd5\u7ed8\u5236\u5230canvas\u753b\u5e03\u4e0a\uff08\u82e5\u8c01\u77e5\u9053\u539f\u56e0\u6b22\u8fce\u4e0d\u541d\u8d50\u6559\uff09\u3002<\/p>\n<p>\u4e0d\u8fc7\u597d\u7684\u662f\u79fb\u52a8\u7aefSafari\u6d4f\u89c8\u5668\u4ee5\u53ca\u5fae\u4fe1\u6d4f\u89c8\u5668\u90fd\u662f\u652f\u6301\u7684\uff0c\u56e0\u6b64\uff0c\u6b64\u65b9\u6cd5\u7406\u8bba\u4e0a\u662f\u53ef\u4ee5\u5728\u79fb\u52a8\u7aef\u4f7f\u7528\u7684\u3002\u4f8b\u5982\u6211\u624b\u673aSafari\u7684\u6548\u679c\u622a\u56fe\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/image.zhangxinxu.com\/image\/blog\/201802\/safari_cut_3701.png\" width=\"375\" height=\"377\" alt=\"Safari\u6d4f\u89c8\u5668\u4e0b\u7684\u81ea\u52a8\u6362\u884c\u5b9e\u73b0\" class=\"alignnone\" \/><\/p>\n<h3>\u4e8c\u3001\u5982\u4f55\u8ba9canvas\u652f\u6301\u5b57\u7b26\u95f4\u8ddd\uff1f<\/h3>\n<h4>1. \u5982\u679c\u53ea\u9700\u8981\u517c\u5bb9Chrome\uff0c\u76f4\u63a5letter-spacing\u63a7\u5236<\/h4>\n<p>\u5bf9\u4e8eChrome\u6d4f\u89c8\u5668\uff0c\u65e0\u8bba\u662f\u5b57\u7b26\u95f4\u8ddd\u8fd8\u662f\u5355\u8bcd\u95f4\u8ddd\uff0c\u90fd\u53ef\u4ee5\u81ea\u52a8\u7ee7\u627f\u4e8e<code>&lt;canvas&gt;<\/code>\u5143\u7d20\uff0c\u8fd9\u4e2a\u7279\u6027\u8ba9\u4eba\u975e\u5e38\u611f\u52a8\u3002<\/p>\n<p>\u4e5f\u5c31\u662f\uff1a<\/p>\n<pre>canvas { letter-pacing: 5px; }<\/pre>\n<p>\u7ed8\u5236\u7684\u6587\u5b57\u5b57\u7b26\u95f4\u8ddd\u81ea\u52a8\u5c31\u662f<code>5px<\/code>\u3002<\/p>\n<p>\u5982\u6b64\u6b23\u559c\u7684\u7279\u6027\u6709\u5fc5\u8981\u4eb2\u773c\u89c1\u8bc1\u4e00\u4e0b\uff0c\u60a8\u53ef\u4ee5\u72e0\u72e0\u5730\u70b9\u51fb\u8fd9\u91cc\uff1a<a href=\"http:\/\/www.zhangxinxu.com\/study\/201802\/canvas-letter-spacing-by-css.html\" rel=\"noopener\" target=\"_blank\">canavs\u6587\u672c\u95f4\u8ddd\u4f7f\u7528CSS letter-spacing\u5b9e\u73b0demo<\/a><\/p>\n<p>\u6548\u679c\u5982\u4e0bGIF\u793a\u610f\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/image.zhangxinxu.com\/image\/blog\/201802\/css-letter-spacing-canvas.gif\" width=\"362\" height=\"143\" alt=\"\u76f4\u63a5CSS letter-spacing\u63a7\u5236canvas\u5b57\u7b26\u95f4\u8ddd\" class=\"alignnone\" \/><\/p>\n<p>\u5b8c\u6574\u6d4b\u8bd5JS\u4ee3\u7801\u5982\u4e0b\uff1a<\/p>\n<pre>var canvas = document.querySelector('canvas');\nvar context = canvas.getContext('2d');\nvar range = document.querySelector('input[type=range]');\n<span style=\"color:green;\">\/\/ \u7ed8\u5236\u65b9\u6cd5<\/span>\nvar draw = function () {\n    <span style=\"color:green;\">\/\/ \u6e05\u9664\u4e4b\u524d\u7684\u7ed8\u5236<\/span>\n    context.clearRect(0, 0, canvas.width, canvas.height);\n    <span style=\"color:green;\">\/\/ \u5b57\u7b26\u95f4\u8ddd\u8bbe\u7f6e<\/span>\n    canvas.style.letterSpacing = range.value + 'px';\n    <span style=\"color:green;\">\/\/ \u5e76\u7ed8\u5236\u6587\u672c\uff0cfont\u5c5e\u6027\u503c\u8bbe\u7f6e\u4e00\u5b9a\u8981\u5728\u8fd9\u91cc<\/span>\n    context.font = '32px sans-serif';\n    context.fillText('\u6211\u662f\u4e00\u6bb5\u6587\u672c', 0, 50);\n};\n<span style=\"color:green;\">\/\/ \u6539\u53d8\u5b57\u7b26\u95f4\u8ddd\u540e\u91cd\u7ed8<\/span>\nrange.addEventListener('change', draw);\n<span style=\"color:green;\">\/\/ \u4e00\u8fdb\u6765\u6839\u636e\u9ed8\u8ba4\u503c\u7ed8\u5236<\/span>\ndraw();<\/pre>\n<p>\u6839\u636e\u6211\u7684\u89c2\u5bdf\uff0c\u8c8c\u4f3cChrome\u6d4f\u89c8\u5668\u5728\u8bbe\u7f6e<code>font<\/code>\u5c5e\u6027\u503c\u7684\u65f6\u5019\uff0c\u628a<code>letter-spacing<\/code>\u7b49\u4fe1\u606f\u4e00\u8d77\u7b97\u4f5c\u4e0a\u4e0b\u6587\u4e2d\u4e86\u3002\u6240\u4ee5\uff0c\u867d\u7136\u770b\u4e0a\u53bb<code>context.font = '32px sans-serif'<\/code>\u4e00\u76f4\u90fd\u6ca1\u53d8\uff0c\u4f46\u5374\u4e0d\u80fd\u653e\u5728<code>draw()<\/code>\u65b9\u6cd5\u4e4b\u5916\uff0c\u5426\u5219\uff0c\u8fd8\u662f\u6309\u7167\u8001\u7684<code>letter-spacing<\/code>\u6e32\u67d3\u800c\u770b\u4e0d\u5230\u5b57\u7b26\u95f4\u8ddd\u53d8\u5316\u3002<\/p>\n<p>\u6b64\u65b9\u6cd5\u6700\u7b80\u5355\u6700\u5bb9\u6613\u7406\u89e3\uff0c\u53ea\u53ef\u60dc\uff0c\u6839\u636e\u6211\u7684\u6d4b\u8bd5\uff0c\u76ee\u524d\u4ec5Chrome\u6d4f\u89c8\u5668\u652f\u6301\u3002Firefox\u4ee5\u53caSafari\u5168\u90fd\u4e0d\u884c\u3002<\/p>\n<h4>2. canvas\u8ba1\u7b97\u4e0e\u9010\u5b57\u7ed8\u5236<\/h4>\n<p>\u539f\u7406\u4e3a\uff0c\u6bcf\u4e00\u4e2a\u5b57\u7b26\u5355\u72ec\u4f5c\u4e3a\u4e00\u4e2a\u7ed8\u5236\u5355\u5143\uff0c\u7136\u540e\u6839\u636e\u5b57\u7b26\u5bbd\u5ea6+letterSpacing\u95f4\u8ddd\u52a8\u6001\u7ed8\u5236\uff0c\u540c\u6837\uff0c\u79bb\u4e0d\u5f00\u4f7f\u7528<code>CanvasRenderingContext2D.measureText(text)<\/code>\u8fd9\u4e2aAPI\u3002<\/p>\n<p>\u4ee5\u4e0b\u5c31\u662f\u81ea\u5df1\u76f4\u63a5\u5728\u539f\u578b\u4e0a\u6269\u5c55\u7684\u5b57\u7b26\u95f4\u8ddd\u7ed8\u5236\u65b9\u6cd5letterSpacingText\uff0c\u5927\u5bb6\u53ef\u4ee5\u76f4\u63a5\u62f7\u8d1d\u8fc7\u53bb\u4f7f\u7528\uff0cMIT\u534f\u8bae\uff0c\u4fdd\u7559\u539f\u51fa\u5904\u5373\u53ef\u3002<\/p>\n<pre><span style=\"color:green;\">\/**\n* @author zhangxinxu(.com)\n* @licence MIT\n* @description http:\/\/www.zhangxinxu.com\/wordpress\/?p=7362\n*\/<\/span>\nCanvasRenderingContext2D.prototype.letterSpacingText = function (text, x, y, letterSpacing) {\n    var context = this;\n    var canvas = context.canvas;\n    \n    if (!letterSpacing &amp;&amp; canvas) {\n        letterSpacing = parseFloat(window.getComputedStyle(canvas).letterSpacing);\n    }\n    if (!letterSpacing) {\n        return this.fillText(text, x, y);\n    }\n    \n    var arrText = text.split('');\n    var align = context.textAlign || 'left';\n    \n    <span style=\"color:green;\">\/\/ \u8fd9\u91cc\u4ec5\u8003\u8651\u6c34\u5e73\u6392\u5217<\/span>\n    var originWidth = context.measureText(text).width;\n    <span style=\"color:green;\">\/\/ \u5e94\u7528letterSpacing\u5360\u636e\u5bbd\u5ea6<\/span>\n    var actualWidth = originWidth + letterSpacing * (arrText.length - 1);\n    <span style=\"color:green;\">\/\/ \u6839\u636e\u6c34\u5e73\u5bf9\u9f50\u65b9\u5f0f\u786e\u5b9a\u7b2c\u4e00\u4e2a\u5b57\u7b26\u7684\u5750\u6807<\/span>\n    if (align == 'center') {\n        x = x - actualWidth \/ 2;\n    } else if (align == 'right') {\n        x = x - actualWidth;\n    }\n    \n    <span style=\"color:green;\">\/\/ \u4e34\u65f6\u4fee\u6539\u4e3a\u6587\u672c\u5de6\u5bf9\u9f50<\/span>\n    context.textAlign = 'left';\n    <span style=\"color:green;\">\/\/ \u5f00\u59cb\u9010\u5b57\u7ed8\u5236<\/span>\n    arrText.forEach(function (letter) {\n        var letterWidth = context.measureText(letter).width;\n        context.fillText(letter, x, y);\n        <span style=\"color:green;\">\/\/ \u786e\u5b9a\u4e0b\u4e00\u4e2a\u5b57\u7b26\u7684\u6a2a\u5750\u6807<\/span>\n        x = x + letterWidth + letterSpacing;\n    });\n    <span style=\"color:green;\">\/\/ \u5bf9\u9f50\u65b9\u5f0f\u8fd8\u539f<\/span>\n    context.textAlign = align;\n};<\/pre>\n<p>API\u8be6\u7ec6\uff1a<\/p>\n<pre>CanvasRenderingContext2D.letterSpacingText(text, x, y, letterSpacing);<\/pre>\n<p>\u5176\u4e2d<code>text<\/code>, <code>x<\/code>, <code>y<\/code> 3\u4e2a\u53c2\u6570\u548c<code>fillText()<\/code>\u65b9\u6cd5\u4e2d\u7684\u8fd93\u4e2a\u53c2\u6570\u542b\u4e49\u662f\u4e00\u6837\u7684\uff0c\u4e0d\u8d58\u8ff0\u3002<code>letterSpacing<\/code>\u8868\u793a\u5b57\u7b26\u95f4\u8ddd\u5927\u5c0f\uff0c\u6570\u503c\u3002\u53ef\u7f3a\u7701\uff0c\u9ed8\u8ba4\u4f1a\u62ff<code>&lt;canvas&gt;<\/code>\u5143\u7d20\u5728DOM\u73af\u5883\u4e0b\u7684<code>letter-spacing<\/code>\u5927\u5c0f\u4f5c\u4e3a\u8ba1\u7b97\u503c\u3002<\/p>\n<p>\u4f7f\u7528\u793a\u610f\uff1a<\/p>\n<pre>var canvas = document.querySelector('canvas');\t\nvar context = canvas.getContext('2d');\ncontext.font = '32px sans-serif';\ncontext.textAlign = 'center';\n<span style=\"color:green;\">\/\/ \u5b57\u7b26\u95f4\u96995px<\/span>\ncontext.letterSpacingText('\u6211\u662f\u4e00\u6bb5\u6587\u672c', canvas.width \/ 2, 50, 5);<\/pre>\n<p>\u60a8\u53ef\u4ee5\u72e0\u72e0\u5730\u70b9\u51fb\u8fd9\u91cc\uff1a<a href=\"http:\/\/www.zhangxinxu.com\/study\/201802\/canvas-letter-spacing.html\" rel=\"noopener\" target=\"_blank\">canavs\u5b57\u7b26\u95f4\u8dddJS\u9010\u5b57\u8ba1\u7b97demo<\/a><\/p>\n<p>\u6548\u679c\u5982\u4e0bGIF\u793a\u610f\uff08\u5c45\u4e2d\u5bf9\u9f50\uff0c\u622a\u81eaIE Edge\uff09\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/image.zhangxinxu.com\/image\/blog\/201802\/canvas-letter-spacing-js.gif\" width=\"332\" height=\"150\" alt=\"\u5c45\u4e2d\u5bf9\u9f50\u4e0b\u7684\u5b57\u7b26\u95f4\u9699\u793a\u610f\" class=\"alignnone\" \/><\/p>\n<p>\u6b64\u65b9\u6cd5\u517c\u5bb9\u6027\u975e\u5e38\u597d\uff0cIE9+\u6d4f\u89c8\u5668\u90fd\u652f\u6301\uff0cPC\u548cMobile\u901a\u5403\u3002<\/p>\n<h4>3. \u501f\u52a9SVG &lt;foreignObject&gt;\u76f4\u63a5\u628aCSS\u6548\u679c\u7ed8\u5236\u4e0a\u53bb<\/h4>\n<p>\u548c\u81ea\u52a8\u6362\u884c\u5b9e\u73b0\u7c7b\u4f3c\uff0c\u8be6\u7ec6\u7565\u3002<\/p>\n<h3>\u56db\u3001\u5982\u4f55\u8ba9canvas\u652f\u6301\u7ad6\u76f4\u6392\u5217\uff1f<\/h3>\n<p>\u6587\u5b57\u7ad6\u76f4\u6392\u5217\uff0c\u5bf9\u4e8e\u73a9\u82f1\u6587\u7684\u8001\u5916\uff0c\u53ef\u4ee5\u4f7f\u7528<code>context.rotate()<\/code>\u65cb\u8f6c<code>90deg<\/code>\u5b9e\u73b0\uff0c\u4f46\u662f\u5bf9\u4e8e\u4e2d\u6587\u7b49\u4e2d\u4e9a\u6587\u5b57\uff0c\u5374\u662f\u5b8c\u5168\u4e0d\u9002\u5408\u7684\u3002\u56e0\u4e3a\u4e24\u79cd\u8bed\u8a00\u7684\u7ad6\u76f4\u6392\u7248\u89c4\u5219\u662f\u4e0d\u4e00\u6837\u7684\u3002<\/p>\n<p>\u4e2d\u6587\u7b49\u4e1c\u4e9a\u6587\u5b57\u4e0a\uff0c\u4f8b\u5982\u4e00\u4e9b\u53e4\u8bd7\u8bcd\u6587\u5b57\u8fd8\u662f\u6b63\u7684\uff0c\u4ec5\u4ec5\u662f\u9605\u8bfb\u65b9\u5411\u662f\u4ece\u4e0a\u5f80\u4e0b\uff0c\u4f46\u662f\uff0c\u82f1\u6587\uff08\u4ee5\u53ca\u963f\u62c9\u4f2f\u6570\u5b57\uff09\u7531\u4e8e\u672c\u8eab\u7684\u5b57\u7b26\u7279\u6027\uff0c\u76f4\u63a5\u5c31\u662f\u65cb\u8f6c\u6392\u5217\u7684\u3002<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/image.zhangxinxu.com\/image\/blog\/201802\/2018-02-05_011925.png\" width=\"32\" height=\"140\" class=\"alignnone\" \/><\/p>\n<p>\u6240\u4ee5\u5355\u7eaf\u65cb\u8f6c\u7b56\u7565\u5bf9\u4e8e\u5927\u4e2d\u56fd\u5e76\u4e0d\u5b9e\u7528\u3002<\/p>\n<p>\u5728CSS\u4e2d\uff0c\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528<code>writing-mode<\/code>\u6539\u53d8\u6587\u6863\u6d41\u7684\u65b9\u5411\uff0c\u4ece\u800c\u5b9e\u73b0\u6587\u5b57\u7ad6\u6392\uff0c\u76f8\u5173\u6587\u7ae0\u53ef\u4ee5\u53c2\u89c1\u6211\u4e4b\u524d\u7684\u6587\u7ae0\uff1a\u201c<a href=\"http:\/\/www.zhangxinxu.com\/wordpress\/2016\/04\/css-writing-mode\/\">\u6539\u53d8CSS\u4e16\u754c\u7eb5\u6a2a\u89c4\u5219\u7684writing-mode\u5c5e\u6027<\/a>\u201d\uff0c\u6216\u8005\u8d2d\u4e70\u6211\u7684<a href=\"http:\/\/www.cssworld.cn\/\" rel=\"noopener\" target=\"_blank\">\u300aCSS\u4e16\u754c\u300b<\/a>\uff0c\u5176\u4e2d\u6709\u8be6\u7ec6\u4ecb\u7ecd\u3002<\/p>\n<p>\u90a3\u5728canvas\u4e2d\u53c8\u8be5\u5982\u4f55\u5b9e\u73b0\u5462\uff1f<\/p>\n<h4>1. JS\u6df7\u5408\u8ba1\u7b97\u9010\u5b57\u6392\u5217<\/h4>\n<p>\u6df7\u5408\u8ba1\u7b97\u89c4\u5219\u5982\u4e0b\uff1a\u5168\u89d2\u5b57\u7b26\u7ad6\u6392\uff0c\u82f1\u6587\u6570\u5b57\u7b49\u534a\u89d2\u5b57\u7b26\u65cb\u8f6c\u6392\u5217\u3002<\/p>\n<p>\u4e0b\u9762\u662f\u6211\u6269\u5c55\u7684\u7ad6\u6392\u65b9\u6cd5\uff0c\u540c\u6837MIT\u534f\u8bae\uff0c\u53ef\u968f\u610f\u4f7f\u7528\uff0c\u4fdd\u7559\u4e0a\u9762\u4e00\u6bb5\u4f5c\u8005\u548c\u51fa\u5904\u8bf4\u660e\u5373\u53ef\u3002<\/p>\n<pre><span style=\"color:green;\">\/**\n* @author zhangxinxu(.com)\n* @licence MIT\n* @description http:\/\/www.zhangxinxu.com\/wordpress\/?p=7362\n*\/<\/span>\nCanvasRenderingContext2D.prototype.fillTextVertical = function (text, x, y) {\n    var context = this;\n    var canvas = context.canvas;\n    \n    var arrText = text.split('');\n    var arrWidth = arrText.map(function (letter) {\n        return context.measureText(letter).width;\n    });\n    \n    var align = context.textAlign;\n    var baseline = context.textBaseline;\n    \n    if (align == 'left') {\n        x = x + Math.max.apply(null, arrWidth) \/ 2;\n    } else if (align == 'right') {\n        x = x - Math.max.apply(null, arrWidth) \/ 2;\n    }\n    if (baseline == 'bottom' || baseline == 'alphabetic' || baseline == 'ideographic') {\n        y = y - arrWidth[0] \/ 2;\n    } else if (baseline == 'top' || baseline == 'hanging') {\n        y = y + arrWidth[0] \/ 2;\n    }\n    \n    context.textAlign = 'center';\n    context.textBaseline = 'middle';\n    \n    <span style=\"color:green;\">\/\/ \u5f00\u59cb\u9010\u5b57\u7ed8\u5236<\/span>\n    arrText.forEach(function (letter, index) {\n        <span style=\"color:green;\">\/\/ \u786e\u5b9a\u4e0b\u4e00\u4e2a\u5b57\u7b26\u7684\u7eb5\u5750\u6807\u4f4d\u7f6e<\/span>\n        var letterWidth = arrWidth[index];\n        <span style=\"color:green;\">\/\/ \u662f\u5426\u9700\u8981\u65cb\u8f6c\u5224\u65ad<\/span>\n        var code = letter.charCodeAt(0);\n        if (code &lt;= 256) {\n            context.translate(x, y);\n            <span style=\"color:green;\">\/\/ \u82f1\u6587\u5b57\u7b26\uff0c\u65cb\u8f6c90\u00b0<\/span>\n            context.rotate(90 * Math.PI \/ 180);\n            context.translate(-x, -y);\n        } else if (index &gt; 0 &amp;&amp; text.charCodeAt(index - 1) &lt; 256) {\n            <span style=\"color:green;\">\/\/ y\u4fee\u6b63<\/span>\n            y = y + arrWidth[index - 1] \/ 2;\n        }\n        context.fillText(letter, x, y);\n        <span style=\"color:green;\">\/\/ \u65cb\u8f6c\u5750\u6807\u7cfb\u8fd8\u539f\u6210\u521d\u59cb\u6001<\/span>\n        context.setTransform(1, 0, 0, 1, 0, 0);\n        <span style=\"color:green;\">\/\/ \u786e\u5b9a\u4e0b\u4e00\u4e2a\u5b57\u7b26\u7684\u7eb5\u5750\u6807\u4f4d\u7f6e<\/span>\n        var letterWidth = arrWidth[index];\n        y = y + letterWidth;\n    });\n    <span style=\"color:green;\">\/\/ \u6c34\u5e73\u5782\u76f4\u5bf9\u9f50\u65b9\u5f0f\u8fd8\u539f<\/span>\n    context.textAlign = align;\n    context.textBaseline = baseline;\n};<\/pre>\n<p>API\u540d\u79f0\u662f<code>fillTextVertical<\/code>\uff0c\u8bed\u6cd5\u5982\u4e0b\uff1a<\/p>\n<pre>CanvasRenderingContext2D.fillTextVertical(text, x, y)<\/pre>\n<p>\u5176\u4e2d<code>text<\/code>, <code>x<\/code>, <code>y<\/code> 3\u4e2a\u53c2\u6570\u548c<code>fillText()<\/code>\u65b9\u6cd5\u4e2d\u7684\u8fd93\u4e2a\u53c2\u6570\u542b\u4e49\u662f\u4e00\u6837\u7684\uff0c\u4e0d\u8d58\u8ff0\u3002<\/p>\n<p>\u5b9e\u73b0\u7684\u6548\u679c\u662f\uff1a\u82f1\u6587\u6570\u5b57\u7b49\u65cb\u8f6c\uff0c\u4e2d\u6587\u5782\u76f4\u6392\u5217\u3002\u652f\u6301<code>textAlign<\/code>\u548c<code>textBaseline<\/code>\u7b49\u57fa\u672c\u8bbe\u7f6e\u3002<\/p>\n<p>\u60a8\u53ef\u4ee5\u72e0\u72e0\u5730\u70b9\u51fb\u8fd9\u91cc\uff1a<a href=\"http:\/\/www.zhangxinxu.com\/study\/201802\/canvas-filltext-vertical.html\" rel=\"noopener\" target=\"_blank\">canavs\u6587\u672c\u7ad6\u6392JS\u9010\u5b57\u8ba1\u7b97\u5b9e\u73b0demo<\/a><\/p>\n<p>\u4f7f\u7528JS\u5982\u4e0b\uff1a<\/p>\n<pre>var canvas = document.querySelector('canvas');\t\nvar context = canvas.getContext('2d');\ncontext.font = '24px STKaiti, sans-serif';\ncontext.textAlign = 'center';\ncontext.textBaseline = 'top';\ncontext.fillTextVertical('anglebaby\u548c\u9ec4\u6653\u660e', canvas.width \/ 2, 0);<\/pre>\n<p>\u7ed3\u679c\u5982\u4e0b\u56fe\u6240\u793a\uff1a<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/image.zhangxinxu.com\/image\/blog\/201802\/2018-02-05_024704.png\" width=\"109\" height=\"212\" alt=\"\u7ad6\u76f4\u6392\u5217\u6548\u679c\u622a\u56fe\" class=\"alignnone\" \/><\/p>\n<h4>2. \u501f\u52a9SVG &lt;foreignObject&gt;\u76f4\u63a5\u628aCSS\u6548\u679c\u7ed8\u5236\u4e0a\u53bb<\/h4>\n<p>\u548c\u81ea\u52a8\u6362\u884c\u5b9e\u73b0\u7c7b\u4f3c\uff0c\u8be6\u7ec6\u7565\u3002<\/p>\n<h3>\u4e94\u3001\u7ed3\u675f\u8bed<\/h3>\n<p>\u5f53\u5e74CSS\u4e4b\u6240\u4ee5\u4e00\u7edf\u5929\u4e0b\u5c31\u662f\u5728\u6587\u672c\u5c55\u73b0\u6587\u5b57\u6392\u7248\u8fd9\u4e00\u5757\u975e\u5e38\u65b9\u4fbf\u3002<\/p>\n<p>\u770b\u770bSVG\u7684\u6587\u672c\u5c55\u73b0\uff0c\u5728\u770b\u770bcanvas\u7684\u6587\u672c\u5448\u73b0\uff0c\u96be\u7528\u7684\u5f88\u3002\u5168\u9760\u53cb\u519b\u886c\u6258\u554a\uff01<\/p>\n<p>\u95ee\u9898\u6765\u4e86\uff0cCSS\u6587\u672c\u5448\u73b0\u8fd9\u91cc\u5389\u5bb3\uff0c\u90a3\u8fd8\u9700\u8981canvas\u5e72\u4ec0\u4e48\uff1f<\/p>\n<p>\u56e0\u4e3acanvas\u53ef\u4ee5\u65b9\u4fbf\u628a\u6587\u5b57\u8f6c\u6362\u6210\u56fe\u7247\uff0c\u4f8b\u5982\u4e00\u4e9b\u5e7f\u544a\u5de5\u5177\u7b49\u7b49\uff0c\u9700\u8981\u524d\u7aef\u5408\u6210\u7684\uff0c\u5c31\u9700\u8981canvas\u5927\u653e\u5f02\u5f69\u4e86\u3002<\/p>\n<p>\u672c\u6587\u6269\u5c55\u7684\u8fd9\u4e9b\u65b9\u6cd5\u5e76\u672a\u5b9e\u9645\u9879\u76ee\u5927\u89c4\u6a21\u9a8c\u8bc1\uff0c\u6709\u758f\u6f0f\u4e4b\u5904\u5728\u6240\u96be\u514d\uff0c\u6b22\u8fce\u6307\u6b63\uff01<\/p>\n<p>\u611f\u8c22\u9605\u8bfb\uff01<\/p>\n<p><img decoding=\"async\" src=\"http:\/\/image.zhangxinxu.com\/image\/blog\/201611\/14.png\" align=\"absmiddle\"><\/p>\n<p>\u672c\u6587\u4e3a\u539f\u521b\u6587\u7ae0\uff0c\u4f1a\u7ecf\u5e38\u66f4\u65b0\u77e5\u8bc6\u70b9\u4ee5\u53ca\u4fee\u6b63\u4e00\u4e9b\u9519\u8bef\uff0c\u56e0\u6b64\u8f6c\u8f7d\u8bf7\u4fdd\u7559\u539f\u51fa\u5904\uff0c\u65b9\u4fbf\u6eaf\u6e90\uff0c\u907f\u514d\u9648\u65e7\u9519\u8bef\u77e5\u8bc6\u7684\u8bef\u5bfc\uff0c\u540c\u65f6\u6709\u66f4\u597d\u7684\u9605\u8bfb\u4f53\u9a8c\u3002<br \/>\n\u672c\u6587\u5730\u5740\uff1a<a href=\"http:\/\/www.zhangxinxu.com\/wordpress\/?p=7362\">http:\/\/www.zhangxinxu.com\/wordpress\/?p=7362<\/a><\/p>\n<p>\uff08\u672c\u7bc7\u5b8c\uff09<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u548cCSS\u76f8\u6bd4\uff0cSVG\u4ee5\u53cacanvas\u5bf9\u6587\u5b57\u6392\u7248\u7684\u652f\u6301\u5f88\u5f31\u3002<\/p>\n<p>\u5728CSS\u4e2d\u5929\u7136\u652f\u6301\u7684\u6587\u672c\u81ea\u52a8\u6362\u884c\uff0c\u5176\u4ed6letter-sapcing\u5b57\u95f4\u8ddd\uff0cwriting-mode\u7ad6\u6392\u7b49\u90fd\u662f\u4e00\u4e2aCSS\u5c5e\u6027\u5c31\u53ef\u4ee5\u5b9e\u73b0\u3002\u4f46\u662f\u5728canvas\u4e2d\uff0c\u5168\u90e8\u90fd\u4e0d\u652f\u6301\u3002<\/p>\n<p>\u4f46\u662fcanvas\u53ef\u4ee5\u65b9\u4fbf\u628a\u6587\u5b57\u8f6c\u6362\u6210\u56fe\u7247\uff0c\u6709\u4e9b\u573a\u5408\uff0c\u4f8b\u5982\u5e7f\u544a\u751f\u6210\u5de5\u5177\u5c31\u9700\u8981canvas\u524d\u7aef\u56fe\u7247\u751f\u6210\uff0c\u6b64\u65f6\u6211\u4eec\u8be5\u5982\u4f55\u5904\u7406\u8fd9\u4e9b\u6587\u5b57\u6392\u7248\u5462\uff1f<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[896],"tags":[53,1191,977,521,238,1212,302,1213,1214,1046],"_links":{"self":[{"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/posts\/7362"}],"collection":[{"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/comments?post=7362"}],"version-history":[{"count":0,"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/posts\/7362\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/media?parent=7362"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/categories?post=7362"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.zhangxinxu.com\/wordpress\/wp-json\/wp\/v2\/tags?post=7362"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}