Hel*_*eda 5 javascript canvas html5-canvas
我注意到一个有趣的效果混合进来setLineDash,并strokeText在画布
ctx = document.querySelector("canvas").getContext("2d")
ctx.font = "110px Arial";
i = speed = 3
function loop() {
ctx.clearRect(0, 0, 600, 160)
ctx.beginPath()
ctx.setLineDash([i, 600]);
ctx.strokeText("WORLD ?", 10, 100);
i += speed
if (i > 600 || i < 2)
speed *= -1
}
setInterval(loop, 50)Run Code Online (Sandbox Code Playgroud)
<canvas id="c" width=600 height=160></canvas>Run Code Online (Sandbox Code Playgroud)
如您所见W,绘制所需的时间比O此代码段中的更长。
是否有任何属性可以检索字母最长行的像素数(长度)?
您可以在屏幕外绘制每个字符并“计算”像素的出现次数(非零值):
\n\nfunction getAmount (char, { width, height, font, color }) {\n // create temporary offscreen canvas\n const canvas = document.createElement(\'canvas\')\n canvas.width = width\n canvas.height = height\n\n // draw the character\n const ctx = canvas.getContext("2d")\n ctx.font = font\n ctx.strokeText(char, 0, 90)\n\n // get the pixels data\n const imageData = ctx.getImageData(0, 0, width, height)\n let sum = 0\n imageData.data.forEach(point => {\n if (point > 0) sum++\n })\n return sum\n}\n\nconst width = 90\nconst height = 90\nconst font = "90px Arial"\n\ngetAmount(\'W\', { font, width, height }) // 940\ngetAmount(\'O\', { font, width, height }) // 660\ngetAmount(\'R\', { font, width, height }) // 673\ngetAmount(\'L\', { font, width, height }) // 296\ngetAmount(\'D\', { font, width, height }) // 613\nRun Code Online (Sandbox Code Playgroud)\n\n您可以粗略地使用这些值来加权速度并单独绘制每个角色,但请记住,您必须另外管理放置等。此外,这仅检测任何非零值。如果您对笔划使用渐变,则必须检测渐变范围内的图像数据。
\n\n由于找不到真相来源,我们可以使用另一个技巧:
\n\ni求创建与全虚线字符具有相同像素数量的屏幕外图像的数量。
/**\n * draws a stroked text by given params to a context\n **/\n\nfunction draw (char, ctx, minValue, maxValue) {\n ctx.clearRect(0, 0, 600, 160)\n ctx.beginPath()\n if (minValue && maxValue) {\n ctx.setLineDash([minValue, maxValue])\n }\n ctx.strokeText(char, 10, 100);\n}\n\n/**\n * Returns the amount of pixels for a given character\n */\nconst offscreenCanvas = document.createElement(\'canvas\')\nfunction getAmount (char, { value, max, width, height, font }) {\n // draw offscreen, then detect border pixels\n offscreenCanvas.width = width\n offscreenCanvas.height = height\n\n // draw the character\n const ctx = offscreenCanvas.getContext("2d")\n ctx.font = font\n draw(char, ctx, value, max)\n\n // get the pixels data\n const imageData = ctx.getImageData(0, 0, width, height)\n let sum = 0\n imageData.data.forEach(point => {\n if (point > 0) sum++\n })\n\n return sum\n}\n\n/**\n * Returns the number of iterations required to complete a character\n **/\n\nfunction getIterations (char, { font, width, height }) {\n // get amount when word is fully drawn\n const fullAmount = getAmount(char, { value: undefined, max: undefined, width, height, font })\n\n let iterations = 1\n let amount = 0\n do {\n amount = getAmount(char, { value: iterations, max: 1000, width, height, font })\n iterations++\n } while ((amount - fullAmount < -3) && iterations < 2000);\n\n return iterations\n}\nRun Code Online (Sandbox Code Playgroud)\n\n从这里我们可以确定参数i的值setLineDash:
const font = "110px Arial";\nconst width = 110\nconst height = 110\n\nconst check = char => {\n const amount = getIterations(char, { font, width, height })\n console.log(char, amount)\n}\n\n\ncheck(\'W\') // 620\ncheck(\'O\') // 243\ncheck(\'R\') // 331\ncheck(\'L\') // 248\ncheck(\'D\') // 248\ncheck(\'\xe3\x81\xb5\') // 185\nRun Code Online (Sandbox Code Playgroud)\n\n使用这些值,您可以创建一个相对speed参数,使您可以同时完成笔划。
请注意,这种方法是超级贪婪的,并不是真正的性能优化,而是一种概念证明。
\n