如何使用HTML5 Canvas在同一行中给不同的单词上色?

编程入门 行业动态 更新时间:2024-10-08 19:47:48
本文介绍了如何使用HTML5 Canvas在同一行中给不同的单词上色?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

考虑以下循环,该循环遍历对象中的键值对:

Consider this loop that runs through key value pairs in an object:

Object.keys(categories).forEach(categoryKey => { ctx.fillText(`${categoryKey}: ${categories[categoryKey]}`, 40, (30 * i) + 160); ctx.fillStyle = '#fff'; i++; });

所有文本均为白色,但我想要的是 $ {categoryKey} 处的文本为红色.

All text is white, but what I would like is for the text at: ${categoryKey} to be red.

因为它在同一字符串中运行,所以我不确定如何在不中断的情况下执行此操作,因为我希望它位于同一 ctx.fillText()调用中./p>

Because this runs in the same string, I'm unsure how to do this without breaking it out, because I'd like it to be within the same ctx.fillText() call.

推荐答案

我需要多次格式化画布渲染的文本格式(尤其是数学示例),因此下面是对我用来修改渲染文本的功能的修改使用嵌套的格式指南.

There are many times I need to format text for canvas rendering (particularly for math examples) so below is a modification of the function I use to modify the rendered text using a nested formatting guide.

我自己的库中的修改后的副本,可根据嵌套样式规则设置文本格式.

A modified copy from my own library that formats text according to nested style rules.

simpleTextStyler 的工作方式是先获取字体中每个字符的大小(使用 simpleTextStyler.setFont()设置当前上下文字体,否则它将不起作用)然后查看字符串中的每个字符,以分离出具有相同样式的字符组,并一次渲染一个字符.

The simpleTextStyler works by first getting the size of each character in the font (use simpleTextStyler.setFont() to set the current context font or it will not work) and then looking at each character in the string separating out groups of characters with the same styles and rendering them one at a time.

如果发现新样式"{",它将使用堆栈来保存当前样式,从而将样式推入堆栈.并在每个结束}"

It uses a stack to hold the current style pushing a style onto the stack if a new one is found "{" and popping the style off the stack at each closing "}"

