canvas教程

canvas文本绘制自动换行、字间距、竖排等实现(2)

字号+ 作者:H5之家 来源:H5之家 2018-02-11 18:05 我要评论( )

JS实现如下: var canvas = document.querySelector(canvas);var context = canvas.getContext(2d);context.font = 16px sans-serif;var width = canvas.width;var height = canvas.height;var tempImg = new Image

JS实现如下:

var canvas = document.querySelector('canvas'); var context = canvas.getContext('2d'); context.font = '16px sans-serif'; var width = canvas.width; var height = canvas.height; var tempImg = new Image(); tempImg.width = width; tempImg.height = height; tempImg.onload = function () { // 把img绘制在canvas画布上 context.drawImage(this, 0, 0, width, height); }; tempImg.src = 'data:image/svg+xml;charset=utf-8,<svg xmlns=""><foreignObject width="'+ width +'" height="'+ height +'"><body xmlns="" style="margin:0;font:'+ context.font +';">我是一段需要换行的文字啦啦啦</body></foreignObject></svg>';

此方法优点在于足够简单,只要一段带 style 样式的HTML代码即可!

唯一不足在于兼容性,IE浏览器不支持 <foreignObject> ,最新的Firefox浏览器虽然支持 <foreignObject> ,但是只能以 <img< 形式呈现,无法绘制到canvas画布上(若谁知道原因欢迎不吝赐教)。

不过好的是移动端Safari浏览器以及微信浏览器都是支持的,因此,此方法理论上是可以在移动端使用的。例如我手机Safari的效果截图:

二、如何让canvas支持字符间距? 1. 如果只需要兼容Chrome,直接letter-spacing控制

对于Chrome浏览器,无论是字符间距还是单词间距,都可以自动继承于 <canvas> 元素,这个特性让人非常感动。

也就是:

canvas { letter-pacing: 5px; }

绘制的文字字符间距自动就是 5px 。

如此欣喜的特性有必要亲眼见证一下,您可以狠狠地点击这里: canavs文本间距使用CSS letter-spacing实现demo

效果如下GIF示意:

完整测试JS代码如下:

var canvas = document.querySelector('canvas'); var context = canvas.getContext('2d'); var range = document.querySelector('input[type=range]'); // 绘制方法 var draw = function () { // 清除之前的绘制 context.clearRect(0, 0, canvas.width, canvas.height); // 字符间距设置 canvas.style.letterSpacing = range.value + 'px'; // 并绘制文本,font属性值设置一定要在这里 context.font = '32px sans-serif'; context.fillText('我是一段文本', 0, 50); }; // 改变字符间距后重绘 range.addEventListener('change', draw); // 一进来根据默认值绘制 draw();

根据我的观察,貌似Chrome浏览器在设置 font 属性值的时候,把 letter-spacing 等信息一起算作上下文中了。所以,虽然看上去 context.font = '32px sans-serif' 一直都没变,但却不能放在 draw() 方法之外,否则,还是按照老的 letter-spacing 渲染而看不到字符间距变化。

此方法最简单最容易理解,只可惜,根据我的测试,目前仅Chrome浏览器支持。Firefox以及Safari全都不行。

2. canvas计算与逐字绘制

原理为,每一个字符单独作为一个绘制单元,然后根据字符宽度+letterSpacing间距动态绘制,同样,离不开使用 CanvasRenderingContext2D.measureText(text) 这个API。

以下就是自己直接在原型上扩展的字符间距绘制方法letterSpacingText,大家可以直接拷贝过去使用,MIT协议,保留原出处即可。

/** * @author zhangxinxu(.com) * @licence MIT * @description ?p=7362 */ CanvasRenderingContext2D.prototype.letterSpacingText = function (text, x, y, letterSpacing) { var context = this; var canvas = context.canvas; if (!letterSpacing && canvas) { letterSpacing = parseFloat(window.getComputedStyle(canvas).letterSpacing); } if (!letterSpacing) { return this.fillText(text, x, y); } var arrText = text.split(''); var align = context.textAlign || 'left'; // 这里仅考虑水平排列 var originWidth = context.measureText(text).width; // 应用letterSpacing占据宽度 var actualWidth = originWidth + letterSpacing * (arrText.length - 1); // 根据水平对齐方式确定第一个字符的坐标 if (align == 'center') { x = x - actualWidth / 2; } else if (align == 'right') { x = x - actualWidth; } // 临时修改为文本左对齐 context.textAlign = 'left'; // 开始逐字绘制 arrText.forEach(function (letter) { var letterWidth = context.measureText(letter).width; context.fillText(letter, x, y); // 确定下一个字符的横坐标 x = x + letterWidth + letterSpacing; }); // 对齐方式还原 context.textAlign = align; };

API详细:

CanvasRenderingContext2D.letterSpacingText(text, x, y, letterSpacing);

其中 text , x , y 3个参数和 fillText() 方法中的这3个参数含义是一样的,不赘述。 letterSpacing 表示字符间距大小,数值。可缺省,默认会拿 <canvas> 元素在DOM环境下的 letter-spacing 大小作为计算值。

使用示意:

var canvas = document.querySelector('canvas'); var context = canvas.getContext('2d'); context.font = '32px sans-serif'; context.textAlign = 'center'; // 字符间隙5px context.letterSpacingText('我是一段文本', canvas.width / 2, 50, 5);

您可以狠狠地点击这里: canavs字符间距JS逐字计算demo

效果如下GIF示意(居中对齐,截自IE Edge):

此方法兼容性非常好,IE9+浏览器都支持,PC和Mobile通吃。

3. 借助SVG <foreignObject>直接把CSS效果绘制上去

和自动换行实现类似,详细略。

四、如何让canvas支持竖直排列?

文字竖直排列,对于玩英文的老外,可以使用 context.rotate() 旋转 90deg 实现,但是对于中文等中亚文字,却是完全不适合的。因为两种语言的竖直排版规则是不一样的。

中文等东亚文字上,例如一些古诗词文字还是正的,仅仅是阅读方向是从上往下,但是,英文(以及阿拉伯数字)由于本身的字符特性,直接就是旋转排列的。

所以单纯旋转策略对于大中国并不实用。

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • HTML5 Canvas实现玫瑰曲线和心形图案的代码实例_html5教程技巧

    HTML5 Canvas实现玫瑰曲线和心形图案的代码实例_html5教程技巧

    2018-02-11 18:04

  • canvas实现按住鼠标移动绘制出轨迹的示例代码

    canvas实现按住鼠标移动绘制出轨迹的示例代码

    2018-02-10 17:01

  • 微信小程序canvas尺寸设置

    微信小程序canvas尺寸设置

    2018-02-10 15:07

  • 超炫的Canvas下雨动画

    超炫的Canvas下雨动画

    2018-02-10 15:00

网友点评
i