如果"\ n"被发现.如果出现"\ t",则移至下一个制表位.并在" {{" 和}" 内使用各种嵌套样式,其中"{" 之后的第一个字符表示功能.

It will add a new line if "\n" is found. Move to the next tab stop if "\t" and use various nested style inside "{" and "}" where the first character after the "{" denotes the function.

  • s 子脚本
  • S 超级脚本
  • + 较大的文字
  • -较小的文本
  • #颜色后必须是6个字符的十六进制颜色,例如红色{#FF0000此文本为红色}
  • s sub script
  • S super script
  • + bigger text
  • - smaller text
  • # colour must be followed by 6 char hex colour eg red {#FF0000This text is red}

注意::必须仅使用7个字符的CSS十六进制颜色.例如将颜色更改为{#FF0000Red}"

NOTE: Must use only 7 char CSS hex colour. eg "Change colour to {#FF0000Red}"

文本样式可以嵌套,例如"text {Ssuper {ssub {Ssuper}} {Ssuper super}}" 是text Super Sub super 超级超级

Text styles can be nested eg "text{Ssuper{ssub{Ssuper}}{Ssuper super}}" is textSuperSubsuperSuper super

该演示呈现字符串" Testing \ nnewline \ n \ tTab \ n \ t \ tTab \ n \ t \ t \ tTab \ nSub {sScript} Super {SScript} Size {+ Big {+ Bigger}}正常{-Small {-Smaller}} \ n \ n \ n {#FF0000Red} {#00FF00Green} {#0000FFBlue}"

满足您的需求

simpleTextStyler.setFont(); // only needs to be set for the font family // sizing text is in the last argument of the next call simpleTextStyler.drawText(ctx, `{#FF0000${categoryKey}}: ${categories[categoryKey]}`, 40, (30 * i) + 160,fontSize);

var ctx = canvas.getContext("2d"); ctx.font = "18px arial"; setTimeout(drawExamples,0); function drawExamples(){ simpleTextStyler.setFont(); // set the current font simpleTextStyler.drawText(ctx, "Testing simple Canvas2D text styler...\nnewline\n\tTab\n\t\tTab\n\t\t\tTab\nSub{sScript} Super{SScript} Size {+Big {+Bigger}} Normal {-Small {-Smaller}}\nAnd now colours \n{#FF0000Red} {#00FF00Green} {#0000FFBlue}", 10,20,18) } const simpleTextStyler = (function(){ const simpleTextStyler = { sizes: [], baseSize: undefined, font: undefined, controlChars: "{}\n\t", spaceSize: 0, tabSize: 8, // in spaceSize units tabs: (function() {var t = []; for(var i=0; i < 100; i += 8){t.push(i);}; return t;})(), getNextTab: function(x) { var i = 0; while (i < this.tabs.length) { if (x < this.tabs[i] * this.tabSize * this.spaceSize) { return this.tabs[i] * this.tabSize * this.spaceSize; } i++; } return this.tabs[i-1] * this.tabSize * this.spaceSize; }, getFontSize: function(font){ var numFind = /[0-9]+/; var number = numFind.exec(font)[0]; if (isNaN(number)) { throw Error("SimpleTextStyler Cant find font size"); } return Number(number); }, setFont: function(font = ctx.font) { this.font = ctx.font = font; this.baseSize = this.getFontSize(font); for (var i = 32; i < 256; i ++) { this.sizes[i - 32] = ctx.measureText(String.fromCharCode(i), 0, 0).width/this.baseSize; } this.spaceSize = this.sizes[0]; }, drawText: function(context, text, x, y, size) { var i, len, subText; var w, scale; var xx, yy, ctx; var state = []; if(text === undefined){ return } xx = x; yy = y; if (!context.setTransform) { // simple test if this is a 2D context if (context.ctx) { ctx = context.ctx } // may be a image with attached ctx? else{ return } } else { ctx = context } function renderText(text) { ctx.save(); ctx.fillStyle = colour; ctx.translate(x, y) ctx.scale(scale, scale) ctx.fillText(text, 0, 0); ctx.restore(); } var colour = ctx.fillStyle; ctx.font = this.font; len = text.length; subText = ""; w = 0; i = 0; scale = size / this.baseSize; while (i < len) { const c = text[i]; const cc = text.charCodeAt(i); if (cc < 256) { // only ascii if (this.controlChars.indexOf(c) > -1) { if (subText !== "") { scale = size / this.baseSize; renderText(subText); x += w; w = 0; subText = ""; } if (c === "\n") { // return move to new line x = xx; y += size; } else if (c === "\t") { // tab move to next tab x = this.getNextTab(x - xx) + xx; } else if (c === "{") { // Text format delimiter state.push({size, colour, x, y}) i += 1; const t = text[i]; if (t === "+") { // Increase size size *= 1/(3/4); } else if (t === "-") { // decrease size size *= 3/4; } else if (t === "s") { // sub script y += size * (1/3); size *= (2/3); } else if (t === "S") { // super script y -= size * (1/3); size *= (2/3); } else if (t === "#") { colour = text.substr(i,7); i+= 6; } } else if (c === "}"){ const s = state.pop(); y = s.y; size = s.size; colour = s.colour; scale = size / this.baseSize; } } else { subText += c; w += this.sizes[cc-32] * size; } } i += 1; } if (subText !== "") { renderText(subText) } }, } return simpleTextStyler; })();

canvas { border : 2px solid black; }

<canvas id="canvas" width=512 height=160></canvas>

更多推荐

如何使用HTML5 Canvas在同一行中给不同的单词上色?

本文发布于:2023-10-31 10:19:31,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1545792.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:如何使用   单词   Canvas

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!